Commit 2cc22718 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #887496.

This bug in the function Loose_scan_opt::check_ref_access_part1 could lead
to choosing an invalid execution plan employing a loose scan access to a
semi-join table even in the cases when such access could not be used at all.
This could result in wrong answers for some queries with IN subqueries.
parent 5bef088e
...@@ -346,8 +346,8 @@ WHERE t4.a >= t3.b ...@@ -346,8 +346,8 @@ WHERE t4.a >= t3.b
AND a = SOME (SELECT b FROM t5)); AND a = SOME (SELECT b FROM t5));
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 t3 ALL NULL NULL NULL NULL 2 Using where 1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
2 DEPENDENT SUBQUERY t5 index c c 10 NULL 2 Using where; Using index; LooseScan 2 DEPENDENT SUBQUERY t5 index c c 10 NULL 2 Using where; Using index; Start temporary
2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t5.b 1 Using index condition; Using where 2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t5.b 1 Using index condition; Using where; End temporary
SELECT * SELECT *
FROM t3 FROM t3
WHERE t3.b > ALL ( WHERE t3.b > ALL (
......
...@@ -2050,4 +2050,37 @@ a ...@@ -2050,4 +2050,37 @@ a
3 3
set optimizer_switch= @tmp_otimizer_switch; set optimizer_switch= @tmp_otimizer_switch;
drop table t1,t2; drop table t1,t2;
#
# Bug #887496: semijoin with IN equality for the second part of an index
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (9), (0), (8), (5);
CREATE TABLE t2 (a int, b varchar(1), INDEX idx (b,a));
INSERT INTO t2 VALUES (5,'r'), (5,'z');
CREATE TABLE t3 (a int, b varchar(1), INDEX idx (b,a));
INSERT INTO t3 VALUES (5,'r'), (5,'z');
set @tmp_otimizer_switch= @@optimizer_switch;
SET SESSION optimizer_switch='semijoin=on,firstmatch=on';
SET SESSION optimizer_switch='loosescan=off';
EXPLAIN
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
a
5
SET SESSION optimizer_switch='loosescan=on';
EXPLAIN
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
a
5
set optimizer_switch= @tmp_otimizer_switch;
DROP TABLE t1,t2,t3;
set optimizer_switch=@subselect_sj_tmp; set optimizer_switch=@subselect_sj_tmp;
...@@ -2061,6 +2061,39 @@ a ...@@ -2061,6 +2061,39 @@ a
3 3
set optimizer_switch= @tmp_otimizer_switch; set optimizer_switch= @tmp_otimizer_switch;
drop table t1,t2; drop table t1,t2;
#
# Bug #887496: semijoin with IN equality for the second part of an index
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (9), (0), (8), (5);
CREATE TABLE t2 (a int, b varchar(1), INDEX idx (b,a));
INSERT INTO t2 VALUES (5,'r'), (5,'z');
CREATE TABLE t3 (a int, b varchar(1), INDEX idx (b,a));
INSERT INTO t3 VALUES (5,'r'), (5,'z');
set @tmp_otimizer_switch= @@optimizer_switch;
SET SESSION optimizer_switch='semijoin=on,firstmatch=on';
SET SESSION optimizer_switch='loosescan=off';
EXPLAIN
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
a
5
SET SESSION optimizer_switch='loosescan=on';
EXPLAIN
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index idx idx 9 NULL 2 Using where; Using index; Start temporary
1 PRIMARY t3 ref idx idx 4 test.t2.b 1 Using index
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
a
5
set optimizer_switch= @tmp_otimizer_switch;
DROP TABLE t1,t2,t3;
set optimizer_switch=@subselect_sj_tmp; set optimizer_switch=@subselect_sj_tmp;
# #
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
......
...@@ -1880,5 +1880,35 @@ set optimizer_switch= @tmp_otimizer_switch; ...@@ -1880,5 +1880,35 @@ set optimizer_switch= @tmp_otimizer_switch;
drop table t1,t2; drop table t1,t2;
--echo #
--echo # Bug #887496: semijoin with IN equality for the second part of an index
--echo #
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (9), (0), (8), (5);
CREATE TABLE t2 (a int, b varchar(1), INDEX idx (b,a));
INSERT INTO t2 VALUES (5,'r'), (5,'z');
CREATE TABLE t3 (a int, b varchar(1), INDEX idx (b,a));
INSERT INTO t3 VALUES (5,'r'), (5,'z');
set @tmp_otimizer_switch= @@optimizer_switch;
SET SESSION optimizer_switch='semijoin=on,firstmatch=on';
SET SESSION optimizer_switch='loosescan=off';
EXPLAIN
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
SET SESSION optimizer_switch='loosescan=on';
EXPLAIN
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
SELECT * FROM t1 WHERE a IN (SELECT t2.a FROM t2,t3 WHERE t2.b = t3.b);
set optimizer_switch= @tmp_otimizer_switch;
DROP TABLE t1,t2,t3;
# The following command must be the last one the file # The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp; set optimizer_switch=@subselect_sj_tmp;
...@@ -170,7 +170,7 @@ class Loose_scan_opt ...@@ -170,7 +170,7 @@ class Loose_scan_opt
PREV_BITS(ulonglong, s->emb_sj_nest->sj_in_exprs) && // (2) PREV_BITS(ulonglong, s->emb_sj_nest->sj_in_exprs) && // (2)
(PREV_BITS(key_part_map, max_loose_keypart+1) & // (3) (PREV_BITS(key_part_map, max_loose_keypart+1) & // (3)
(found_part | loose_scan_keyparts)) == // (3) (found_part | loose_scan_keyparts)) == // (3)
(found_part | loose_scan_keyparts) && // (3) PREV_BITS(key_part_map, max_loose_keypart+1) && // (3)
!key_uses_partial_cols(s->table, key)) !key_uses_partial_cols(s->table, key))
{ {
/* Ok, can use the strategy */ /* Ok, can use the strategy */
......
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