Commit f5a80e5a authored by unknown's avatar unknown

Merge 51.0.168.192.in-addr.arpa:/Users/bell/mysql/bk/work-qc_item_view-5.0

into 51.0.168.192.in-addr.arpa:/Users/bell/mysql/bk/work-repl-5.0


BitKeeper/etc/logging_ok:
  auto-union
parents c41a485d fee0f25f
...@@ -2480,5 +2480,17 @@ ERROR 42000: Can't find any matching row in the user table ...@@ -2480,5 +2480,17 @@ ERROR 42000: Can't find any matching row in the user table
select bug5278()| select bug5278()|
ERROR 42000: Can't find any matching row in the user table ERROR 42000: Can't find any matching row in the user table
drop function bug5278| drop function bug5278|
drop procedure if exists p1|
create table t3(id int)|
insert into t3 values(1)|
create procedure bug7992()
begin
declare i int;
select max(id)+1 into i from t3;
end|
call bug7992()|
call bug7992()|
drop procedure bug7992|
drop table t3|
drop table t1; drop table t1;
drop table t2; drop table t2;
drop table if exists t1,t2,v1,v2,v3;
drop view if exists t1,t2,v1,v2,v3;
set GLOBAL query_cache_size=1355776; set GLOBAL query_cache_size=1355776;
flush status; flush status;
create table t1 (a int, b int); create table t1 (a int, b int);
...@@ -98,4 +100,27 @@ Qcache_hits 1 ...@@ -98,4 +100,27 @@ Qcache_hits 1
drop view v1; drop view v1;
set query_cache_type=default; set query_cache_type=default;
drop table t1; drop table t1;
create table t1 (a int);
insert into t1 values (1), (2), (3);
create view v1 as select a from t1 where a > 1;
select * from v1;
a
2
3
alter view v1 as select a from t1 where a > 2;
select * from v1;
a
3
drop view v1;
select * from v1;
ERROR 42S02: Table 'test.v1' doesn't exist
drop table t1;
create table t1 (a int, primary key (a), b int);
create table t2 (a int, primary key (a), b int);
insert into t2 values (1000, 2000);
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
select * from v3;
a b
drop view v3;
drop table t1, t2;
set GLOBAL query_cache_size=default; set GLOBAL query_cache_size=default;
...@@ -2982,7 +2982,26 @@ select bug5278()| ...@@ -2982,7 +2982,26 @@ select bug5278()|
select bug5278()| select bug5278()|
drop function bug5278| drop function bug5278|
#
# BUG#7992: rolling back temporary Item tree changes in SP
#
--disable_warnings
drop procedure if exists p1|
--enable_warnings
create table t3(id int)|
insert into t3 values(1)|
create procedure bug7992()
begin
declare i int;
select max(id)+1 into i from t3;
end|
call bug7992()|
call bug7992()|
drop procedure bug7992|
drop table t3|
delimiter ;| delimiter ;|
drop table t1; drop table t1;
drop table t2; drop table t2;
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
# #
# QUERY CACHE options for VIEWs # QUERY CACHE options for VIEWs
# #
--disable_warnings
drop table if exists t1,t2,v1,v2,v3;
drop view if exists t1,t2,v1,v2,v3;
--enable_warnings
set GLOBAL query_cache_size=1355776; set GLOBAL query_cache_size=1355776;
flush status; flush status;
create table t1 (a int, b int); create table t1 (a int, b int);
...@@ -53,6 +58,30 @@ drop view v1; ...@@ -53,6 +58,30 @@ drop view v1;
set query_cache_type=default; set query_cache_type=default;
drop table t1; drop table t1;
set GLOBAL query_cache_size=default;
#
# invalidation of view
#
create table t1 (a int);
insert into t1 values (1), (2), (3);
create view v1 as select a from t1 where a > 1;
select * from v1;
alter view v1 as select a from t1 where a > 2;
select * from v1;
drop view v1;
-- error 1146
select * from v1;
drop table t1;
#
# join view with QC
#
create table t1 (a int, primary key (a), b int);
create table t2 (a int, primary key (a), b int);
insert into t2 values (1000, 2000);
create view v3 (a,b) as select t1.a as a, t2.a as b from t1, t2;
select * from v3;
drop view v3;
drop table t1, t2;
set GLOBAL query_cache_size=default;
...@@ -311,7 +311,7 @@ TODO list: ...@@ -311,7 +311,7 @@ TODO list:
#include "emb_qcache.h" #include "emb_qcache.h"
#endif #endif
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF) #if !defined(EXTRA_DBUG) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \ #define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
pthread_mutex_lock(M);} pthread_mutex_lock(M);}
#define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\ #define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\
...@@ -2103,45 +2103,76 @@ void Query_cache::invalidate_table(Query_cache_block *table_block) ...@@ -2103,45 +2103,76 @@ void Query_cache::invalidate_table(Query_cache_block *table_block)
} }
} }
/* /*
Store all used tables Register given table list begining with given position in tables table of
block
SYNOPSIS SYNOPSIS
register_all_tables() Query_cache::register_tables_from_list
block Store tables in this block tables_used given table list
tables_used List if used tables counter number current position in table of tables of block
tables_arg Not used ? block_table pointer to current position in tables table of block
RETURN
0 error
number of next position of table entry in table of tables of block
*/ */
my_bool Query_cache::register_all_tables(Query_cache_block *block, TABLE_COUNTER_TYPE
TABLE_LIST *tables_used, Query_cache::register_tables_from_list(TABLE_LIST *tables_used,
TABLE_COUNTER_TYPE tables_arg) TABLE_COUNTER_TYPE counter,
Query_cache_block_table *block_table)
{ {
TABLE_COUNTER_TYPE n; TABLE_COUNTER_TYPE n;
DBUG_PRINT("qcache", ("register tables block 0x%lx, n %d, header %x", DBUG_ENTER("Query_cache::register_tables_from_list");
(ulong) block, (int) tables_arg, for (n= counter;
(int) ALIGN_SIZE(sizeof(Query_cache_block))));
Query_cache_block_table *block_table = block->table(0);
for (n= 0;
tables_used; tables_used;
tables_used= tables_used->next_global, n++, block_table++) tables_used= tables_used->next_global, n++, block_table++)
{
block_table->n= n;
if (tables_used->view)
{
char key[MAX_DBKEY_LENGTH];
uint key_length;
DBUG_PRINT("qcache", ("view %s, db %s",
tables_used->view_name.str,
tables_used->view_db.str));
key_length= (uint) (strmov(strmov(key, tables_used->view_db.str) + 1,
tables_used->view_name.str) - key) + 1;
/*
There are not callback function for for VIEWs
*/
if (!insert_table(key_length, key, block_table,
tables_used->view_db.length + 1,
HA_CACHE_TBL_NONTRANSACT, 0, 0))
DBUG_RETURN(0);
{
TABLE_COUNTER_TYPE inc= register_tables_from_list(tables_used->ancestor,
n + 1,
block_table + 1);
if (!inc)
DBUG_RETURN(0);
n+= inc;
block_table+= inc;
}
}
else
{ {
DBUG_PRINT("qcache", DBUG_PRINT("qcache",
("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx", ("table %s, db %s, openinfo at 0x%lx, keylen %u, key at 0x%lx",
tables_used->table_name, tables_used->db, tables_used->table->s->table_name,
tables_used->table->s->table_cache_key,
(ulong) tables_used->table, (ulong) tables_used->table,
tables_used->table->s->key_length, tables_used->table->s->key_length,
(ulong) tables_used->table->s->table_cache_key)); (ulong) tables_used->table->s->table_cache_key));
block_table->n= n;
if (!insert_table(tables_used->table->s->key_length, if (!insert_table(tables_used->table->s->key_length,
tables_used->table->s->table_cache_key, block_table, tables_used->table->s->table_cache_key, block_table,
tables_used->db_length, tables_used->db_length,
tables_used->table->file->table_cache_type(), tables_used->table->file->table_cache_type(),
tables_used->callback_func, tables_used->callback_func,
tables_used->engine_data)) tables_used->engine_data))
break; DBUG_RETURN(0);
if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM) if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
{ {
...@@ -2163,13 +2194,39 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block, ...@@ -2163,13 +2194,39 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
db_length, db_length,
tables_used->table->file->table_cache_type(), tables_used->table->file->table_cache_type(),
0, 0)) 0, 0))
goto err; DBUG_RETURN(0);
}
} }
} }
} }
DBUG_RETURN(n - counter);
}
/*
Store all used tables
SYNOPSIS
register_all_tables()
block Store tables in this block
tables_used List if used tables
tables_arg Not used ?
*/
my_bool Query_cache::register_all_tables(Query_cache_block *block,
TABLE_LIST *tables_used,
TABLE_COUNTER_TYPE tables_arg)
{
TABLE_COUNTER_TYPE n;
DBUG_PRINT("qcache", ("register tables block 0x%lx, n %d, header %x",
(ulong) block, (int) tables_arg,
(int) ALIGN_SIZE(sizeof(Query_cache_block))));
Query_cache_block_table *block_table = block->table(0);
n= register_tables_from_list(tables_used, 0, block_table);
err: err:
if (tables_used) if (n)
{ {
DBUG_PRINT("qcache", ("failed at table %d", (int) n)); DBUG_PRINT("qcache", ("failed at table %d", (int) n));
/* Unlink the tables we allocated above */ /* Unlink the tables we allocated above */
...@@ -2178,7 +2235,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block, ...@@ -2178,7 +2235,7 @@ my_bool Query_cache::register_all_tables(Query_cache_block *block,
tmp++) tmp++)
unlink_table(tmp); unlink_table(tmp);
} }
return (tables_used == 0); return (n);
} }
/* /*
...@@ -2676,36 +2733,47 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail, ...@@ -2676,36 +2733,47 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
*****************************************************************************/ *****************************************************************************/
/* /*
If query is cacheable return number tables in query Collect information about table types, check that tables are cachable and
(query without tables are not cached) count them
SYNOPSIS
process_and_count_tables()
tables_used table list for processing
tables_type pointer to variable for table types collection
RETURN
0 error
>0 number of tables
*/ */
TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len, static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
char *query,
LEX *lex,
TABLE_LIST *tables_used,
uint8 *tables_type) uint8 *tables_type)
{ {
DBUG_ENTER("process_and_count_tables");
TABLE_COUNTER_TYPE table_count = 0; TABLE_COUNTER_TYPE table_count = 0;
DBUG_ENTER("Query_cache::is_cacheable");
if (lex->sql_command == SQLCOM_SELECT &&
(thd->variables.query_cache_type == 1 ||
(thd->variables.query_cache_type == 2 && (lex->select_lex.options &
OPTION_TO_QUERY_CACHE))) &&
lex->safe_to_cache_query)
{
DBUG_PRINT("qcache", ("options %lx %lx, type %u",
OPTION_TO_QUERY_CACHE,
lex->select_lex.options,
(int) thd->variables.query_cache_type));
for (; tables_used; tables_used= tables_used->next_global) for (; tables_used; tables_used= tables_used->next_global)
{ {
table_count++; table_count++;
if (tables_used->view)
{
DBUG_PRINT("qcache", ("view %s, db %s",
tables_used->view_name.str,
tables_used->view_db.str));
*tables_type|= HA_CACHE_TBL_NONTRANSACT;
{
TABLE_COUNTER_TYPE subcount;
if (!(subcount= process_and_count_tables(tables_used->ancestor,
tables_type)))
DBUG_RETURN(0);
table_count+= subcount;
}
}
else
{
DBUG_PRINT("qcache", ("table %s, db %s, type %u", DBUG_PRINT("qcache", ("table %s, db %s, type %u",
tables_used->table_name, tables_used->table->s->table_name,
tables_used->db, tables_used->table->s->db_type)); tables_used->table->s->table_cache_key,
tables_used->table->s->db_type));
*tables_type|= tables_used->table->file->table_cache_type(); *tables_type|= tables_used->table->file->table_cache_type();
/* /*
...@@ -2715,12 +2783,13 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len, ...@@ -2715,12 +2783,13 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
if (tables_used->table->s->tmp_table != NO_TMP_TABLE || if (tables_used->table->s->tmp_table != NO_TMP_TABLE ||
(*tables_type & HA_CACHE_TBL_NOCACHE) || (*tables_type & HA_CACHE_TBL_NOCACHE) ||
(tables_used->db_length == 5 && (tables_used->db_length == 5 &&
my_strnncoll(table_alias_charset, (uchar*)tables_used->db, 6, my_strnncoll(table_alias_charset,
(uchar*)tables_used->table->s->table_cache_key, 6,
(uchar*)"mysql",6) == 0)) (uchar*)"mysql",6) == 0))
{ {
DBUG_PRINT("qcache", DBUG_PRINT("qcache",
("select not cacheable: temporary, system or \ ("select not cacheable: temporary, system or \
other non-cacheable table(s)")); other non-cacheable table(s)"));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM) if (tables_used->table->s->db_type == DB_TYPE_MRG_MYISAM)
...@@ -2730,6 +2799,38 @@ other non-cacheable table(s)")); ...@@ -2730,6 +2799,38 @@ other non-cacheable table(s)"));
table_count+= (file->end_table - file->open_tables); table_count+= (file->end_table - file->open_tables);
} }
} }
}
DBUG_RETURN(table_count);
}
/*
If query is cacheable return number tables in query
(query without tables are not cached)
*/
TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
char *query,
LEX *lex,
TABLE_LIST *tables_used,
uint8 *tables_type)
{
TABLE_COUNTER_TYPE table_count;
DBUG_ENTER("Query_cache::is_cacheable");
if (lex->sql_command == SQLCOM_SELECT &&
(thd->variables.query_cache_type == 1 ||
(thd->variables.query_cache_type == 2 && (lex->select_lex.options &
OPTION_TO_QUERY_CACHE))) &&
lex->safe_to_cache_query)
{
DBUG_PRINT("qcache", ("options %lx %lx, type %u",
OPTION_TO_QUERY_CACHE,
lex->select_lex.options,
(int) thd->variables.query_cache_type));
if (!(table_count= process_and_count_tables(tables_used, tables_type)))
DBUG_RETURN(0);
if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
((*tables_type)&HA_CACHE_TBL_TRANSACT)) ((*tables_type)&HA_CACHE_TBL_TRANSACT))
...@@ -2769,7 +2870,9 @@ my_bool Query_cache::ask_handler_allowance(THD *thd, ...@@ -2769,7 +2870,9 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
for (; tables_used; tables_used= tables_used->next_global) for (; tables_used; tables_used= tables_used->next_global)
{ {
TABLE *table= tables_used->table; TABLE *table;
if (!(table= tables_used->table))
continue;
handler *handler= table->file; handler *handler= table->file;
if (!handler->register_query_cache_table(thd, table->s->table_cache_key, if (!handler->register_query_cache_table(thd, table->s->table_cache_key,
table->s->key_length, table->s->key_length,
......
...@@ -285,6 +285,10 @@ class Query_cache ...@@ -285,6 +285,10 @@ class Query_cache
void invalidate_table(TABLE *table); void invalidate_table(TABLE *table);
void invalidate_table(byte *key, uint32 key_length); void invalidate_table(byte *key, uint32 key_length);
void invalidate_table(Query_cache_block *table_block); void invalidate_table(Query_cache_block *table_block);
TABLE_COUNTER_TYPE
register_tables_from_list(TABLE_LIST *tables_used,
TABLE_COUNTER_TYPE counter,
Query_cache_block_table *block_table);
my_bool register_all_tables(Query_cache_block *block, my_bool register_all_tables(Query_cache_block *block,
TABLE_LIST *tables_used, TABLE_LIST *tables_used,
TABLE_COUNTER_TYPE tables); TABLE_COUNTER_TYPE tables);
......
...@@ -305,6 +305,8 @@ bool mysql_create_view(THD *thd, ...@@ -305,6 +305,8 @@ bool mysql_create_view(THD *thd,
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
res= mysql_register_view(thd, view, mode); res= mysql_register_view(thd, view, mode);
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
if (view->revision != 1)
query_cache_invalidate3(thd, view, 0);
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
if (res) if (res)
goto err; goto err;
...@@ -917,6 +919,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) ...@@ -917,6 +919,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
} }
if (my_delete(path, MYF(MY_WME))) if (my_delete(path, MYF(MY_WME)))
goto err; goto err;
query_cache_invalidate3(thd, view, 0);
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
} }
send_ok(thd); send_ok(thd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment