From 59e64b6c9bdcfd576db5118e5e33df2c813233dd Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 2 Aug 2012 17:06:05 +0400 Subject: [PATCH] MDEV-416: Server crashes in SQL_SELECT::cleanup on EXPLAIN with SUM ( DISTINCT ) - When JOIN::cleanup(full==TRUE) is called, the select can be in two states: = Right after the create_sort_index() call, when join->join_tab[0] is used to read data produced by filesort(). = After create_sort_index(), and after JOIN::reinit() calls, when join->join_tab[0] has been reset to read the original data. - We didn't handle the second case correctly, which resulted in an attempt to free the same SQL_SELECT two times. The fix is to make sure we don't double-free. --- mysql-test/r/show_explain.result | 13 +++++++++++++ mysql-test/t/show_explain.test | 14 ++++++++++++++ sql/sql_select.cc | 16 +++++++++++++--- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/show_explain.result b/mysql-test/r/show_explain.result index 6ff9a0d0f4e..7f942c2e227 100644 --- a/mysql-test/r/show_explain.result +++ b/mysql-test/r/show_explain.result @@ -998,5 +998,18 @@ Note 1003 SELECT b AS field1, b AS field2 FROM t1, t2, t3 WHERE d = b ORDER BY f field1 field2 set debug_dbug=''; DROP TABLE t1,t2,t3; +# +# MDEV-416: Server crashes in SQL_SELECT::cleanup on EXPLAIN with SUM ( DISTINCT ) in a non-correlated subquery (5.5-show-explain tree) +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (8),(9); +EXPLAIN SELECT * FROM t1 +WHERE ( 8, 89 ) IN ( SELECT b, SUM( DISTINCT b ) FROM t2 GROUP BY b ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using filesort +DROP TABLE t1,t2; # End drop table t0; diff --git a/mysql-test/t/show_explain.test b/mysql-test/t/show_explain.test index 24b01402287..edc9907356d 100644 --- a/mysql-test/t/show_explain.test +++ b/mysql-test/t/show_explain.test @@ -1026,5 +1026,19 @@ set debug_dbug=''; DROP TABLE t1,t2,t3; +--echo # +--echo # MDEV-416: Server crashes in SQL_SELECT::cleanup on EXPLAIN with SUM ( DISTINCT ) in a non-correlated subquery (5.5-show-explain tree) +--echo # +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (8),(9); + +EXPLAIN SELECT * FROM t1 +WHERE ( 8, 89 ) IN ( SELECT b, SUM( DISTINCT b ) FROM t2 GROUP BY b ); + +DROP TABLE t1,t2; + --echo # End drop table t0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 02be522290d..815ff7229a2 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10731,9 +10731,22 @@ void JOIN::cleanup(bool full) if (full) { + JOIN_TAB *sort_tab= first_linear_tab(this, WITHOUT_CONST_TABLES); + if (pre_sort_join_tab) + { + if (sort_tab && sort_tab->select == pre_sort_join_tab->select) + { + pre_sort_join_tab->select= NULL; + } + else + clean_pre_sort_join_tab(); + } + for (tab= first_linear_tab(this, WITH_CONST_TABLES); tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) + { tab->cleanup(); + } } else { @@ -10755,9 +10768,6 @@ void JOIN::cleanup(bool full) */ if (full) { - if (pre_sort_join_tab) - clean_pre_sort_join_tab(); - if (tmp_join) tmp_table_param.copy_field= 0; group_fields.delete_elements();