#At file:///home/mysql_src/bzrrepos_new/mysql-next-mr-opt-backporting-wl4800/ based on revid:guilhem.bichot@stripped
3322 Guilhem Bichot 2011-06-01
fix for BUG#12612201 - SEGFAULT IN SUBSELECT_UNIQUESUBQUERY_ENGINE::PRINT WITH OPTIMIZER TRACE
@ sql/sql_derived.cc
In mysql_derived_cleanup(), don't clean up SELECT_LEX_UNIT or JOIN, if
EXPLAIN or optimizer trace. Cleanup happens later then.
This was already the case for some mysql_derived_cleanup() calls
in SELECT, this is now extended to UPDATE (because optimizer trace
works for UPDATE too). It will 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_base.cc
sql/sql_derived.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-01 15:19:10 +0000
@@ -671,3 +671,113 @@ 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 (
+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),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_nokey int(11) DEFAULT NULL,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_date_nokey date DEFAULT NULL,
+col_time_key time DEFAULT NULL,
+col_time_nokey time DEFAULT NULL,
+col_datetime_key datetime DEFAULT NULL,
+col_datetime_nokey datetime DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t2 VALUES
+(1,2,4,'2008-12-05','2008-12-05','22:34:09','22:34:09','1900-01-01
+00:00:00','1900-01-01 00:00:00','v','v');
+INSERT INTO t2 VALUES
+(20,6,5,'2004-10-10','2004-10-10','20:58:33','20:58:33','2004-03-27
+09:32:04','2004-03-27 09:32:04','r','r');
+CREATE TABLE t3 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_nokey int(11) DEFAULT NULL,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_date_nokey date DEFAULT NULL,
+col_time_key time DEFAULT NULL,
+col_time_nokey time DEFAULT NULL,
+col_datetime_key datetime DEFAULT NULL,
+col_datetime_nokey datetime DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t3 VALUES
+(28,9,NULL,'2007-04-09','2007-04-09','08:46:48','08:46:48','2005-03-24
+07:33:11','2005-03-24 07:33:11','j','j');
+INSERT INTO t3 VALUES
+(29,6,8,'2000-09-20','2000-09-20','14:11:27','14:11:27','2003-06-13
+23:19:49','2003-06-13 23:19:49','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-01 15:19:10 +0000
@@ -153,3 +153,99 @@ 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 (
+ 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),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_nokey int(11) DEFAULT NULL,
+ col_int_key int(11) DEFAULT NULL,
+ col_date_key date DEFAULT NULL,
+ col_date_nokey date DEFAULT NULL,
+ col_time_key time DEFAULT NULL,
+ col_time_nokey time DEFAULT NULL,
+ col_datetime_key datetime DEFAULT NULL,
+ col_datetime_nokey datetime DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+INSERT INTO t2 VALUES
+(1,2,4,'2008-12-05','2008-12-05','22:34:09','22:34:09','1900-01-01
+00:00:00','1900-01-01 00:00:00','v','v');
+INSERT INTO t2 VALUES
+(20,6,5,'2004-10-10','2004-10-10','20:58:33','20:58:33','2004-03-27
+09:32:04','2004-03-27 09:32:04','r','r');
+
+CREATE TABLE t3 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_nokey int(11) DEFAULT NULL,
+ col_int_key int(11) DEFAULT NULL,
+ col_date_key date DEFAULT NULL,
+ col_date_nokey date DEFAULT NULL,
+ col_time_key time DEFAULT NULL,
+ col_time_nokey time DEFAULT NULL,
+ col_datetime_key datetime DEFAULT NULL,
+ col_datetime_nokey datetime DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+INSERT INTO t3 VALUES
+(28,9,NULL,'2007-04-09','2007-04-09','08:46:48','08:46:48','2005-03-24
+07:33:11','2005-03-24 07:33:11','j','j');
+INSERT INTO t3 VALUES
+(29,6,8,'2000-09-20','2000-09-20','14:11:27','14:11:27','2003-06-13
+23:19:49','2003-06-13 23:19:49','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_base.cc'
--- a/sql/sql_base.cc 2011-05-24 12:46:22 +0000
+++ b/sql/sql_base.cc 2011-06-01 15:19:10 +0000
@@ -5564,16 +5564,7 @@ bool open_and_lock_tables(THD *thd, TABL
mysql_handle_derived(thd->lex, &mysql_derived_cleanup);
goto err;
}
- if (!(thd->lex->describe
-#ifdef OPTIMIZER_TRACE
- /*
- Printing the expanded query in optimizer trace requires
- non-destroyed JOINs for subquery engines.
- */
- || thd->opt_trace.support_I_S()
-#endif
- ))
- mysql_handle_derived(thd->lex, &mysql_derived_cleanup);
+ mysql_handle_derived(thd->lex, &mysql_derived_cleanup);
}
DBUG_RETURN(FALSE);
=== modified file 'sql/sql_derived.cc'
--- a/sql/sql_derived.cc 2011-05-13 14:02:31 +0000
+++ b/sql/sql_derived.cc 2011-06-01 15:19:10 +0000
@@ -318,13 +318,28 @@ bool mysql_derived_filling(THD *thd, LEX
/**
Cleans up the SELECT_LEX_UNIT for the derived table (if any).
+ Exception: the function does nothing if EXPLAIN or optimizer trace is used,
+ because these need units to exist longer, so that they can be explained or
+ printed; they are then cleaned up in st_select_lex_unit::cleanup() at end
+ of mysql_execute_command().
*/
bool mysql_derived_cleanup(THD *thd, LEX *lex, TABLE_LIST *derived)
{
DBUG_ENTER("mysql_derived_cleanup");
- SELECT_LEX_UNIT *unit= derived->derived;
- if (unit)
- unit->cleanup();
+ if (!lex->describe
+#ifdef OPTIMIZER_TRACE
+ /*
+ Printing the expanded query in optimizer trace requires
+ non-destroyed JOINs for subquery engines.
+ */
+ && !thd->opt_trace.support_I_S()
+#endif
+ )
+ {
+ SELECT_LEX_UNIT *unit= derived->derived;
+ if (unit)
+ unit->cleanup();
+ }
DBUG_RETURN(false);
}
Attachment: [text/bzr-bundle] bzr/guilhem.bichot@oracle.com-20110601151910-y5ycqtubddn0nx0a.bundle