Commit acc161d3 authored by Sergey Petrunya's avatar Sergey Petrunya

BUG#752992: Wrong results for a subquery with 'semijoin=on'

- Let advance_sj_state() save the value of JOIN::cur_dups_producing_tables
  in POSITION::prefix_dups_producing_tables, and restore_sj_state() restore
  it. 
parent 2a498b39
...@@ -5046,3 +5046,25 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -5046,3 +5046,25 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index 2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
#
CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t1 VALUES (11,0);
INSERT INTO t1 VALUES (12,5);
INSERT INTO t1 VALUES (15,0);
CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t2 VALUES (11,1);
INSERT INTO t2 VALUES (12,2);
INSERT INTO t2 VALUES (15,4);
EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 Start temporary
1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; End temporary
SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
pk i
11 0
12 5
15 0
DROP table t1,t2;
...@@ -1142,15 +1142,15 @@ create table t1 (a int) as select * from t0 where a < 5; ...@@ -1142,15 +1142,15 @@ create table t1 (a int) as select * from t0 where a < 5;
set @save_max_heap_table_size=@@max_heap_table_size; set @save_max_heap_table_size=@@max_heap_table_size;
set @@optimizer_switch='firstmatch=off,materialization=off'; set @@optimizer_switch='firstmatch=off,materialization=off';
set @@max_heap_table_size= 16384; set @@max_heap_table_size= 16384;
explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary 1 PRIMARY E ALL NULL NULL NULL NULL 5 Start temporary
1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY D ALL NULL NULL NULL NULL 10 Using where; End temporary; Using join buffer (flat, BNL join)
flush status; flush status;
select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
count(*) count(*)
5000 5000
show status like 'Created_tmp_disk_tables'; show status like 'Created_tmp_disk_tables';
......
...@@ -1149,15 +1149,15 @@ create table t1 (a int) as select * from t0 where a < 5; ...@@ -1149,15 +1149,15 @@ create table t1 (a int) as select * from t0 where a < 5;
set @save_max_heap_table_size=@@max_heap_table_size; set @save_max_heap_table_size=@@max_heap_table_size;
set @@optimizer_switch='firstmatch=off,materialization=off'; set @@optimizer_switch='firstmatch=off,materialization=off';
set @@max_heap_table_size= 16384; set @@max_heap_table_size= 16384;
explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary 1 PRIMARY E ALL NULL NULL NULL NULL 5 Using where; Start temporary
1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join) 1 PRIMARY A ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join) 1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join)
1 PRIMARY C ALL NULL NULL NULL NULL 10 Using join buffer (incremental, BNL join) 1 PRIMARY C ALL NULL NULL NULL NULL 10 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY D hash_ALL NULL #hash#$hj 5 test.E.a 10 Using where; End temporary; Using join buffer (incremental, BNLH join) 1 PRIMARY D hash_ALL NULL #hash#$hj 5 test.E.a 10 Using where; End temporary; Using join buffer (incremental, BNLH join)
flush status; flush status;
select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
count(*) count(*)
5000 5000
show status like 'Created_tmp_disk_tables'; show status like 'Created_tmp_disk_tables';
......
...@@ -5048,6 +5048,28 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -5048,6 +5048,28 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index 2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
#
CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t1 VALUES (11,0);
INSERT INTO t1 VALUES (12,5);
INSERT INTO t1 VALUES (15,0);
CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t2 VALUES (11,1);
INSERT INTO t2 VALUES (12,2);
INSERT INTO t2 VALUES (15,4);
EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 Start temporary
1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; End temporary
SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
pk i
11 0
12 5
15 0
DROP table t1,t2;
set optimizer_switch=default; set optimizer_switch=default;
select @@optimizer_switch like '%materialization=on%'; select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%' @@optimizer_switch like '%materialization=on%'
......
...@@ -5045,4 +5045,26 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -5045,4 +5045,26 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index 2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
#
CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t1 VALUES (11,0);
INSERT INTO t1 VALUES (12,5);
INSERT INTO t1 VALUES (15,0);
CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t2 VALUES (11,1);
INSERT INTO t2 VALUES (12,2);
INSERT INTO t2 VALUES (15,4);
EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index
SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
pk i
11 0
12 5
15 0
DROP table t1,t2;
set optimizer_switch=default; set optimizer_switch=default;
...@@ -5045,4 +5045,26 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -5045,4 +5045,26 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index 2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# BUG#752992: Wrong results for a subquery with 'semijoin=on'
#
CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t1 VALUES (11,0);
INSERT INTO t1 VALUES (12,5);
INSERT INTO t1 VALUES (15,0);
CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t2 VALUES (11,1);
INSERT INTO t2 VALUES (12,2);
INSERT INTO t2 VALUES (15,4);
EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
2 SUBQUERY it index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
pk i
11 0
12 5
15 0
DROP table t1,t2;
set optimizer_switch=default; set optimizer_switch=default;
...@@ -4316,3 +4316,20 @@ SELECT * FROM t1 ...@@ -4316,3 +4316,20 @@ SELECT * FROM t1
WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a); WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # BUG#752992: Wrong results for a subquery with 'semijoin=on'
--echo #
CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t1 VALUES (11,0);
INSERT INTO t1 VALUES (12,5);
INSERT INTO t1 VALUES (15,0);
CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
INSERT INTO t2 VALUES (11,1);
INSERT INTO t2 VALUES (12,2);
INSERT INTO t2 VALUES (15,4);
EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
DROP table t1,t2;
...@@ -949,9 +949,9 @@ set @save_max_heap_table_size=@@max_heap_table_size; ...@@ -949,9 +949,9 @@ set @save_max_heap_table_size=@@max_heap_table_size;
set @@optimizer_switch='firstmatch=off,materialization=off'; set @@optimizer_switch='firstmatch=off,materialization=off';
set @@max_heap_table_size= 16384; set @@max_heap_table_size= 16384;
explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
flush status; flush status;
select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E); select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E where a+1 < 10000 + A.a + B.a +C.a+D.a);
show status like 'Created_tmp_disk_tables'; show status like 'Created_tmp_disk_tables';
set @save_max_heap_table_size=@@max_heap_table_size; set @save_max_heap_table_size=@@max_heap_table_size;
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
......
...@@ -1861,6 +1861,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, ...@@ -1861,6 +1861,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
} }
} }
} }
pos->prefix_dups_producing_tables= join->cur_dups_producing_tables;
} }
...@@ -1882,6 +1883,8 @@ void restore_prev_sj_state(const table_map remaining_tables, ...@@ -1882,6 +1883,8 @@ void restore_prev_sj_state(const table_map remaining_tables,
tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables; tab->join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
} }
} }
POSITION *pos= tab->join->positions + idx;
tab->join->cur_dups_producing_tables= pos->prefix_dups_producing_tables;
} }
......
...@@ -573,6 +573,8 @@ typedef struct st_position ...@@ -573,6 +573,8 @@ typedef struct st_position
semi-join's ON expression so we can correctly account for fanout. semi-join's ON expression so we can correctly account for fanout.
*/ */
table_map sjm_scan_need_tables; table_map sjm_scan_need_tables;
table_map prefix_dups_producing_tables;
} POSITION; } POSITION;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment