From b6e3a9e28c731429f4cdebc78cef580a8cf3a1f4 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 26 Jul 2008 13:44:07 -0700 Subject: [PATCH] Fixed bug #38191. Calling List::delete_elements for the same list twice caused a crash of the server in the function JOIN::cleaunup. Ensured that delete_elements() in JOIN::cleanup would be called only once. mysql-test/r/subselect.result: Added a test case for bug #38191. mysql-test/t/subselect.test: Added a test case for bug #38191. sql/sql_select.cc: Fixed bug #38191. Ensured that delete_elements() in JOIN::cleanup would be called only once. --- mysql-test/r/subselect.result | 11 +++++++++++ mysql-test/t/subselect.test | 12 ++++++++++++ sql/sql_select.cc | 6 ++++++ 3 files changed, 29 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 12e3aac486e..c5bae840214 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4396,4 +4396,15 @@ id select_type table type possible_keys key key_len ref rows Extra Warnings: Note 1003 select 1 AS `1` from `test`.`t1` where (1,(select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having ((1) = (1)))) DROP TABLE t1; +CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a)); +INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20); +CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a)); +INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100); +SELECT * FROM t1 +WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); +pk a +1 10 +3 30 +2 20 +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 4d9507f1231..2dfad2c58dd 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3295,5 +3295,17 @@ EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a); EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a); DROP TABLE t1; +# +# Bug #38191: Server crash with subquery containing DISTINCT and ORDER BY +# + +CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a)); +INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20); +CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a)); +INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100); +SELECT * FROM t1 + WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); +DROP TABLE t1,t2; + --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 60ba7591726..c222b8a55ca 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6469,6 +6469,12 @@ void JOIN::cleanup(bool full) if (tmp_join) tmp_table_param.copy_field= 0; group_fields.delete_elements(); + /* + Ensure that the above delete_elements() would not be called + twice for the same list. + */ + if (tmp_join && tmp_join != this) + tmp_join->group_fields= group_fields; /* We can't call delete_elements() on copy_funcs as this will cause problems in free_elements() as some of the elements are then deleted.