Commit 1019dd40 authored by unknown's avatar unknown

Bug#20045: Server crash on INSERT ... SELECT ... FROM non-mergeable view

The regression is caused by the fix for bug 14767. When INSERT ... SELECT
used a view in the SELECT list that was not inlined, and there was an 
active transaction, the server could crash in Query_cache::invalidate.

On INSERT ... SELECT only the table being inserted into is invalidated.
Thus views that can't be inlined are skipped from invalidation.

The bug manifests itself in two ways so there is 2 test cases.
One checks that the only the table being inserted into is invalidated.
And the second one checks that there is no crash on INSERT ... SELECT.


mysql-test/t/query_cache.test:
  Added a test case for bug#20045: Server crash on INSERT ... SELECT ... FROM non-mergeable view
mysql-test/r/query_cache.result:
  Added a test case for bug#20045: Server crash on INSERT ... SELECT ... FROM non-mergeable view
sql/sql_parse.cc:
  Bug#20045: Server crash on INSERT ... SELECT ... FROM non-mergeable view 
  On INSERT ... SELECT only the table being inserted into is invalidated.
parent 405dcd2d
...@@ -1274,3 +1274,51 @@ Variable_name Value ...@@ -1274,3 +1274,51 @@ Variable_name Value
Last_query_cost 0.000000 Last_query_cost 0.000000
drop table t1; drop table t1;
SET GLOBAL query_cache_size=0; SET GLOBAL query_cache_size=0;
set global query_cache_size=1024*1024;
flush status;
create table t1 (a int);
insert into t1 (a) values (1), (2), (3);
select * from t1;
a
1
2
3
show status like 'Qcache_hits';
Variable_name Value
Qcache_hits 0
select * from t1;
a
1
2
3
show status like 'Qcache_hits';
Variable_name Value
Qcache_hits 1
create table t2 like t1;
select * from t1;
a
1
2
3
show status like 'Qcache_hits';
Variable_name Value
Qcache_hits 2
insert into t2 select * from t1;
select * from t1;
a
1
2
3
show status like 'Qcache_hits';
Variable_name Value
Qcache_hits 3
drop table t1, t2;
create table t1(c1 int);
create table t2(c1 int);
create table t3(c1 int);
create view v1 as select t3.c1 as c1 from t3,t2 where t3.c1 = t2.c1;
start transaction;
insert into t1(c1) select c1 from v1;
drop table t1, t2, t3;
drop view v1;
set global query_cache_size=0;
...@@ -870,3 +870,32 @@ select * from t1 where a > 3; ...@@ -870,3 +870,32 @@ select * from t1 where a > 3;
show status like 'last_query_cost'; show status like 'last_query_cost';
drop table t1; drop table t1;
SET GLOBAL query_cache_size=0; SET GLOBAL query_cache_size=0;
#
# Bug #20045: Server crash on INSERT ... SELECT ... FROM non-mergeable view
#
set global query_cache_size=1024*1024;
flush status;
create table t1 (a int);
insert into t1 (a) values (1), (2), (3);
select * from t1;
show status like 'Qcache_hits';
select * from t1;
show status like 'Qcache_hits';
create table t2 like t1;
select * from t1;
show status like 'Qcache_hits';
insert into t2 select * from t1;
select * from t1;
show status like 'Qcache_hits';
drop table t1, t2;
create table t1(c1 int);
create table t2(c1 int);
create table t3(c1 int);
create view v1 as select t3.c1 as c1 from t3,t2 where t3.c1 = t2.c1;
start transaction;
insert into t1(c1) select c1 from v1;
drop table t1, t2, t3;
drop view v1;
set global query_cache_size=0;
...@@ -3421,8 +3421,12 @@ end_with_restore_list: ...@@ -3421,8 +3421,12 @@ end_with_restore_list:
if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT && if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
thd->lock) thd->lock)
{ {
/* INSERT ... SELECT should invalidate only the very first table */
TABLE_LIST *save_table= first_table->next_local;
first_table->next_local= 0;
mysql_unlock_tables(thd, thd->lock); mysql_unlock_tables(thd, thd->lock);
query_cache_invalidate3(thd, first_table, 1); query_cache_invalidate3(thd, first_table, 1);
first_table->next_local= save_table;
thd->lock=0; thd->lock=0;
} }
delete result; delete result;
......
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