Skip to content

Commit 51e1bb7

Browse files
Sergey GlukhovSergey Glukhov
authored andcommitted
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. --BZR-- revision-id: [email protected] property-branch-nick: mysql-5.1-security property-file-info: ld7:file_id62:sp1f-ps.result-20040405154119-efxzt5onloys45nfjak4gt44kr4awkdi7:message9:test case4:path22:mysql-test/r/ps.resulted7:file_id60:sp1f-ps.test-20040405154119-4zqf6po44yypvz5foa2osprg5kb5ok637:message9:test case4:path20:mysql-test/t/ps.tested7:file_id70:sp1f-item_subselect.cc-20020512204640-qep43aqhsfrwkqmrobni6czc3fqj36oo7:message56:call ::update_used_tables() before ::const_item() check.4:path21:sql/item_subselect.ccee testament3-sha1: 3451b951e40721d2396210b7ddb455f0b9671e91
1 parent 32b76df commit 51e1bb7

File tree

3 files changed

+44
-11
lines changed

3 files changed

+44
-11
lines changed

mysql-test/r/ps.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3021,4 +3021,22 @@ Warnings:
30213021
Note 1003 select 1 AS `1` from `test`.`t1` `t2` left join `test`.`t1` on(1) where 1
30223022
DEALLOCATE PREPARE stmt;
30233023
DROP TABLE t1;
3024+
#
3025+
# Bug#54488 crash when using explain and prepared statements with subqueries
3026+
#
3027+
CREATE TABLE t1(f1 INT);
3028+
INSERT INTO t1 VALUES (1),(1);
3029+
PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))';
3030+
EXECUTE stmt;
3031+
id select_type table type possible_keys key key_len ref rows Extra
3032+
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
3033+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3034+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
3035+
EXECUTE stmt;
3036+
id select_type table type possible_keys key key_len ref rows Extra
3037+
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
3038+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
3039+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
3040+
DEALLOCATE PREPARE stmt;
3041+
DROP TABLE t1;
30243042
End of 5.1 tests.

mysql-test/t/ps.test

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3090,4 +3090,15 @@ EXECUTE stmt;
30903090
DEALLOCATE PREPARE stmt;
30913091
DROP TABLE t1;
30923092

3093+
--echo #
3094+
--echo # Bug#54488 crash when using explain and prepared statements with subqueries
3095+
--echo #
3096+
CREATE TABLE t1(f1 INT);
3097+
INSERT INTO t1 VALUES (1),(1);
3098+
PREPARE stmt FROM 'EXPLAIN SELECT 1 FROM t1 WHERE (SELECT (SELECT 1 FROM t1 GROUP BY f1))';
3099+
EXECUTE stmt;
3100+
EXECUTE stmt;
3101+
DEALLOCATE PREPARE stmt;
3102+
DROP TABLE t1;
3103+
30933104
--echo End of 5.1 tests.

sql/item_subselect.cc

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,18 +1914,22 @@ int subselect_single_select_engine::exec()
19141914
}
19151915
if (!select_lex->uncacheable && thd->lex->describe &&
19161916
!(join->select_options & SELECT_DESCRIBE) &&
1917-
join->need_tmp && item->const_item())
1917+
join->need_tmp)
19181918
{
1919-
/*
1920-
Force join->join_tmp creation, because this subquery will be replaced
1921-
by a simple select from the materialization temp table by optimize()
1922-
called by EXPLAIN and we need to preserve the initial query structure
1923-
so we can display it.
1924-
*/
1925-
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
1926-
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
1927-
if (join->init_save_join_tab())
1928-
DBUG_RETURN(1); /* purecov: inspected */
1919+
item->update_used_tables();
1920+
if (item->const_item())
1921+
{
1922+
/*
1923+
Force join->join_tmp creation, because this subquery will be replaced
1924+
by a simple select from the materialization temp table by optimize()
1925+
called by EXPLAIN and we need to preserve the initial query structure
1926+
so we can display it.
1927+
*/
1928+
select_lex->uncacheable|= UNCACHEABLE_EXPLAIN;
1929+
select_lex->master_unit()->uncacheable|= UNCACHEABLE_EXPLAIN;
1930+
if (join->init_save_join_tab())
1931+
DBUG_RETURN(1); /* purecov: inspected */
1932+
}
19291933
}
19301934
if (item->engine_changed)
19311935
{

0 commit comments

Comments
 (0)