#At file:///home/mysql_src/bzrrepos_new/mysql-next-mr-opt-backporting-wl4800-2/ based on revid:guilhem.bichot@stripped
3322 Guilhem Bichot 2011-06-09
fix for BUG#12612201 - SEGFAULT IN SUBSELECT_UNIQUESUBQUERY_ENGINE::PRINT WITH OPTIMIZER TRACE
@ sql/sql_update.cc
It was already the case (see open_and_lock_tables()) that EXPLAIN SELECT
does not clean up derived tables early, because they must be around
longer until the transformed query is printed. This also applied to
SELECT with optimizer trace enabled, which also prints the transformed
query and WHERE clauses.
But optimizer trace works for (multi-)UPDATE too. So the same must be true
in the (multi-)UPDATE code, otherwise we get the bug.
Derived tables are then cleaned up at end of mysql_execute_command()
(lex->unit.cleanup() call).
This might also be useful for EXPLAIN UPDATE.
modified:
mysql-test/suite/optimizer_trace/r/optimizer_trace_bugs.result
mysql-test/suite/optimizer_trace/t/optimizer_trace_bugs.test
sql/sql_update.cc
=== modified file 'mysql-test/suite/optimizer_trace/r/optimizer_trace_bugs.result'
--- a/mysql-test/suite/optimizer_trace/r/optimizer_trace_bugs.result 2011-05-31 13:00:14 +0000
+++ b/mysql-test/suite/optimizer_trace/r/optimizer_trace_bugs.result 2011-06-09 08:59:51 +0000
@@ -671,3 +671,82 @@ FROM t1
] /* steps */
} 0 0
DROP TABLE where_subselect_19033,t1,t2;
+
+# BUG#12612201 - SEGFAULT IN
+# SUBSELECT_UNIQUESUBQUERY_ENGINE::PRINT WITH OPTIMIZER TRACE
+
+CREATE TABLE t1 (
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL
+);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (1,4,'v','v'),(20,5,'r','r');
+CREATE TABLE t3 (
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL
+);
+INSERT INTO t3 VALUES (NULL,'j','j'),(8,'c','c');
+CREATE TABLE where_updatedelete_20769 select count( alias2 . col_varchar_key ) as field1
+from (
+(select sq1_alias1 . *
+from ( t3 as sq1_alias1
+straight_join t1 as sq1_alias2
+on (sq1_alias2 . col_varchar_key = sq1_alias1 . col_varchar_key)
+)
+where sq1_alias1 . col_int_key in (
+select c_sq1_alias1 . pk as c_sq1_field1
+from t2 as c_sq1_alias1
+)
+) as alias1
+left outer join t1 as alias2
+on (alias2 . col_varchar_key = alias1 . col_varchar_key )
+)
+where ( alias2 . col_varchar_key in (
+select sq2_alias1 . col_varchar_nokey as sq2_field1
+from t2 as sq2_alias1
+where sq2_alias1 . col_int_key in (
+select distinct c_sq2_alias1 . col_int_key as c_sq2_field1
+from t3 as c_sq2_alias1
+)
+) )
+or alias1 . col_int_key = 2
+and alias2 . col_varchar_nokey <= alias1 . col_varchar_nokey
+order by alias1 . col_varchar_key , field1
+;
+UPDATE where_updatedelete_20769 SET field1 = ( select count( alias2 . col_varchar_key ) as field1
+from (
+(select sq1_alias1 . *
+from ( t3 as sq1_alias1
+straight_join t1 as sq1_alias2
+on (sq1_alias2 . col_varchar_key = sq1_alias1 . col_varchar_key)
+)
+where sq1_alias1 . col_int_key in (
+select c_sq1_alias1 . pk as c_sq1_field1
+from t2 as c_sq1_alias1
+)
+) as alias1
+left outer join t1 as alias2
+on (alias2 . col_varchar_key = alias1 . col_varchar_key )
+)
+where ( alias2 . col_varchar_key in (
+select sq2_alias1 . col_varchar_nokey as sq2_field1
+from t2 as sq2_alias1
+where sq2_alias1 . col_int_key in (
+select distinct c_sq2_alias1 . col_int_key as c_sq2_field1
+from t3 as c_sq2_alias1
+)
+) )
+or alias1 . col_int_key = 2
+and alias2 . col_varchar_nokey <= alias1 . col_varchar_nokey
+order by alias1 . col_varchar_key , field1
+ );
+DROP TABLE where_updatedelete_20769;
+DROP TABLE t1,t2,t3;
=== modified file 'mysql-test/suite/optimizer_trace/t/optimizer_trace_bugs.test'
--- a/mysql-test/suite/optimizer_trace/t/optimizer_trace_bugs.test 2011-05-31 13:00:14 +0000
+++ b/mysql-test/suite/optimizer_trace/t/optimizer_trace_bugs.test 2011-06-09 08:59:51 +0000
@@ -153,3 +153,68 @@ WHERE field1 IN
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
DROP TABLE where_subselect_19033,t1,t2;
+
+--echo
+--echo # BUG#12612201 - SEGFAULT IN
+--echo # SUBSELECT_UNIQUESUBQUERY_ENGINE::PRINT WITH OPTIMIZER TRACE
+--echo
+
+CREATE TABLE t1 (
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL
+);
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t2 VALUES (1,4,'v','v'),(20,5,'r','r');
+
+CREATE TABLE t3 (
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL
+);
+
+INSERT INTO t3 VALUES (NULL,'j','j'),(8,'c','c');
+
+let $query=
+ select count( alias2 . col_varchar_key ) as field1
+ from (
+ (select sq1_alias1 . *
+ from ( t3 as sq1_alias1
+ straight_join t1 as sq1_alias2
+ on (sq1_alias2 . col_varchar_key = sq1_alias1 . col_varchar_key)
+ )
+ where sq1_alias1 . col_int_key in (
+ select c_sq1_alias1 . pk as c_sq1_field1
+ from t2 as c_sq1_alias1
+ )
+ ) as alias1
+ left outer join t1 as alias2
+ on (alias2 . col_varchar_key = alias1 . col_varchar_key )
+ )
+ where ( alias2 . col_varchar_key in (
+ select sq2_alias1 . col_varchar_nokey as sq2_field1
+ from t2 as sq2_alias1
+ where sq2_alias1 . col_int_key in (
+ select distinct c_sq2_alias1 . col_int_key as c_sq2_field1
+ from t3 as c_sq2_alias1
+ )
+ ) )
+ or alias1 . col_int_key = 2
+ and alias2 . col_varchar_nokey <= alias1 . col_varchar_nokey
+ order by alias1 . col_varchar_key , field1
+;
+
+eval CREATE TABLE where_updatedelete_20769 $query;
+
+eval UPDATE where_updatedelete_20769 SET field1 = ( $query );
+
+DROP TABLE where_updatedelete_20769;
+DROP TABLE t1,t2,t3;
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2011-05-24 12:46:22 +0000
+++ b/sql/sql_update.cc 2011-06-09 08:59:51 +0000
@@ -305,7 +305,12 @@ int mysql_update(THD *thd,
mysql_handle_derived(thd->lex, &mysql_derived_cleanup);
DBUG_RETURN(1);
}
- mysql_handle_derived(thd->lex, &mysql_derived_cleanup);
+ if (!(thd->lex->describe
+#ifdef OPTIMIZER_TRACE
+ || thd->opt_trace.support_I_S()
+#endif
+ ))
+ mysql_handle_derived(thd->lex, &mysql_derived_cleanup);
THD_STAGE_INFO(thd, stage_init);
table= table_list->table;
@@ -1304,7 +1309,12 @@ int mysql_multi_update_prepare(THD *thd)
mysql_handle_derived(lex, &mysql_derived_cleanup);
DBUG_RETURN(TRUE);
}
- mysql_handle_derived(lex, &mysql_derived_cleanup);
+ if (!(lex->describe
+#ifdef OPTIMIZER_TRACE
+ || thd->opt_trace.support_I_S()
+#endif
+ ))
+ mysql_handle_derived(lex, &mysql_derived_cleanup);
DBUG_RETURN (FALSE);
}
Attachment: [text/bzr-bundle] bzr/guilhem.bichot@oracle.com-20110609085951-htu1e1lejguyt1t6.bundle