From b76277fce5a375b931ae2f967e26956539eb1ffc Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Thu, 23 Sep 2010 10:43:51 +0400 Subject: [PATCH] Bug#54494 crash with explain extended and prepared statements In case of outer join and emtpy WHERE conditon 'always true' condition is created for WHERE clasue. Later in mysql_select() original SELECT_LEX WHERE condition is overwritten with created cond. However SELECT_LEX condition is also used as inital condition in mysql_select()->JOIN::prepare(). On second execution of PS modified SELECT_LEX condition is taken and it leads to crash. The fix is to restore original SELECT_LEX condition (set to NULL if original cond is NULL) in reinit_stmt_before_use(). HAVING clause is fixed too for safety reason (no test case as I did not manage to think out appropriate example). mysql-test/r/ps.result: test case mysql-test/t/ps.test: test case sql/sql_prepare.cc: restore original SELECT_LEX condition (set to NULL if original cond is NULL) in reinit_stmt_before_use() --- mysql-test/r/ps.result | 20 ++++++++++++++++++++ mysql-test/t/ps.test | 11 +++++++++++ sql/sql_prepare.cc | 4 ++++ 3 files changed, 35 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f21f1d83acd..c2bc80c4641 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -3001,4 +3001,24 @@ EXECUTE stmt; 1 DEALLOCATE PREPARE stmt; DROP TABLE t1; +# +# Bug#54494 crash with explain extended and prepared statements +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2); +PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1 +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 4390b70e9e9..036c8404095 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3079,4 +3079,15 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # Bug#54494 crash with explain extended and prepared statements +--echo # +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2); +PREPARE stmt FROM 'EXPLAIN EXTENDED SELECT 1 FROM t1 RIGHT JOIN t1 t2 ON 1'; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + --echo End of 5.1 tests. diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d6eb90a57be..5ba375f9710 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2362,11 +2362,15 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) sl->where= sl->prep_where->copy_andor_structure(thd); sl->where->cleanup(); } + else + sl->where= NULL; if (sl->prep_having) { sl->having= sl->prep_having->copy_andor_structure(thd); sl->having->cleanup(); } + else + sl->having= NULL; DBUG_ASSERT(sl->join == 0); ORDER *order; /* Fix GROUP list */