diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index c2bc80c4641..5cc10e49c51 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -3021,4 +3021,22 @@ 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; +# +# Bug#54488 crash when using explain and prepared statements with subqueries +# +CREATE TABLE t1(f1 INT); +INSERT INTO t1 VALUES (1),(1); +PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))'; +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +EXECUTE stmt; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +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 036c8404095..9b3f3e750e1 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3090,4 +3090,15 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; +--echo # +--echo # Bug#54488 crash when using explain and prepared statements with subqueries +--echo # +CREATE TABLE t1(f1 INT); +INSERT INTO t1 VALUES (1),(1); +PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))'; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + --echo End of 5.1 tests. diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index b93ea6f241b..2daeeb12b6d 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1914,18 +1914,22 @@ int subselect_single_select_engine::exec() } if (!select_lex->uncacheable && thd->lex->describe && !(join->select_options & SELECT_DESCRIBE) && - join->need_tmp && item->const_item()) + join->need_tmp) { - /* - Force join->join_tmp creation, because this subquery will be replaced - by a simple select from the materialization temp table by optimize() - called by EXPLAIN and we need to preserve the initial query structure - so we can display it. - */ - select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; - select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; - if (join->init_save_join_tab()) - DBUG_RETURN(1); /* purecov: inspected */ + item->update_used_tables(); + if (item->const_item()) + { + /* + Force join->join_tmp creation, because this subquery will be replaced + by a simple select from the materialization temp table by optimize() + called by EXPLAIN and we need to preserve the initial query structure + so we can display it. + */ + select_lex->uncacheable|= UNCACHEABLE_EXPLAIN; + select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN; + if (join->init_save_join_tab()) + DBUG_RETURN(1); /* purecov: inspected */ + } } if (item->engine_changed) {