diff options
-rw-r--r-- | mysql-test/r/query_cache.result | 43 | ||||
-rw-r--r-- | mysql-test/t/query_cache-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/query_cache.test | 55 | ||||
-rw-r--r-- | sql/sql_cache.cc | 26 |
4 files changed, 120 insertions, 5 deletions
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 0b86c79afbf..83d2e439fbc 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -1,8 +1,9 @@ +set GLOBAL query_cache_size=1355776; flush query cache; flush query cache; reset query cache; flush status; -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t11,t21; drop database if exists mysqltest; create table t1 (a int not null); insert into t1 values (1),(2),(3); @@ -640,3 +641,43 @@ Variable_name Value Qcache_queries_in_cache 2 SET OPTION SQL_SELECT_LIMIT=DEFAULT; drop table t1; +flush query cache; +reset query cache; +flush status; +set GLOBAL query_cache_size=1048576; +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +create table t2 (a text not null); +create table t3 (a text not null); +insert into t3 values("1111111111111111111111111111111111111111111111111111"); +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +drop table t2; +create table t2 (a int not null); +insert into t2 values (1),(2),(3); +create table t4 (a int not null); +insert into t4 values (1),(2),(3); +select * from t4; +select * from t2; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +select * from t2; +select * from t4; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +select * from t2; +select * from t4; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +delete from t2 where a=1; +flush query cache; +select * from t3; +delete from t4 where a=1; +flush query cache; +drop table t1,t2,t3,t4; +set GLOBAL query_cache_size=0; diff --git a/mysql-test/t/query_cache-master.opt b/mysql-test/t/query_cache-master.opt deleted file mode 100644 index cfdce628e74..00000000000 --- a/mysql-test/t/query_cache-master.opt +++ /dev/null @@ -1 +0,0 @@ ---set-variable=query_cache_size=1355776 diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 9e1c22ac642..2ab5504f84b 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -3,6 +3,7 @@ # # Tests with query cache # +set GLOBAL query_cache_size=1355776; # Reset query cache variables. @@ -10,7 +11,7 @@ flush query cache; # This crashed in some versions flush query cache; # This crashed in some versions reset query cache; flush status; -drop table if exists t1,t2,t3; +drop table if exists t1,t2,t3,t4,t11,t21; drop database if exists mysqltest; # @@ -450,3 +451,55 @@ select * from t1; show status like "Qcache_queries_in_cache"; SET OPTION SQL_SELECT_LIMIT=DEFAULT; drop table t1; + + +# +# query cache crash on using same table twice in one query test +# +flush query cache; +reset query cache; +flush status; +set GLOBAL query_cache_size=1048576; + + +create table t1 (a int not null); +insert into t1 values (1),(2),(3); +create table t2 (a text not null); +create table t3 (a text not null); +insert into t3 values("1111111111111111111111111111111111111111111111111111"); +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +insert into t2 select * from t3; +insert into t3 select * from t2; +drop table t2; +create table t2 (a int not null); +insert into t2 values (1),(2),(3); +create table t4 (a int not null); +insert into t4 values (1),(2),(3); + +disable_result_log; +select * from t4; +select * from t2; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +select * from t2; +select * from t4; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; +select * from t2; +select * from t4; +select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2; + +delete from t2 where a=1; +flush query cache; +select * from t3; +enable_result_log; +delete from t4 where a=1; +flush query cache; + +drop table t1,t2,t3,t4; +set GLOBAL query_cache_size=0; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 97ec6033ad6..5d525c7be4e 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2666,11 +2666,33 @@ my_bool Query_cache::move_by_type(byte **border, relink(block, new_block, next, prev, pnext, pprev); if (queries_blocks == block) queries_blocks = new_block; + Query_cache_block_table *beg_of_table_table= block->table(0), + *end_of_table_table= block->table(n_tables); + byte *beg_of_new_table_table= (byte*) new_block->table(0); + for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++) { Query_cache_block_table *block_table = new_block->table(j); - block_table->next->prev = block_table; - block_table->prev->next = block_table; + + // use aligment from begining of table if 'next' is in same block + if ((beg_of_table_table <= block_table->next) && + (block_table->next < end_of_table_table)) + ((Query_cache_block_table *)(beg_of_new_table_table + + (((byte*)block_table->next) - + ((byte*)beg_of_table_table))))->prev= + block_table; + else + block_table->next->prev= block_table; + + // use aligment from begining of table if 'prev' is in same block + if ((beg_of_table_table <= block_table->prev) && + (block_table->prev < end_of_table_table)) + ((Query_cache_block_table *)(beg_of_new_table_table + + (((byte*)block_table->prev) - + ((byte*)beg_of_table_table))))->next= + block_table; + else + block_table->prev->next = block_table; } DBUG_PRINT("qcache", ("after circle tt")); *border += len; |