From f0791b8b6b02286a7a01b7659050f3bd900a3529 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 1 May 2009 00:20:37 +0500 Subject: [PATCH] Bug #37362: Crash in do_field_eq EXPLAIN EXTENDED of nested query containing a error: 1054 Unknown column '...' in 'field list' may cause a server crash. Parse error like described above forces a call to JOIN::destroy() on malformed subquery. That JOIN::destroy function closes and frees temporary tables. However, temporary fields of these tables may be listed in st_select_lex::group_list of outer query, and that st_select_lex may not cleanup them properly. So, after the JOIN::destroy call that st_select_lex::group_list may have Item_field objects with dangling pointers to freed temporary table Field objects. That caused a crash. mysql-test/r/subselect3.result: Added test case for bug #37362. mysql-test/t/subselect3.test: Added test case for bug #37362. sql/sql_select.cc: Bug #37362: Crash in do_field_eq The JOIN::destroy function has been modified to cleanup temporary table column items. --- mysql-test/r/subselect3.result | 19 +++++++++++++++++++ mysql-test/t/subselect3.test | 19 +++++++++++++++++++ sql/sql_select.cc | 8 ++++++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 9a6f4436ff0..759c6689be8 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -849,4 +849,23 @@ ROW(1,2) = (SELECT 1, 1) ROW(1,2) IN (SELECT 1, 1) SELECT ROW(1,2) = (SELECT 1, 2), ROW(1,2) IN (SELECT 1, 2); ROW(1,2) = (SELECT 1, 2) ROW(1,2) IN (SELECT 1, 2) 1 1 +CREATE TABLE t1 (a INT, b INT, c INT); +INSERT INTO t1 VALUES (1,1,1), (1,1,1); +EXPLAIN EXTENDED +SELECT c FROM +( SELECT +(SELECT COUNT(a) FROM +(SELECT COUNT(b) FROM t1) AS x GROUP BY c +) FROM t1 GROUP BY b +) AS y; +ERROR 42S22: Unknown column 'c' in 'field list' +SHOW WARNINGS; +Level Code Message +Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2 +Note 1276 Field or reference 'test.t1.c' of SELECT #3 was resolved in SELECT #2 +Error 1054 Unknown column 'c' in 'field list' +Note 1003 select `c` AS `c` from (select (select count(`test`.`t1`.`a`) AS `COUNT(a)` from (select count(`test`.`t1`.`b`) AS `COUNT(b)` from `test`.`t1`) `x` group by `c`) AS `(SELECT COUNT(a) FROM +(SELECT COUNT(b) FROM t1) AS x GROUP BY c +)` from `test`.`t1` group by `test`.`t1`.`b`) `y` +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test index 2d88d1660b0..6f08ebef86d 100644 --- a/mysql-test/t/subselect3.test +++ b/mysql-test/t/subselect3.test @@ -669,4 +669,23 @@ SELECT ROW(1,2) = (SELECT NULL, 1), ROW(1,2) IN (SELECT NULL, 1); SELECT ROW(1,2) = (SELECT 1, 1), ROW(1,2) IN (SELECT 1, 1); SELECT ROW(1,2) = (SELECT 1, 2), ROW(1,2) IN (SELECT 1, 2); +# +# Bug #37362 Crash in do_field_eq +# +CREATE TABLE t1 (a INT, b INT, c INT); +INSERT INTO t1 VALUES (1,1,1), (1,1,1); + +--error 1054 +EXPLAIN EXTENDED + SELECT c FROM + ( SELECT + (SELECT COUNT(a) FROM + (SELECT COUNT(b) FROM t1) AS x GROUP BY c + ) FROM t1 GROUP BY b + ) AS y; +SHOW WARNINGS; + +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index da3731865ba..9a457f2690d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2161,6 +2161,14 @@ JOIN::destroy() cond_equal= 0; cleanup(1); + /* Cleanup items referencing temporary table columns */ + if (!tmp_all_fields3.is_empty()) + { + List_iterator_fast it(tmp_all_fields3); + Item *item; + while ((item= it++)) + item->cleanup(); + } if (exec_tmp_table1) free_tmp_table(thd, exec_tmp_table1); if (exec_tmp_table2)