Commit c2cb8333 authored by Sergey Petrunya's avatar Sergey Petrunya

Merge backported subquery bugfixes/testcases into MariaDB 5.3

parents d64cf60f 942eae87
...@@ -1725,3 +1725,154 @@ m ...@@ -1725,3 +1725,154 @@ m
DROP TABLE t1; DROP TABLE t1;
# #
End of 5.1 tests End of 5.1 tests
#
# BUG#46680 - Assertion failed in file item_subselect.cc,
# line 305 crashing on HAVING subquery
#
# Create tables
#
CREATE TABLE t1 (
pk INT,
v VARCHAR(1) DEFAULT NULL,
PRIMARY KEY(pk)
);
CREATE TABLE t2 LIKE t1;
CREATE TABLE t3 LIKE t1;
CREATE TABLE empty1 (a int);
INSERT INTO t1 VALUES (1,'c'),(2,NULL);
INSERT INTO t2 VALUES (3,'m'),(4,NULL);
INSERT INTO t3 VALUES (1,'n');
#
# 1) Test that subquery materialization is setup for query with
# premature optimize() exit due to "Impossible WHERE"
#
SELECT MIN(t2.pk)
FROM t2 JOIN t1 ON t1.pk=t2.pk
WHERE 'j'
HAVING ('m') IN (
SELECT v
FROM t2);
MIN(t2.pk)
NULL
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'j'
EXPLAIN
SELECT MIN(t2.pk)
FROM t2 JOIN t1 ON t1.pk=t2.pk
WHERE 'j'
HAVING ('m') IN (
SELECT v
FROM t2);
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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'j'
#
# 2) Test that subquery materialization is setup for query with
# premature optimize() exit due to "No matching min/max row"
#
SELECT MIN(t2.pk)
FROM t2
WHERE t2.pk>10
HAVING ('m') IN (
SELECT v
FROM t2);
MIN(t2.pk)
NULL
EXPLAIN
SELECT MIN(t2.pk)
FROM t2
WHERE t2.pk>10
HAVING ('m') IN (
SELECT v
FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
#
# 3) Test that subquery materialization is setup for query with
# premature optimize() exit due to "Select tables optimized away"
#
# NOTE: The result of this query is actually wrong; it should be NULL
# See BUG#47762. Even so, the test case is still needed to test
# that the HAVING subquery does not crash the server
#
SELECT MIN(pk)
FROM t1
WHERE pk=NULL
HAVING ('m') IN (
SELECT v
FROM t2);
MIN(pk)
NULL
EXPLAIN
SELECT MIN(pk)
FROM t1
WHERE pk=NULL
HAVING ('m') IN (
SELECT v
FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
#
# 4) Test that subquery materialization is setup for query with
# premature optimize() exit due to "No matching row in const table"
#
SELECT MIN(a)
FROM (SELECT a FROM empty1) tt
HAVING ('m') IN (
SELECT v
FROM t2);
MIN(a)
NULL
EXPLAIN
SELECT MIN(a)
FROM (SELECT a FROM empty1) tt
HAVING ('m') IN (
SELECT v
FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2
2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
#
# 5) Test that subquery materialization is setup for query with
# premature optimize() exit due to "Impossible WHERE noticed
# after reading const tables"
#
SELECT min(t1.pk)
FROM t1
WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
HAVING ('m') IN (
SELECT v
FROM t2);
min(t1.pk)
NULL
EXPLAIN
SELECT min(t1.pk)
FROM t1
WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
HAVING ('m') IN (
SELECT v
FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2
#
# Cleanup for BUG#46680
#
DROP TABLE IF EXISTS t1,t2,t3,empty1;
End of 6.0 tests
...@@ -711,4 +711,35 @@ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; ...@@ -711,4 +711,35 @@ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
COUNT(*) COUNT(*)
6145 6145
DROP TABLE t1; DROP TABLE t1;
#
# Testcase Backport: BUG#48093: 6.0 Server not processing equivalent IN clauses properly
# with Innodb tables
#
CREATE TABLE t1 (
i int(11) DEFAULT NULL,
v1 varchar(1) DEFAULT NULL,
v2 varchar(20) DEFAULT NULL,
KEY i (i),
KEY v (v1,i)
) ENGINE=innodb;
INSERT INTO t1 VALUES (1,'f','no');
INSERT INTO t1 VALUES (2,'u','yes-u');
INSERT INTO t1 VALUES (2,'h','yes-h');
INSERT INTO t1 VALUES (3,'d','no');
SELECT v2
FROM t1
WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
v2
yes-u
yes-h
# Should not use index_merge
EXPLAIN
SELECT v2
FROM t1
WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref i,v i 5 const 2 Using where
DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save; set optimizer_switch= @optimizer_switch_save;
...@@ -681,3 +681,46 @@ pk b c ...@@ -681,3 +681,46 @@ pk b c
4 40 0 4 40 0
drop table t1; drop table t1;
set optimizer_use_mrr = @my_save_optimizer_use_mrr; set optimizer_use_mrr = @my_save_optimizer_use_mrr;
#
# Bug#43360 - Server crash with a simple multi-table update
#
CREATE TABLE t1 (
a CHAR(2) NOT NULL PRIMARY KEY,
b VARCHAR(20) NOT NULL,
KEY (b)
) ENGINE=InnoDB;
CREATE TABLE t2 (
a CHAR(2) NOT NULL PRIMARY KEY,
b VARCHAR(20) NOT NULL,
KEY (b)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('AB','MySQLAB'),
('JA','Sun Microsystems'),
('MS','Microsoft'),
('IB','IBM- Inc.'),
('GO','Google Inc.');
INSERT INTO t2 VALUES
('AB','Sweden'),
('JA','USA'),
('MS','United States of America'),
('IB','North America'),
('GO','South America');
Warnings:
Warning 1265 Data truncated for column 'b' at row 3
UPDATE t1,t2 SET t1.b=UPPER(t1.b) WHERE t1.b LIKE 'United%';
SELECT * FROM t1;
a b
GO Google Inc.
IB IBM- Inc.
MS Microsoft
AB MySQLAB
JA Sun Microsystems
SELECT * FROM t2;
a b
IB North America
GO South America
AB Sweden
MS United States of Ame
JA USA
DROP TABLE t1,t2;
...@@ -6220,4 +6220,22 @@ SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1; ...@@ -6220,4 +6220,22 @@ SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
f1 f2 f1 f2 f1 f2 f1 f2
SET SESSION join_cache_level = DEFAULT; SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# Backported testcase for: Bug #45092: join buffer contains two blob columns one of which is
# used in the key employed to access the joined table
#
CREATE TABLE t1 (c1 int, c2 int, key (c2));
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,2);
CREATE TABLE t2 (c1 text, c2 text);
INSERT INTO t2 VALUES('tt', 'uu');
INSERT INTO t2 VALUES('zzzz', 'xxxxxxxxx');
ANALYZE TABLE t1,t2;
set join_cache_level=6;
SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH(t2.c2) FROM t1,t2
WHERE t1.c2=LENGTH(t2.c2) and t1.c1=LENGTH(t2.c1);
c1 c2 c1 c2 LENGTH(t2.c1) LENGTH(t2.c2)
2 2 tt uu 2 2
set join_cache_level=default;
DROP TABLE t1,t2;
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
...@@ -4971,3 +4971,39 @@ k ...@@ -4971,3 +4971,39 @@ k
3 3
drop table t1,t2,t3; drop table t1,t2,t3;
drop view v2; drop view v2;
#
# Bug#52068: Optimizer generates invalid semijoin materialization plan
#
drop table if exists ot1, ot2, it1, it2;
CREATE TABLE ot1(a INTEGER);
INSERT INTO ot1 VALUES(5), (8);
CREATE TABLE it2(a INTEGER);
INSERT INTO it2 VALUES(9), (5), (1), (8);
CREATE TABLE it3(a INTEGER);
INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
CREATE TABLE ot4(a INTEGER);
INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
a a
5 1
8 1
5 5
8 5
5 7
8 7
5 7
8 7
5 1
8 1
explain SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 24
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY it2 ALL NULL NULL NULL NULL 4
2 SUBQUERY it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
DROP TABLE IF EXISTS ot1, ot4, it2, it3;
...@@ -4974,6 +4974,41 @@ k ...@@ -4974,6 +4974,41 @@ k
3 3
drop table t1,t2,t3; drop table t1,t2,t3;
drop view v2; drop view v2;
#
# Bug#52068: Optimizer generates invalid semijoin materialization plan
#
drop table if exists ot1, ot2, it1, it2;
CREATE TABLE ot1(a INTEGER);
INSERT INTO ot1 VALUES(5), (8);
CREATE TABLE it2(a INTEGER);
INSERT INTO it2 VALUES(9), (5), (1), (8);
CREATE TABLE it3(a INTEGER);
INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
CREATE TABLE ot4(a INTEGER);
INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
a a
5 1
8 1
5 5
8 5
5 7
8 7
5 7
8 7
5 1
8 1
explain SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot1 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY it2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (flat, BNL join)
DROP TABLE IF EXISTS ot1, ot4, it2, it3;
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%'
......
...@@ -4971,4 +4971,39 @@ k ...@@ -4971,4 +4971,39 @@ k
3 3
drop table t1,t2,t3; drop table t1,t2,t3;
drop view v2; drop view v2;
#
# Bug#52068: Optimizer generates invalid semijoin materialization plan
#
drop table if exists ot1, ot2, it1, it2;
CREATE TABLE ot1(a INTEGER);
INSERT INTO ot1 VALUES(5), (8);
CREATE TABLE it2(a INTEGER);
INSERT INTO it2 VALUES(9), (5), (1), (8);
CREATE TABLE it3(a INTEGER);
INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
CREATE TABLE ot4(a INTEGER);
INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
a a
5 1
8 1
5 5
8 5
5 7
8 7
5 7
8 7
5 1
8 1
explain SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY it2 ALL NULL NULL NULL NULL 4 Using where
2 DEPENDENT SUBQUERY it3 ALL NULL NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join)
DROP TABLE IF EXISTS ot1, ot4, it2, it3;
set optimizer_switch=default; set optimizer_switch=default;
...@@ -4971,4 +4971,39 @@ k ...@@ -4971,4 +4971,39 @@ k
3 3
drop table t1,t2,t3; drop table t1,t2,t3;
drop view v2; drop view v2;
#
# Bug#52068: Optimizer generates invalid semijoin materialization plan
#
drop table if exists ot1, ot2, it1, it2;
CREATE TABLE ot1(a INTEGER);
INSERT INTO ot1 VALUES(5), (8);
CREATE TABLE it2(a INTEGER);
INSERT INTO it2 VALUES(9), (5), (1), (8);
CREATE TABLE it3(a INTEGER);
INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
CREATE TABLE ot4(a INTEGER);
INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
a a
5 1
8 1
5 5
8 5
5 7
8 7
5 7
8 7
5 1
8 1
explain SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
2 SUBQUERY it2 ALL NULL NULL NULL NULL 4
2 SUBQUERY it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
DROP TABLE IF EXISTS ot1, ot4, it2, it3;
set optimizer_switch=default; set optimizer_switch=default;
...@@ -1099,3 +1099,140 @@ DROP TABLE t1; ...@@ -1099,3 +1099,140 @@ DROP TABLE t1;
--echo # --echo #
--echo End of 5.1 tests --echo End of 5.1 tests
--echo #
--echo # BUG#46680 - Assertion failed in file item_subselect.cc,
--echo # line 305 crashing on HAVING subquery
--echo #
--echo # Create tables
--echo #
CREATE TABLE t1 (
pk INT,
v VARCHAR(1) DEFAULT NULL,
PRIMARY KEY(pk)
);
CREATE TABLE t2 LIKE t1;
CREATE TABLE t3 LIKE t1;
CREATE TABLE empty1 (a int);
INSERT INTO t1 VALUES (1,'c'),(2,NULL);
INSERT INTO t2 VALUES (3,'m'),(4,NULL);
INSERT INTO t3 VALUES (1,'n');
--echo
--echo #
--echo # 1) Test that subquery materialization is setup for query with
--echo # premature optimize() exit due to "Impossible WHERE"
--echo #
SELECT MIN(t2.pk)
FROM t2 JOIN t1 ON t1.pk=t2.pk
WHERE 'j'
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
EXPLAIN
SELECT MIN(t2.pk)
FROM t2 JOIN t1 ON t1.pk=t2.pk
WHERE 'j'
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
--echo #
--echo # 2) Test that subquery materialization is setup for query with
--echo # premature optimize() exit due to "No matching min/max row"
--echo #
SELECT MIN(t2.pk)
FROM t2
WHERE t2.pk>10
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
EXPLAIN
SELECT MIN(t2.pk)
FROM t2
WHERE t2.pk>10
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
--echo #
--echo # 3) Test that subquery materialization is setup for query with
--echo # premature optimize() exit due to "Select tables optimized away"
--echo #
--echo # NOTE: The result of this query is actually wrong; it should be NULL
--echo # See BUG#47762. Even so, the test case is still needed to test
--echo # that the HAVING subquery does not crash the server
--echo #
SELECT MIN(pk)
FROM t1
WHERE pk=NULL
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
EXPLAIN
SELECT MIN(pk)
FROM t1
WHERE pk=NULL
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
--echo #
--echo # 4) Test that subquery materialization is setup for query with
--echo # premature optimize() exit due to "No matching row in const table"
--echo #
--echo
SELECT MIN(a)
FROM (SELECT a FROM empty1) tt
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
EXPLAIN
SELECT MIN(a)
FROM (SELECT a FROM empty1) tt
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
--echo #
--echo # 5) Test that subquery materialization is setup for query with
--echo # premature optimize() exit due to "Impossible WHERE noticed
--echo # after reading const tables"
--echo #
SELECT min(t1.pk)
FROM t1
WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
HAVING ('m') IN (
SELECT v
FROM t2);
--echo
EXPLAIN
SELECT min(t1.pk)
FROM t1
WHERE t1.pk IN (SELECT 1 from t3 where pk>10)
HAVING ('m') IN (
SELECT v
FROM t2);
--echo #
--echo # Cleanup for BUG#46680
--echo #
DROP TABLE IF EXISTS t1,t2,t3,empty1;
###
--echo End of 6.0 tests
...@@ -90,4 +90,37 @@ SELECT COUNT(*) FROM ...@@ -90,4 +90,37 @@ SELECT COUNT(*) FROM
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # Testcase Backport: BUG#48093: 6.0 Server not processing equivalent IN clauses properly
--echo # with Innodb tables
--echo #
CREATE TABLE t1 (
i int(11) DEFAULT NULL,
v1 varchar(1) DEFAULT NULL,
v2 varchar(20) DEFAULT NULL,
KEY i (i),
KEY v (v1,i)
) ENGINE=innodb;
INSERT INTO t1 VALUES (1,'f','no');
INSERT INTO t1 VALUES (2,'u','yes-u');
INSERT INTO t1 VALUES (2,'h','yes-h');
INSERT INTO t1 VALUES (3,'d','no');
--echo
SELECT v2
FROM t1
WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
--echo
--echo # Should not use index_merge
EXPLAIN
SELECT v2
FROM t1
WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save; set optimizer_switch= @optimizer_switch_save;
...@@ -378,4 +378,40 @@ select * from t1 where pk < 2 or pk between 3 and 4; ...@@ -378,4 +378,40 @@ select * from t1 where pk < 2 or pk between 3 and 4;
select * from t1 where pk < 2 or pk between 3 and 4; select * from t1 where pk < 2 or pk between 3 and 4;
drop table t1; drop table t1;
set optimizer_use_mrr = @my_save_optimizer_use_mrr; set optimizer_use_mrr = @my_save_optimizer_use_mrr;
--echo #
--echo # Bug#43360 - Server crash with a simple multi-table update
--echo #
CREATE TABLE t1 (
a CHAR(2) NOT NULL PRIMARY KEY,
b VARCHAR(20) NOT NULL,
KEY (b)
) ENGINE=InnoDB;
CREATE TABLE t2 (
a CHAR(2) NOT NULL PRIMARY KEY,
b VARCHAR(20) NOT NULL,
KEY (b)
) ENGINE=InnoDB;
INSERT INTO t1 VALUES
('AB','MySQLAB'),
('JA','Sun Microsystems'),
('MS','Microsoft'),
('IB','IBM- Inc.'),
('GO','Google Inc.');
INSERT INTO t2 VALUES
('AB','Sweden'),
('JA','USA'),
('MS','United States of America'),
('IB','North America'),
('GO','South America');
UPDATE t1,t2 SET t1.b=UPPER(t1.b) WHERE t1.b LIKE 'United%';
SELECT * FROM t1;
SELECT * FROM t2;
DROP TABLE t1,t2;
...@@ -2846,5 +2846,31 @@ SET SESSION join_cache_level = DEFAULT; ...@@ -2846,5 +2846,31 @@ SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # Backported testcase for: Bug #45092: join buffer contains two blob columns one of which is
--echo # used in the key employed to access the joined table
--echo #
CREATE TABLE t1 (c1 int, c2 int, key (c2));
INSERT INTO t1 VALUES (1,1);
INSERT INTO t1 VALUES (2,2);
CREATE TABLE t2 (c1 text, c2 text);
INSERT INTO t2 VALUES('tt', 'uu');
INSERT INTO t2 VALUES('zzzz', 'xxxxxxxxx');
--disable_result_log
ANALYZE TABLE t1,t2;
--enable_result_log
set join_cache_level=6;
SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH(t2.c2) FROM t1,t2
WHERE t1.c2=LENGTH(t2.c2) and t1.c1=LENGTH(t2.c1);
set join_cache_level=default;
DROP TABLE t1,t2;
# this must be the last command in the file # this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch; set @@optimizer_switch=@save_optimizer_switch;
...@@ -4251,3 +4251,30 @@ select * from t3 where k in (select j from v2); ...@@ -4251,3 +4251,30 @@ select * from t3 where k in (select j from v2);
drop table t1,t2,t3; drop table t1,t2,t3;
drop view v2; drop view v2;
--echo #
--echo # Bug#52068: Optimizer generates invalid semijoin materialization plan
--echo #
--disable_warnings
drop table if exists ot1, ot2, it1, it2;
--enable_warnings
CREATE TABLE ot1(a INTEGER);
INSERT INTO ot1 VALUES(5), (8);
CREATE TABLE it2(a INTEGER);
INSERT INTO it2 VALUES(9), (5), (1), (8);
CREATE TABLE it3(a INTEGER);
INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
CREATE TABLE ot4(a INTEGER);
INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
let $query=
SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
eval $query;
eval explain $query;
DROP TABLE IF EXISTS ot1, ot4, it2, it3;
...@@ -169,9 +169,17 @@ JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab) ...@@ -169,9 +169,17 @@ JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab)
if (join_tab->first_sjm_sibling) if (join_tab->first_sjm_sibling)
return tab; return tab;
uint i= tab-join->join_tab; uint i= tab-join->join_tab;
/*
Temporary measure before MWL#90 refactorings are there: if 'tab' is at upper
level (i.e. it's not inside an SJM nest), still include into the join buffer
the tables from within SJM nest. We might need the subquery's select list
columns, because SJ-Materialization-Scan upacks data to those.
while (sj_is_materialize_strategy(join->best_positions[i].sj_strategy) && while (sj_is_materialize_strategy(join->best_positions[i].sj_strategy) &&
i < join->tables) i < join->tables)
i+= join->best_positions[i].n_sj_tables; i+= join->best_positions[i].n_sj_tables;
*/
return join->join_tab+i < join_tab ? join->join_tab+i : NULL; return join->join_tab+i < join_tab ? join->join_tab+i : NULL;
} }
......
...@@ -13171,6 +13171,15 @@ sub_select_sjm(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) ...@@ -13171,6 +13171,15 @@ sub_select_sjm(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
last_tab->read_record.read_record= rr_sequential_and_unpack; last_tab->read_record.read_record= rr_sequential_and_unpack;
} }
} }
else
{
if (sjm->is_sj_scan)
{
/* Reset the cursor for a new scan over the table */
if (sjm->table->file->ha_rnd_init(TRUE))
DBUG_RETURN(NESTED_LOOP_ERROR);
}
}
if (sjm->is_sj_scan) if (sjm->is_sj_scan)
{ {
......
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