diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index c90596315e1..bce5afaec43 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -6700,5 +6700,21 @@ Handler_read_rnd 0 Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 drop table t1, t2, t3; +# +# MDEV-288 CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +CREATE TABLE t2 (b INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +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 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +a +drop table t1,t2; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result index 0722ca7ba88..4ffb4600f77 100644 --- a/mysql-test/r/subselect_no_mat.result +++ b/mysql-test/r/subselect_no_mat.result @@ -6698,6 +6698,22 @@ Handler_read_rnd 0 Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 drop table t1, t2, t3; +# +# MDEV-288 CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +CREATE TABLE t2 (b INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +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 Select tables optimized away +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +a +drop table t1,t2; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result index 27cf1f70864..c8251f67d2a 100644 --- a/mysql-test/r/subselect_no_opts.result +++ b/mysql-test/r/subselect_no_opts.result @@ -6695,6 +6695,22 @@ Handler_read_rnd 0 Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 drop table t1, t2, t3; +# +# MDEV-288 CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +CREATE TABLE t2 (b INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +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 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +a +drop table t1,t2; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result index 9994ede79de..07652189bfe 100644 --- a/mysql-test/r/subselect_no_scache.result +++ b/mysql-test/r/subselect_no_scache.result @@ -6706,6 +6706,22 @@ Handler_read_rnd 0 Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 drop table t1, t2, t3; +# +# MDEV-288 CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +CREATE TABLE t2 (b INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +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 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +a +drop table t1,t2; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set optimizer_switch=default; diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result index 1973262cdaf..ecef51beb07 100644 --- a/mysql-test/r/subselect_no_semijoin.result +++ b/mysql-test/r/subselect_no_semijoin.result @@ -6695,6 +6695,22 @@ Handler_read_rnd 0 Handler_read_rnd_deleted 0 Handler_read_rnd_next 16 drop table t1, t2, t3; +# +# MDEV-288 CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +CREATE TABLE t2 (b INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +EXPLAIN +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +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 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +a +drop table t1,t2; # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; set @optimizer_switch_for_subselect_test=null; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1cbb15b0b95..1074416cea6 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -5624,5 +5624,22 @@ show status like '%Handler_read%'; drop table t1, t2, t3; +--echo # +--echo # MDEV-288 CHEAP SQ: Valgrind warnings "Memory lost" with IN and EXISTS nested subquery, materialization+semijoin +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); + +CREATE TABLE t2 (b INT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); + +EXPLAIN +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); +SELECT * FROM t1 WHERE 4 IN (SELECT MAX(b) FROM t2 WHERE EXISTS (SELECT * FROM t1)); + +drop table t1,t2; + + --echo # return optimizer switch changed in the beginning of this test set optimizer_switch=@subselect_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 10c841639a9..865f3a9d425 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10595,6 +10595,22 @@ void JOIN::cleanup(bool full) tmp_join->tmp_table_param.save_copy_field= 0; } tmp_table_param.cleanup(); + + if (!join_tab) + { + List_iterator li(*join_list); + TABLE_LIST *table_ref; + while ((table_ref= li++)) + { + if (table_ref->table && + table_ref->jtbm_subselect && + table_ref->jtbm_subselect->is_jtbm_const_tab) + { + free_tmp_table(thd, table_ref->table); + table_ref->table= NULL; + } + } + } } DBUG_VOID_RETURN; }