From b4c9fa321dd1fc08227333439695ec4314fb34c8 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 6 Dec 2011 02:46:42 -0800 Subject: [PATCH] Fixed LP bug #899509. The optimizer must ignore any possible hash join key when looking for the query execution plan with join_cache_level set to 0. --- mysql-test/r/derived.result | 4 +-- mysql-test/r/join_cache.result | 38 ++++++++++++++++++++++++++ mysql-test/r/subselect_extra.result | 2 +- mysql-test/suite/pbxt/r/derived.result | 4 +-- mysql-test/t/join_cache.test | 29 ++++++++++++++++++++ sql/sql_select.cc | 4 ++- 6 files changed, 75 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index f34810ada6a..a9247ff41bf 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -192,13 +192,13 @@ pla_id test explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join) 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join) 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 drop table t1,t2; diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index 8372f68fde0..ef5c0a66130 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5226,4 +5226,42 @@ a b c SET SESSION join_cache_level = DEFAULT; SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# Bug #899509: an attempt to use hash join with join_cache_level=0 +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (8), (7); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (8), (7); +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (8), (7); +SET @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch=default; +set @@optimizer_switch='semijoin_with_cache=off'; +set @@optimizer_switch='outer_join_with_cache=off'; +SET optimizer_switch='derived_merge=off,derived_with_keys=off'; +SET join_cache_level=0; +EXPLAIN +SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 +1 PRIMARY ALL NULL NULL NULL NULL 4 Using where +3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 +2 DERIVED t1 ALL NULL NULL NULL NULL 2 +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3); +a +8 +8 +7 +7 +SELECT * FROM ( SELECT ta.* FROM t1 AS ta, t1 ) tb WHERE a IN ( SELECT * FROM t1 ); +a +8 +8 +7 +7 +SET SESSION join_cache_level = DEFAULT; +SET optimizer_switch=@tmp_optimizer_switch; +DROP TABLE t1,t2,t3; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result index c9f69c9e3c1..23c4849b120 100644 --- a/mysql-test/r/subselect_extra.result +++ b/mysql-test/r/subselect_extra.result @@ -432,7 +432,7 @@ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 system NULL NULL NULL NULL 1 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where -1 PRIMARY ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary +1 PRIMARY ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join) 3 DERIVED t1 ALL NULL NULL NULL NULL 3 SELECT * FROM t3 WHERE t3.b IN (SELECT v1.b FROM v1, t2 diff --git a/mysql-test/suite/pbxt/r/derived.result b/mysql-test/suite/pbxt/r/derived.result index 1e4126315fb..d59316b04db 100644 --- a/mysql-test/suite/pbxt/r/derived.result +++ b/mysql-test/suite/pbxt/r/derived.result @@ -192,13 +192,13 @@ pla_id test explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join) 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY m2 ALL NULL NULL NULL NULL 9 -1 PRIMARY ALL NULL NULL NULL NULL 9 Using where +1 PRIMARY ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join) 2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort 2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1 drop table t1,t2; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 66381150ede..ac92ff1631b 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -3294,5 +3294,34 @@ SET optimizer_switch=@tmp_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # Bug #899509: an attempt to use hash join with join_cache_level=0 +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (8), (7); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (8), (7); +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (8), (7); + +SET @tmp_optimizer_switch=@@optimizer_switch; +set optimizer_switch=default; +set @@optimizer_switch='semijoin_with_cache=off'; +set @@optimizer_switch='outer_join_with_cache=off'; +SET optimizer_switch='derived_merge=off,derived_with_keys=off'; +SET join_cache_level=0; + +EXPLAIN +SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3); +SELECT * FROM (SELECT t1.* FROM t1, t2) t WHERE t.a IN (SELECT * FROM t3); + +SELECT * FROM ( SELECT ta.* FROM t1 AS ta, t1 ) tb WHERE a IN ( SELECT * FROM t1 ); + +SET SESSION join_cache_level = DEFAULT; +SET optimizer_switch=@tmp_optimizer_switch; + +DROP TABLE t1,t2,t3; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b0fd09b7f24..ba7ae875be9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5381,7 +5381,9 @@ best_access_path(JOIN *join, (1) s is inner table of semi-join -> join cache is allowed for semijoins (2) s is inner table of outer join -> join cache is allowed for outer joins */ - if (idx > join->const_tables && best_key == 0 && + if (idx > join->const_tables && best_key == 0 && + (join->allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) && + join->max_allowed_join_cache_level > 2 && !bitmap_is_clear_all(eq_join_set) && !disable_jbuf && (!s->emb_sj_nest || join->allowed_semijoin_with_cache) && // (1)