Hi Guilhem,
Have you discussed this change with Evgeny? I notice that in the WL5274
branch the calls to mysql_derived_cleanup() are in places that do not
overlap with the calls in the current backporting branch. Maybe there
is come need for coordination ...
--
Øystein
On 01/06/2011 17:19, Guilhem Bichot wrote:
> #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);
> }
>
>
>
>
>
--
Øystein Grøvlen, Principal Software Engineer
MySQL Group, Oracle
Trondheim, Norway