From d1138283b9d7e4857126dcee335f1bafb2da0982 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 20 May 2011 01:05:06 +0400 Subject: [PATCH] BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 - in advance_sj_state(), remember join->cur_dups_producing_tables in pos->prefix_dups_producing_tables *before* we modify it, so that restore_prev_sj_state() restores cur_dups_producing_tables in all cases. - Updated test results in subselect_sj2[_jcl6].result (the original EXPLAIN was invalid there) --- mysql-test/r/subselect_sj.result | 27 ++++++++++++++++++++++++++ mysql-test/r/subselect_sj2.result | 5 +++-- mysql-test/r/subselect_sj2_jcl6.result | 7 ++++--- mysql-test/r/subselect_sj_jcl6.result | 27 ++++++++++++++++++++++++++ mysql-test/t/subselect_sj.test | 19 ++++++++++++++++++ sql/opt_subselect.cc | 2 +- 6 files changed, 81 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result index 1fc5955f493..f6374d1a65c 100644 --- a/mysql-test/r/subselect_sj.result +++ b/mysql-test/r/subselect_sj.result @@ -1240,4 +1240,31 @@ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) AND pk = 9; datetime_key DROP TABLE t1, t2, t3; +# +# BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 +# +CREATE TABLE t1 ( t1field integer, primary key (t1field)); +CREATE TABLE t2 ( t2field integer, primary key (t2field)); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2),(3),(4); +explain +SELECT * FROM t1 A +WHERE +A.t1field IN (SELECT A.t1field FROM t2 B) AND +A.t1field IN (SELECT C.t2field FROM t2 C +WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY A index PRIMARY PRIMARY 4 NULL 3 Using index; Start temporary +1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY C eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index +1 PRIMARY D eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index +SELECT * FROM t1 A +WHERE +A.t1field IN (SELECT A.t1field FROM t2 B) AND +A.t1field IN (SELECT C.t2field FROM t2 C +WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +t1field +2 +3 +drop table t1,t2; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result index 56c0f45ea1d..ab7b3898268 100644 --- a/mysql-test/r/subselect_sj2.result +++ b/mysql-test/r/subselect_sj2.result @@ -311,9 +311,10 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan -1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where +1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 1 1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where +1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where +2 SUBQUERY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan DROP TABLE t1,t2,t3; CREATE TABLE t1 ( Code char(3) NOT NULL DEFAULT '', diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result index 31da487158e..faf9d2a5904 100644 --- a/mysql-test/r/subselect_sj2_jcl6.result +++ b/mysql-test/r/subselect_sj2_jcl6.result @@ -318,9 +318,10 @@ t2.Code IN (SELECT Country FROM t3 WHERE Language='English' AND Percentage > 10 AND t2.Population > 100000); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan -1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan -1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 1 +1 PRIMARY t2 eq_ref PRIMARY,Population PRIMARY 3 test.t1.Country 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +2 SUBQUERY t1 range Population,Country Population 4 NULL 1 Using index condition; Rowid-ordered scan DROP TABLE t1,t2,t3; CREATE TABLE t1 ( Code char(3) NOT NULL DEFAULT '', diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 46ca02cd71a..83143cf6ae4 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -1248,6 +1248,33 @@ IN (SELECT t3.pk, t3.pk FROM t2 LEFT JOIN t3 ON t3.varchar_key) AND pk = 9; datetime_key DROP TABLE t1, t2, t3; +# +# BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 +# +CREATE TABLE t1 ( t1field integer, primary key (t1field)); +CREATE TABLE t2 ( t2field integer, primary key (t2field)); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2),(3),(4); +explain +SELECT * FROM t1 A +WHERE +A.t1field IN (SELECT A.t1field FROM t2 B) AND +A.t1field IN (SELECT C.t2field FROM t2 C +WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY A index PRIMARY PRIMARY 4 NULL 3 Using index; Start temporary +1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; End temporary; Using join buffer (flat, BNL join) +1 PRIMARY C eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index +1 PRIMARY D eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index +SELECT * FROM t1 A +WHERE +A.t1field IN (SELECT A.t1field FROM t2 B) AND +A.t1field IN (SELECT C.t2field FROM t2 C +WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +t1field +2 +3 +drop table t1,t2; set @@optimizer_switch=@save_optimizer_switch; # # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test index acc37a6f9ae..b478ba69032 100644 --- a/mysql-test/t/subselect_sj.test +++ b/mysql-test/t/subselect_sj.test @@ -1117,6 +1117,25 @@ WHERE (int_nokey, pk) DROP TABLE t1, t2, t3; +--echo # +--echo # BUG#784723: Wrong result with semijoin + nested subqueries in maria-5.3 +--echo # +CREATE TABLE t1 ( t1field integer, primary key (t1field)); +CREATE TABLE t2 ( t2field integer, primary key (t2field)); +INSERT INTO t1 VALUES (1),(2),(3); +INSERT INTO t2 VALUES (2),(3),(4); +explain +SELECT * FROM t1 A +WHERE + A.t1field IN (SELECT A.t1field FROM t2 B) AND + A.t1field IN (SELECT C.t2field FROM t2 C + WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +SELECT * FROM t1 A +WHERE + A.t1field IN (SELECT A.t1field FROM t2 B) AND + A.t1field IN (SELECT C.t2field FROM t2 C + WHERE C.t2field IN (SELECT D.t2field FROM t2 D)); +drop table t1,t2; # The following command must be the last one the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index e12412299c5..a4a276bd87c 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1429,6 +1429,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, pos->prefix_record_count= *current_record_count; pos->sj_strategy= SJ_OPT_NONE; + pos->prefix_dups_producing_tables= join->cur_dups_producing_tables; /* Initialize the state or copy it from prev. tables */ if (idx == join->const_tables) { @@ -1861,7 +1862,6 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, } } } - pos->prefix_dups_producing_tables= join->cur_dups_producing_tables; }