From eb056f8726131b652f22b33b23c0682741ea5475 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Tue, 2 Apr 2019 15:04:45 +0200 Subject: [PATCH] MDEV-17362: SIGSEGV in JOIN::optimize_inner or Assertion `fixed == 0' failed in Item_equal::fix_fields, server crashes after 2nd execution of PS Move reinitialisation of pushdown variables for every query, because it used now not only for derived tables. --- mysql-test/main/subselect_innodb.result | 33 +++++++++++++++++++++++++ mysql-test/main/subselect_innodb.test | 32 ++++++++++++++++++++++++ sql/sql_derived.cc | 5 ---- sql/sql_prepare.cc | 4 +++ sql/sql_select.cc | 6 +++-- 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/mysql-test/main/subselect_innodb.result b/mysql-test/main/subselect_innodb.result index 0eb40c9be00..8e09be9b705 100644 --- a/mysql-test/main/subselect_innodb.result +++ b/mysql-test/main/subselect_innodb.result @@ -616,3 +616,36 @@ id select_type table type possible_keys key key_len ref rows filtered Extra Warnings: Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` semi join (`test`.`t4`) join `test`.`t3` where `test`.`t4`.`f4` = 1 and `test`.`t1`.`f1` >= `test`.`t2`.`f2` DROP TABLE t1,t2,t3,t4; +# +# MDEV-17362: SIGSEGV in JOIN::optimize_inner or Assertion `fixed == 0' +# failed in Item_equal::fix_fields, server crashes after 2nd execution +# of PS +# +create table t1 (a int, b int); +create table t2 (x int, y int); +insert into t1 values (1,1),(2,2); +insert into t2 values (1,1),(2,2),(2,3); +# here we can see conditions pushdown (see HAVING): +prepare stmt from " +explain extended +SELECT * FROM t1 +WHERE a = b + AND (a,b) IN (SELECT t2.x, COUNT(t2.y) FROM t2 WHERE 1=2 GROUP BY t2.x);"; +execute stmt; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (/* select#2 */ select `test`.`t2`.`x`,count(`test`.`t2`.`y`) from `test`.`t2` where 0 group by `test`.`t2`.`x` having `COUNT(t2.y)` = `test`.`t2`.`x`) join `test`.`t1` where 0 +# here re-execution of the pushdown does not crash: +prepare stmt from " +SELECT * FROM t1 +WHERE a = b + AND (a,b) IN (SELECT t2.x, COUNT(t2.y) FROM t2 WHERE 1=2 GROUP BY t2.x);"; +execute stmt; +a b +execute stmt; +a b +execute stmt; +a b +drop table t1,t2; diff --git a/mysql-test/main/subselect_innodb.test b/mysql-test/main/subselect_innodb.test index 544bcd994ed..b8d12d04a5e 100644 --- a/mysql-test/main/subselect_innodb.test +++ b/mysql-test/main/subselect_innodb.test @@ -611,3 +611,35 @@ FROM t1 DROP TABLE t1,t2,t3,t4; +--echo # +--echo # MDEV-17362: SIGSEGV in JOIN::optimize_inner or Assertion `fixed == 0' +--echo # failed in Item_equal::fix_fields, server crashes after 2nd execution +--echo # of PS +--echo # + +create table t1 (a int, b int); +create table t2 (x int, y int); + +insert into t1 values (1,1),(2,2); +insert into t2 values (1,1),(2,2),(2,3); + +--echo # here we can see conditions pushdown (see HAVING): +prepare stmt from " +explain extended +SELECT * FROM t1 +WHERE a = b + AND (a,b) IN (SELECT t2.x, COUNT(t2.y) FROM t2 WHERE 1=2 GROUP BY t2.x);"; + +execute stmt; + +--echo # here re-execution of the pushdown does not crash: +prepare stmt from " +SELECT * FROM t1 +WHERE a = b + AND (a,b) IN (SELECT t2.x, COUNT(t2.y) FROM t2 WHERE 1=2 GROUP BY t2.x);"; + +execute stmt; +execute stmt; +execute stmt; + +drop table t1,t2; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 548383e818c..c2412657371 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -1293,11 +1293,6 @@ bool mysql_derived_reinit(THD *thd, LEX *lex, TABLE_LIST *derived) unit->types.empty(); /* for derived tables & PS (which can't be reset by Item_subselect) */ unit->reinit_exec_mechanism(); - for (st_select_lex *sl= unit->first_select(); sl; sl= sl->next_select()) - { - sl->cond_pushed_into_where= NULL; - sl->cond_pushed_into_having= NULL; - } unit->set_thd(thd); DBUG_RETURN(FALSE); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 06701d9808d..fc4aaa82f33 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3026,6 +3026,10 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) for (order= win_spec->order_list->first; order; order= order->next) order->item= &order->item_ptr; } + + // Reinit Pushdown + sl->cond_pushed_into_where= NULL; + sl->cond_pushed_into_having= NULL; } if (sl->changed_elements & TOUCHED_SEL_DERIVED) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f96b3409578..5bdb81bce0f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13463,8 +13463,10 @@ void JOIN::join_free() void JOIN::cleanup(bool full) { DBUG_ENTER("JOIN::cleanup"); - DBUG_PRINT("enter", ("full %u", (uint) full)); - + DBUG_PRINT("enter", ("select: %d (%p) join: %p full: %u", + select_lex->select_number, select_lex, this, + (uint) full)); + if (full) have_query_plan= QEP_DELETED;