Bug#54488 crash when using explain and prepared statements with subqueries

The crash happens because original join table is replaced with temporary table
at execution stage and later we attempt to use this temporary table in
select_describe. It might happen that
Item_subselect::update_used_tables() method which sets const_item flag
is not called by some reasons (no where/having conditon in subquery for example).
It prevents JOIN::join_tmp creation and breaks original join.
The fix is to call ::update_used_tables() before ::const_item() check.


mysql-test/r/ps.result:
  test case
mysql-test/t/ps.test:
  test case
sql/item_subselect.cc:
  call ::update_used_tables() before ::const_item() check.
This commit is contained in:
Sergey Glukhov 2010-10-01 14:08:38 +04:00
parent b76277fce5
commit 233e4d809a
3 changed files with 44 additions and 11 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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)
{