mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge MWL#90 with main 5.3 tree
This commit is contained in:
commit
8fb724281e
43 changed files with 4523 additions and 1960 deletions
|
@ -1543,7 +1543,7 @@ EXPLAIN SELECT 1 FROM t1 WHERE a IN
|
|||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index PRIMARY,i2 PRIMARY 4 NULL 144 Using index
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 144
|
||||
CREATE TABLE t2 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
|
|
|
@ -2255,7 +2255,8 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
|
||||
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 Using where
|
||||
1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 Using index
|
||||
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
|
||||
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
|
||||
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
|
||||
|
|
|
@ -55,7 +55,7 @@ id data data
|
|||
2 female no
|
||||
select t1.id from t1 union select t2.id from t2;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def id id 1 4 1 Y 32768 0 63
|
||||
def id id 1 4 1 Y 49152 0 63
|
||||
id
|
||||
1
|
||||
2
|
||||
|
@ -66,7 +66,7 @@ insert into t1 values (2,'two');
|
|||
set @arg00=1 ;
|
||||
select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def @arg00 @arg00 8 20 1 Y 32768 0 63
|
||||
def @arg00 @arg00 8 20 1 Y 49152 0 63
|
||||
@arg00
|
||||
1
|
||||
select * from (select @arg00) aaa;
|
||||
|
@ -76,7 +76,7 @@ def aaa @arg00 @arg00 8 20 1 Y 32768 0 63
|
|||
1
|
||||
select 1 union select 1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def 1 1 8 20 1 N 32769 0 63
|
||||
def 1 1 8 20 1 N 49153 0 63
|
||||
1
|
||||
1
|
||||
select * from (select 1 union select 1) aaa;
|
||||
|
|
|
@ -1361,7 +1361,7 @@ explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1
|
|||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
|
||||
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.61 Using index; FirstMatch(t2)
|
||||
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
|
||||
insert into t1 values (3,31);
|
||||
|
@ -2831,7 +2831,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cac
|
|||
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1 1.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
|
||||
|
@ -3420,6 +3420,7 @@ EXPLAIN
|
|||
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
||||
ALTER TABLE t1 ADD INDEX(a);
|
||||
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
|
||||
|
@ -3430,7 +3431,8 @@ AAA 8
|
|||
EXPLAIN
|
||||
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
|
||||
1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
||||
DROP TABLE t1;
|
||||
create table t1( f1 int,f2 int);
|
||||
|
@ -4320,16 +4322,18 @@ CREATE TABLE t1 (a INT);
|
|||
INSERT INTO t1 VALUES (1),(2);
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`))))))
|
||||
Note 1003 select 1 AS `1` from <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`1` = 1)
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`))))))
|
||||
Note 1003 select 1 AS `1` from <materialize> (select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`1` = 1)
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#45061: Incorrectly market field caused wrong result.
|
||||
|
@ -5013,7 +5017,7 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 24 Using where
|
||||
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)
|
||||
|
|
|
@ -1023,7 +1023,7 @@ update t22 set c = '2005-12-08 15:58:27' where a = 255;
|
|||
explain select t21.* from t21,t22 where t21.a = t22.a and
|
||||
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 Using temporary; Using filesort
|
||||
1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
|
||||
1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
|
||||
|
@ -1041,7 +1041,7 @@ select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) a
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY X ALL NULL NULL NULL NULL 2
|
||||
2 DEPENDENT SUBQUERY Y ALL NULL NULL NULL NULL 2 Using where
|
||||
2 DEPENDENT SUBQUERY subselect3 eq_ref unique_key unique_key 5 func 1
|
||||
2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 func 1
|
||||
3 SUBQUERY Z ALL NULL NULL NULL NULL 2
|
||||
select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
|
||||
subq
|
||||
|
@ -1112,7 +1112,7 @@ set @@optimizer_switch=@save_optimizer_switch;
|
|||
explain select * from (select a from t0) X where a in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
|
||||
1 PRIMARY subselect3 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 5 func 1
|
||||
3 SUBQUERY t1 ALL NULL NULL NULL NULL 20
|
||||
2 DERIVED t0 ALL NULL NULL NULL NULL 11
|
||||
drop table t0, t1;
|
||||
|
@ -1126,7 +1126,7 @@ insert into t3 select A.a + 10*B.a from t0 A, t0 B;
|
|||
explain select * from t3 where a in (select kp1 from t1 where kp1<20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 100
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using where; Using index
|
||||
create table t4 (pk int primary key);
|
||||
insert into t4 select a from t3;
|
||||
|
@ -1134,7 +1134,7 @@ explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
|
|||
and t4.pk=t1.c);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 100
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR
|
||||
2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index
|
||||
drop table t1, t3, t4;
|
||||
|
@ -1167,7 +1167,7 @@ create table t3 ( a int , filler char(100), key(a));
|
|||
insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
|
||||
explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
|
||||
1 PRIMARY t3 ref a a 5 test.t2.a 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
|
||||
select * from t3 where a in (select a from t2);
|
||||
|
@ -1216,22 +1216,25 @@ insert into t3 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t1 A, t1 B, t1 C
|
|||
explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref a a 5 test.t2.a 10
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.A.a 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
|
||||
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t2.a 1
|
||||
2 SUBQUERY A ALL NULL NULL NULL NULL 10
|
||||
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t2.a 1
|
||||
2 SUBQUERY A ALL NULL NULL NULL NULL 10
|
||||
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
explain select straight_join * from t2 X, t2 Y
|
||||
|
@ -1239,6 +1242,7 @@ where X.a in (select straight_join A.a from t1 A, t1 B);
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.X.a 1
|
||||
2 SUBQUERY A ALL NULL NULL NULL NULL 10
|
||||
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
create table t0 (a int, b int);
|
||||
|
@ -1246,14 +1250,14 @@ insert into t0 values(1,1);
|
|||
explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref a a 5 test.t2.a 10
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
create table t4 as select a as x, a as y from t1;
|
||||
explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where
|
||||
2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
|
||||
drop table t0,t1,t2,t3,t4;
|
||||
|
@ -1265,12 +1269,12 @@ create table t2 as select * from t1;
|
|||
explain select * from t2 where a in (select b from t1 where a=3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
|
||||
explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
|
||||
2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
|
||||
drop table t1,t2;
|
||||
create table t1 (a int, b int);
|
||||
|
@ -1281,14 +1285,14 @@ set @@optimizer_switch='firstmatch=off';
|
|||
explain select * from t1 where (a,b) in (select a,b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
|
||||
set @save_optimizer_search_depth=@@optimizer_search_depth;
|
||||
set @@optimizer_search_depth=63;
|
||||
explain select * from t1 where (a,b) in (select a,b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
|
||||
set @@optimizer_search_depth=@save_optimizer_search_depth;
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
|
@ -1300,7 +1304,7 @@ insert into t1 select * from t0;
|
|||
explain select * from t0 where a in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
|
||||
select * from t0 where a in (select a from t1);
|
||||
a
|
||||
|
@ -1314,7 +1318,7 @@ insert into t1 select * from t0;
|
|||
explain select * from t0 where a in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
|
||||
select * from t0 where a in (select a from t1);
|
||||
a
|
||||
|
@ -1329,7 +1333,7 @@ insert into t2 select * from t2;
|
|||
explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 15 func,func,func 1
|
||||
2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
|
||||
|
@ -1402,7 +1406,7 @@ INNER JOIN t2 c ON c.idContact=cona.idContact
|
|||
WHERE cona.postalStripped='T2H3B2'
|
||||
);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00
|
||||
1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00
|
||||
|
|
|
@ -1030,7 +1030,7 @@ update t22 set c = '2005-12-08 15:58:27' where a = 255;
|
|||
explain select t21.* from t21,t22 where t21.a = t22.a and
|
||||
t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 8 Using temporary; Using filesort
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 Using temporary; Using filesort
|
||||
1 PRIMARY t21 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (flat, BNLH join)
|
||||
1 PRIMARY t22 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (incremental, BNLH join)
|
||||
2 SUBQUERY t11 ALL NULL NULL NULL NULL 8 Using where
|
||||
|
@ -1048,7 +1048,7 @@ select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) a
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY X ALL NULL NULL NULL NULL 2
|
||||
2 DEPENDENT SUBQUERY Y ALL NULL NULL NULL NULL 2 Using where
|
||||
2 DEPENDENT SUBQUERY subselect3 eq_ref unique_key unique_key 5 func 1
|
||||
2 DEPENDENT SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 func 1
|
||||
3 SUBQUERY Z ALL NULL NULL NULL NULL 2
|
||||
select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
|
||||
subq
|
||||
|
@ -1119,7 +1119,7 @@ set @@optimizer_switch=@save_optimizer_switch;
|
|||
explain select * from (select a from t0) X where a in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
|
||||
1 PRIMARY subselect3 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 5 func 1
|
||||
3 SUBQUERY t1 ALL NULL NULL NULL NULL 20
|
||||
2 DERIVED t0 ALL NULL NULL NULL NULL 11
|
||||
drop table t0, t1;
|
||||
|
@ -1133,7 +1133,7 @@ insert into t3 select A.a + 10*B.a from t0 A, t0 B;
|
|||
explain select * from t3 where a in (select kp1 from t1 where kp1<20);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 100
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using where; Using index
|
||||
create table t4 (pk int primary key);
|
||||
insert into t4 select a from t3;
|
||||
|
@ -1141,7 +1141,7 @@ explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
|
|||
and t4.pk=t1.c);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 100
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Using MRR
|
||||
2 SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index
|
||||
drop table t1, t3, t4;
|
||||
|
@ -1174,7 +1174,7 @@ create table t3 ( a int , filler char(100), key(a));
|
|||
insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
|
||||
explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
|
||||
1 PRIMARY t3 ref a a 5 test.t2.a 1 Using join buffer (flat, BKA join)
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
|
||||
select * from t3 where a in (select a from t2);
|
||||
|
@ -1223,22 +1223,25 @@ insert into t3 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t1 A, t1 B, t1 C
|
|||
explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer (flat, BKA join)
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY A ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.A.a 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
|
||||
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t2.a 1
|
||||
2 SUBQUERY A ALL NULL NULL NULL NULL 10
|
||||
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t2.a 1
|
||||
2 SUBQUERY A ALL NULL NULL NULL NULL 10
|
||||
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
explain select straight_join * from t2 X, t2 Y
|
||||
|
@ -1246,6 +1249,7 @@ where X.a in (select straight_join A.a from t1 A, t1 B);
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY X ALL NULL NULL NULL NULL 10 Using where
|
||||
1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.X.a 1
|
||||
2 SUBQUERY A ALL NULL NULL NULL NULL 10
|
||||
2 SUBQUERY B ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
create table t0 (a int, b int);
|
||||
|
@ -1253,14 +1257,14 @@ insert into t0 values(1,1);
|
|||
explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref a a 5 test.t2.a 10 Using join buffer (flat, BKA join)
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 10 Using where
|
||||
create table t4 as select a as x, a as y from t1;
|
||||
explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 system NULL NULL NULL NULL 1
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref a a 5 test.t4.x 10 Using where; Using join buffer (flat, BKA join)
|
||||
2 SUBQUERY t4 ALL NULL NULL NULL NULL 10 Using where
|
||||
drop table t0,t1,t2,t3,t4;
|
||||
|
@ -1272,12 +1276,12 @@ create table t2 as select * from t1;
|
|||
explain select * from t2 where a in (select b from t1 where a=3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
|
||||
explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
|
||||
2 SUBQUERY t1 ref a a 10 const,test.t2.a 8 Using index
|
||||
drop table t1,t2;
|
||||
create table t1 (a int, b int);
|
||||
|
@ -1288,14 +1292,14 @@ set @@optimizer_switch='firstmatch=off';
|
|||
explain select * from t1 where (a,b) in (select a,b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
|
||||
set @save_optimizer_search_depth=@@optimizer_search_depth;
|
||||
set @@optimizer_search_depth=63;
|
||||
explain select * from t1 where (a,b) in (select a,b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 10
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 100
|
||||
set @@optimizer_search_depth=@save_optimizer_search_depth;
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
|
@ -1307,7 +1311,7 @@ insert into t1 select * from t0;
|
|||
explain select * from t0 where a in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
|
||||
select * from t0 where a in (select a from t1);
|
||||
a
|
||||
|
@ -1321,7 +1325,7 @@ insert into t1 select * from t0;
|
|||
explain select * from t0 where a in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 4 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4
|
||||
select * from t0 where a in (select a from t1);
|
||||
a
|
||||
|
@ -1336,7 +1340,7 @@ insert into t2 select * from t2;
|
|||
explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 15 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 15 func,func,func 1
|
||||
2 SUBQUERY X ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY Y ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY Z ALL NULL NULL NULL NULL 6 Using join buffer (incremental, BNL join)
|
||||
|
@ -1409,7 +1413,7 @@ INNER JOIN t2 c ON c.idContact=cona.idContact
|
|||
WHERE cona.postalStripped='T2H3B2'
|
||||
);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2 1.00
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2 100.00
|
||||
1 PRIMARY a index PRIMARY PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY cona ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
2 SUBQUERY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using join buffer (flat, BKA join)
|
||||
|
|
|
@ -356,7 +356,7 @@ FROM t2
|
|||
WHERE PTYPE = 'Design'));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
|
||||
|
@ -371,13 +371,13 @@ WHERE EMPNUM IN
|
|||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 SIMPLE <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
@ -394,7 +394,7 @@ FROM t2
|
|||
WHERE PTYPE = 'Design'));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
|
||||
|
@ -409,13 +409,13 @@ WHERE EMPNUM IN
|
|||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 SIMPLE <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
@ -431,7 +431,7 @@ FROM t2
|
|||
WHERE PTYPE = 'Design'));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
|
||||
|
@ -446,13 +446,13 @@ WHERE EMPNUM IN
|
|||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||
1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 SIMPLE <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
@ -579,7 +579,7 @@ FROM t2
|
|||
WHERE PTYPE = 'Design'));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
|
||||
|
@ -594,13 +594,13 @@ WHERE EMPNUM IN
|
|||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 SIMPLE <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
@ -617,7 +617,7 @@ FROM t2
|
|||
WHERE PTYPE = 'Design'));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
|
||||
|
@ -632,13 +632,13 @@ WHERE EMPNUM IN
|
|||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL t1_IDX NULL NULL NULL 5
|
||||
1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 SIMPLE <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
@ -654,7 +654,7 @@ FROM t2
|
|||
WHERE PTYPE = 'Design'));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
|
||||
|
@ -669,13 +669,13 @@ WHERE EMPNUM IN
|
|||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
EXECUTE stmt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
|
||||
1 SIMPLE subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 SIMPLE <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
@ -735,6 +735,7 @@ WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 ));
|
|||
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 t1 ALL NULL NULL NULL NULL 2 Using where
|
||||
2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 test.t1.f10 1
|
||||
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||
SELECT * FROM t1
|
||||
WHERE f3 = (
|
||||
|
@ -749,6 +750,7 @@ WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 ));
|
|||
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 t1 ALL NULL NULL NULL NULL 2 Using where
|
||||
2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 10 test.t1.f10,test.t1.f10 1
|
||||
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||
SELECT * FROM t1
|
||||
WHERE f3 = (
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
set @@optimizer_switch='semijoin=off';
|
||||
set optimizer_switch='firstmatch=off';
|
||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
||||
drop view if exists v1, v2, v1m, v2m;
|
||||
create table t1 (a1 char(8), a2 char(8));
|
||||
|
@ -30,7 +32,6 @@ create index it3i3 on t3i (c1, c2);
|
|||
insert into t1i select * from t1;
|
||||
insert into t2i select * from t2;
|
||||
insert into t3i select * from t3;
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
/******************************************************************************
|
||||
* Simple tests.
|
||||
******************************************************************************/
|
||||
|
@ -41,7 +42,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`))))))
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -52,7 +53,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`))))))
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -63,7 +64,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -74,7 +75,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`min(b2)`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -82,10 +83,10 @@ a1 a2
|
|||
explain extended
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i index it2i1,it2i3 it2i1 9 NULL 5 100.00 Using where; Using index
|
||||
1 PRIMARY t1i index NULL _it1_idx # NULL 3 100.00 Using where;
|
||||
2 SUBQUERY t2i index it2i1,it2i3 it2i1 # NULL 5 100.00 Using where;
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`))))))
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -93,10 +94,10 @@ a1 a2
|
|||
explain extended
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i range it2i1,it2i3 it2i1 9 NULL 3 100.00 Using where; Using index for group-by
|
||||
1 PRIMARY t1i index NULL # 18 # 3 100.00 #
|
||||
2 SUBQUERY t2i range it2i1,it2i3 # 9 # 3 100.00 #
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`))))))
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -104,10 +105,10 @@ a1 a2
|
|||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
1 PRIMARY t1i index NULL _it1_idx # NULL 3 100.00 Using where;
|
||||
2 SUBQUERY t2i index it2i1,it2i3 it2i3 # NULL 5 100.00 Using where;
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -115,10 +116,10 @@ a1 a2
|
|||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
|
||||
1 PRIMARY t1i index NULL # # # 3 100.00 #
|
||||
2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -126,10 +127,10 @@ a1 a2
|
|||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
|
||||
1 PRIMARY t1i index NULL # # # 3 100.00 #
|
||||
2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`min(b2)`))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`min(b2)`))))))
|
||||
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -140,7 +141,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`max(b2)`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`max(b2)`))))))
|
||||
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -169,13 +170,14 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`min(b2)`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
1 - 02 2 - 02
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
|
||||
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
prepare st1 from
|
||||
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
|
||||
|
@ -202,14 +204,14 @@ execute st1;
|
|||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
1 - 02 2 - 02
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -220,7 +222,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i index NULL it2i3 18 NULL 5 100.00 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
|
@ -275,7 +277,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`)))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1`.`a2` = `<subquery3>`.`c2`)))))))
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
|
@ -289,12 +291,12 @@ where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
|||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
3 SUBQUERY t3i index NULL it3i3 18 NULL 4 100.00 Using where; Using index
|
||||
4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
2 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
1 PRIMARY t1i index NULL # # # 3 100.00 #
|
||||
3 SUBQUERY t3i index NULL # # # 4 100.00 #
|
||||
4 SUBQUERY t2i index it2i2 # # # 5 100.00 #
|
||||
2 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3i`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`c2`)))))))
|
||||
Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery3>`.`c2`)))))))
|
||||
select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
|
@ -317,7 +319,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`)))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
|
@ -342,7 +344,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3c`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`)))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3c`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
|
@ -366,19 +368,19 @@ where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
|||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary; Using filesort
|
||||
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
7 UNION t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
|
||||
9 SUBQUERY t3i index NULL it3i3 18 NULL 4 100.00 Using where; Using index
|
||||
10 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
8 SUBQUERY t2i index it2i1,it2i3 it2i3 18 NULL 5 100.00 Using where; Using index
|
||||
NULL UNION RESULT <union1,7> ALL NULL NULL NULL NULL NULL NULL
|
||||
1 PRIMARY t1 ALL NULL # # # 3 100.00 #
|
||||
5 SUBQUERY t3 ALL NULL # # # 4 100.00 #
|
||||
6 SUBQUERY t2i index it2i2 # # # 5 100.00 #
|
||||
2 SUBQUERY t2 ALL NULL # # # 5 100.00 #
|
||||
4 SUBQUERY t3 ALL NULL # # # 4 100.00 #
|
||||
3 SUBQUERY t3 ALL NULL # # # 4 100.00 #
|
||||
7 UNION t1i index NULL # # # 3 100.00 #
|
||||
9 SUBQUERY t3i index NULL # # # 4 100.00 #
|
||||
10 SUBQUERY t2i index it2i2 # # # 5 100.00 #
|
||||
8 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
|
||||
NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
|
||||
Warnings:
|
||||
Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3i`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1i`.`a2` = `materialized subselect`.`c2`))))))))
|
||||
Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery8>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery8>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery10>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery10>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery9>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery9>`.`c2`))))))))
|
||||
(select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
|
@ -407,7 +409,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `materialized subselect`.`c1`) and (`test`.`t1`.`a2` = `materialized subselect`.`c2`)))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery4>`.`c1`) and (`test`.`t1`.`a2` = `<subquery4>`.`c2`)))))))
|
||||
select * from t1
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
|
@ -430,7 +432,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
|
||||
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`b1`) and (`test`.`t3`.`c2` = `materialized subselect`.`b2`)))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `materialized subselect`.`c1`) and (`test`.`t3`.`c2` = `materialized subselect`.`c2`)))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`c1`) and (`test`.`t3`.`c2` = `<subquery4>`.`c2`)))))))
|
||||
select * from t1, t3
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(c1, c2) in (select c1, c2 from t3
|
||||
|
@ -476,7 +478,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
Warnings:
|
||||
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
|
||||
Note 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `materialized subselect`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select 1 from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`))))))
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
|
@ -549,7 +551,6 @@ a1 a2
|
|||
Test that BLOBs are not materialized (except when arguments of some functions).
|
||||
*/
|
||||
# force materialization to be always considered
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
set @prefix_len = 6;
|
||||
set @blob_len = 16;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
@ -611,7 +612,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `materialized subselect`.`substring(b1,1,16)`))))))
|
||||
Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `<subquery2>`.`substring(b1,1,16)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
|
||||
|
@ -640,7 +641,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` where <expr_cache><`test`.`t1_16`.`a1`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
@ -662,7 +663,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 from `test`.`t1_16` where (<expr_cache><`test`.`t1_16`.`a2`,`test`.`t1_16`.`a1`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `materialized subselect`.`c1`)))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`))))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8))))))
|
||||
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select 1 from `test`.`t1_16` where (<expr_cache><`test`.`t1_16`.`a2`,`test`.`t1_16`.`a1`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `<subquery4>`.`c1`)))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`))))) and (<cache>(concat(`test`.`t1`.`a1`,'x')) = left(`test`.`t1_16`.`a1`,8))))))
|
||||
drop table t1_16, t2_16, t3_16;
|
||||
set @blob_len = 512;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
@ -724,7 +725,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `materialized subselect`.`substring(b1,1,512)`))))))
|
||||
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`substring(b1,1,512)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
|
||||
|
@ -738,7 +739,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
@ -751,7 +752,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` where <expr_cache><`test`.`t1_512`.`a1`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
@ -831,7 +832,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
@ -844,7 +845,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` where <expr_cache><`test`.`t1_1024`.`a1`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
@ -924,7 +925,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
@ -937,7 +938,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
|
||||
Warnings:
|
||||
Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `materialized subselect`.`group_concat(b1)`))))))
|
||||
Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` where <expr_cache><`test`.`t1_1025`.`a1`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
@ -951,7 +952,6 @@ insert into t1bit values (b'010', b'110');
|
|||
insert into t2bit values (b'001', b'101');
|
||||
insert into t2bit values (b'010', b'110');
|
||||
insert into t2bit values (b'110', b'111');
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
explain extended select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
@ -959,7 +959,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 100.00
|
||||
Warnings:
|
||||
Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <expr_cache><`test`.`t1bit`.`a2`,`test`.`t1bit`.`a1`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `materialized subselect`.`b1`) and (`test`.`t1bit`.`a2` = `materialized subselect`.`b2`))))))
|
||||
Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <expr_cache><`test`.`t1bit`.`a2`,`test`.`t1bit`.`a1`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1bit`.`a2` = `<subquery2>`.`b2`))))))
|
||||
select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
@ -994,7 +994,7 @@ drop table t1, t2, t3, t1i, t2i, t3i, columns;
|
|||
/******************************************************************************
|
||||
* Test the cache of the left operand of IN.
|
||||
******************************************************************************/
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
# Test that default values of Cached_item are not used for comparison
|
||||
create table t1 (s1 int);
|
||||
create table t2 (s2 int);
|
||||
insert into t1 values (5),(1),(0);
|
||||
|
@ -1030,7 +1030,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`))))))
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
a
|
||||
2
|
||||
|
@ -1044,7 +1044,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`))))))
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
a
|
||||
2
|
||||
|
@ -1058,7 +1058,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`))))))
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
a
|
||||
2
|
||||
|
@ -1071,7 +1071,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`))))))
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
a
|
||||
2
|
||||
|
@ -1083,7 +1083,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `materialized subselect`.`c`))))))
|
||||
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
a
|
||||
2
|
||||
|
@ -1142,6 +1142,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
|
||||
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
min(a1)
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -1157,17 +1158,25 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
min(a1)
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
# with MariaDB and MWL#90, this particular case is solved:
|
||||
explain select min(a1) from t1 where 7 in (select b1 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
|
||||
select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
min(a1)
|
||||
NULL
|
||||
# but when we go around MWL#90 code, the problem still shows up:
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
|
||||
min(a1)
|
||||
set @@optimizer_switch= @save_optimizer_switch;
|
||||
drop table t1,t2;
|
||||
create table t1 (a char(2), b varchar(10));
|
||||
insert into t1 values ('a', 'aaa');
|
||||
insert into t1 values ('aa', 'aaaa');
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
explain select a,b from t1 where b in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
||||
|
@ -1187,15 +1196,17 @@ INSERT INTO t1 (f1, f2) VALUES (10, 1.668);
|
|||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t2 VALUES (1, 1.789);
|
||||
INSERT INTO t2 VALUES (13, 1.454);
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
||||
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 2
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
|
||||
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
|
||||
COUNT(*)
|
||||
2
|
||||
set @@optimizer_switch= @save_optimizer_switch;
|
||||
DROP TABLE t1, t2;
|
||||
CREATE TABLE t1 (
|
||||
pk int,
|
||||
|
@ -1208,11 +1219,12 @@ PRIMARY KEY (pk)
|
|||
INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
||||
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR
|
||||
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
pk
|
||||
|
@ -1221,6 +1233,7 @@ SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
|
|||
pk
|
||||
2
|
||||
DROP TABLE t1, t2;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
#
|
||||
# BUG#50019: Wrong result for IN-subquery with materialization
|
||||
#
|
||||
|
@ -1272,6 +1285,34 @@ a a in (select a from t1)
|
|||
1 0
|
||||
2 0
|
||||
drop table t0, t1;
|
||||
set optimizer_switch='firstmatch=on';
|
||||
set @@optimizer_switch=default;
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2);
|
||||
create table t1 (a int);
|
||||
insert into t1 values (0),(1),(2);
|
||||
explain select a, a in (select a from t1) from t0;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 3
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
|
||||
select a, a in (select a from t1) from t0;
|
||||
a a in (select a from t1)
|
||||
0 1
|
||||
1 1
|
||||
2 1
|
||||
prepare s from 'select a, a in (select a from t1) from t0';
|
||||
execute s;
|
||||
a a in (select a from t1)
|
||||
0 1
|
||||
1 1
|
||||
2 1
|
||||
update t1 set a=123;
|
||||
execute s;
|
||||
a a in (select a from t1)
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
drop table t0, t1;
|
||||
#
|
||||
# LPBUG#609121: RQG: wrong result on aggregate + NOT IN + HAVING and
|
||||
# partial_match_table_scan=on
|
||||
|
@ -1362,7 +1403,7 @@ SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
|||
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using MRR
|
||||
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
pk
|
||||
|
@ -1372,6 +1413,29 @@ pk
|
|||
2
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# BUG#724228: Wrong result with materialization=on and three aggregates in maria-5.3-mwl90
|
||||
#
|
||||
CREATE TABLE t1 ( f2 int(11)) ;
|
||||
INSERT IGNORE INTO t1 VALUES ('7'),('9'),('7'),('4'),('2'),('6'),('8'),('5'),('6'),('188'),('2'),('1'),('1'),('0'),('9'),('4');
|
||||
CREATE TABLE t2 ( f1 int(11), f2 int(11)) ENGINE=MyISAM;
|
||||
INSERT IGNORE INTO t2 VALUES ('1','1');
|
||||
CREATE TABLE t3 ( f1 int(11), f2 int(11), f3 int(11), PRIMARY KEY (f1)) ;
|
||||
INSERT IGNORE INTO t3 VALUES ('16','6','1'),('18','3','4'),('19',NULL,'9'),('20','0','6'),('41','2','0'),('42','2','5'),('43','9','6'),('44','7','4'),('45','1','4'),('46','222','238'),('47','3','6'),('48','6','6'),('49',NULL,'1'),('50','5','1');
|
||||
SET @_save_join_cache_level = @@join_cache_level;
|
||||
SET @_save_optimizer_switch = @@optimizer_switch;
|
||||
SET join_cache_level = 1;
|
||||
SET optimizer_switch='materialization=on';
|
||||
SELECT f1 FROM t3
|
||||
WHERE
|
||||
f1 NOT IN (SELECT MAX(f2) FROM t1) AND
|
||||
f3 IN (SELECT MIN(f1) FROM t2) AND
|
||||
f1 IN (SELECT COUNT(f2) FROM t1);
|
||||
f1
|
||||
16
|
||||
SET @@join_cache_level = @_save_join_cache_level;
|
||||
SET @@optimizer_switch = @_save_optimizer_switch;
|
||||
drop table t1, t2, t3;
|
||||
#
|
||||
# LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value'
|
||||
# failed with subquery on both sides of NOT IN and materialization
|
||||
#
|
||||
|
|
|
@ -1365,7 +1365,7 @@ explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1
|
|||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
|
||||
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
|
||||
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.61 Using index; FirstMatch(t2)
|
||||
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
|
||||
insert into t1 values (3,31);
|
||||
|
|
|
@ -1300,7 +1300,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
|
||||
2 SUBQUERY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||
a
|
||||
2
|
||||
|
@ -1310,7 +1310,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
||||
a
|
||||
2
|
||||
|
@ -1321,7 +1321,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
drop table t1, t2, t3;
|
||||
create table t1 (a int, b int, index a (a,b));
|
||||
create table t2 (a int, index a (a));
|
||||
|
@ -1343,7 +1343,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
|
||||
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||
a
|
||||
2
|
||||
|
@ -1353,7 +1353,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
|
||||
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
||||
a
|
||||
2
|
||||
|
@ -1364,7 +1364,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
2 SUBQUERY t3 index a a 5 NULL 3 100.00 Using index
|
||||
2 SUBQUERY t1 index NULL a 10 NULL 10004 100.00 Using where; Using index; Using join buffer (flat, BNL join)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where (`test`.`t1`.`b` = `test`.`t3`.`a`) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
insert into t1 values (3,31);
|
||||
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||
a
|
||||
|
@ -1380,7 +1380,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
|
||||
2 SUBQUERY t1 index NULL a 10 NULL 10005 100.00 Using where; Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `materialized subselect`.`a`))))))
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`b` <> 30) ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where ((`test`.`t2`.`a` = `<subquery2>`.`a`))))))
|
||||
drop table t0, t1, t2, t3;
|
||||
create table t1 (a int, b int);
|
||||
create table t2 (a int, b int);
|
||||
|
@ -2834,7 +2834,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),(`test`.`t1`.`one`,`test`.`t1`.`two`) in ( <materialize> (select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N') ), <primary_index_lookup>(`test`.`t1`.`one` in <temporary table> on distinct_key where ((`test`.`t1`.`one` = `materialized subselect`.`one`) and (`test`.`t1`.`two` = `materialized subselect`.`two`))))))
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),(`test`.`t1`.`one`,`test`.`t1`.`two`) in ( <materialize> (select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = 'N') ), <primary_index_lookup>(`test`.`t1`.`one` in <temporary table> on distinct_key where ((`test`.`t1`.`one` = `<subquery2>`.`one`) and (`test`.`t1`.`two` = `<subquery2>`.`two`))))))
|
||||
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
|
||||
|
@ -4323,13 +4323,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
|
|||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`))))))
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery2>`.`1`))))))
|
||||
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `materialized subselect`.`1`))))))
|
||||
Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,1 in ( <materialize> (select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery2>`.`1`))))))
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#45061: Incorrectly market field caused wrong result.
|
||||
|
|
|
@ -811,7 +811,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f
|
|||
EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 13 func 1 1.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func,func 1 100.00
|
||||
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using MRR
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
|
||||
|
@ -980,7 +980,7 @@ FROM t1
|
|||
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 8 func 1 1.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
|
||||
2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_key` < 'n') xor `test`.`t1`.`pk`))
|
||||
|
@ -1062,8 +1062,8 @@ AND t1.val IN (SELECT t3.val FROM t3
|
|||
WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY subselect3 eq_ref unique_key unique_key 14 func 1
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 14 func 1
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 14 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 14 func 1
|
||||
3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
SELECT *
|
||||
|
|
|
@ -32,7 +32,7 @@ a b
|
|||
9 5
|
||||
explain select * from t2 where b in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 3
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
|
||||
1 PRIMARY t2 ref b b 5 test.t1.a 2
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
select * from t2 where b in (select a from t1);
|
||||
|
@ -52,7 +52,7 @@ insert into t3 select a,a, a,a,a from t0;
|
|||
explain select * from t3 where b in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL b NULL NULL NULL 10
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
|
||||
select * from t3 where b in (select a from t1);
|
||||
a b pk1 pk2 pk3
|
||||
|
@ -75,7 +75,7 @@ A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
|
|||
from t0 A, t0 B where B.a <5;
|
||||
explain select * from t3 where b in (select a from t0);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref b b 5 test.t0.a 1
|
||||
2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
|
||||
set @save_ecp= @@engine_condition_pushdown;
|
||||
|
@ -102,7 +102,7 @@ set max_heap_table_size= @save_max_heap_table_size;
|
|||
explain select * from t1 where a in (select b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t2 index b b 5 NULL 10 Using index
|
||||
select * from t1;
|
||||
a b
|
||||
|
@ -130,7 +130,7 @@ explain select
|
|||
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
|
||||
from t1 ot where a in (select a from t2 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 22
|
||||
1 PRIMARY ot ALL NULL NULL NULL NULL 32 Using where; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 22
|
||||
select
|
||||
|
@ -164,7 +164,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
|||
from t2 ot where a in (select a from t1 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY ot ALL NULL NULL NULL NULL 22
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 32
|
||||
select
|
||||
a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
||||
|
@ -198,7 +198,7 @@ explain select
|
|||
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
|
||||
from t1 ot where a in (select a from t2 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 22
|
||||
1 PRIMARY ot ALL NULL NULL NULL NULL 52 Using where; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 22
|
||||
select
|
||||
|
@ -232,7 +232,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
|||
from t2 ot where a in (select a from t1 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY ot ALL NULL NULL NULL NULL 22
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 52
|
||||
select
|
||||
a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
||||
|
@ -349,7 +349,7 @@ WHERE t1.Code IN (
|
|||
SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
|
||||
SELECT Name FROM t1
|
||||
WHERE t1.Code IN (
|
||||
|
@ -360,6 +360,10 @@ Canada
|
|||
China
|
||||
Czech Republic
|
||||
drop table t1, t2;
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
drop procedure if exists p4;
|
||||
CREATE TABLE t1(a INT);
|
||||
CREATE TABLE t2(c INT);
|
||||
CREATE PROCEDURE p1(v1 int)
|
||||
|
@ -693,7 +697,7 @@ The following must use loose index scan over t3, key a:
|
|||
explain select count(a) from t2 where a in ( SELECT a FROM t3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 index a a 5 NULL 1000 Using index
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t3 index a a 5 NULL 30000 Using index
|
||||
select count(a) from t2 where a in ( SELECT a FROM t3);
|
||||
count(a)
|
||||
|
|
|
@ -39,7 +39,7 @@ a b
|
|||
9 5
|
||||
explain select * from t2 where b in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 3
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
|
||||
1 PRIMARY t2 ref b b 5 test.t1.a 2 Using join buffer (flat, BKA join)
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
select * from t2 where b in (select a from t1);
|
||||
|
@ -59,7 +59,7 @@ insert into t3 select a,a, a,a,a from t0;
|
|||
explain select * from t3 where b in (select a from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL b NULL NULL NULL 10
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
|
||||
select * from t3 where b in (select a from t1);
|
||||
a b pk1 pk2 pk3
|
||||
|
@ -82,7 +82,7 @@ A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
|
|||
from t0 A, t0 B where B.a <5;
|
||||
explain select * from t3 where b in (select a from t0);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 10
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 10
|
||||
1 PRIMARY t3 ref b b 5 test.t0.a 1 Using join buffer (flat, BKA join)
|
||||
2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
|
||||
set @save_ecp= @@engine_condition_pushdown;
|
||||
|
@ -109,7 +109,7 @@ set max_heap_table_size= @save_max_heap_table_size;
|
|||
explain select * from t1 where a in (select b from t2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t2 index b b 5 NULL 10 Using index
|
||||
select * from t1;
|
||||
a b
|
||||
|
@ -137,7 +137,7 @@ explain select
|
|||
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
|
||||
from t1 ot where a in (select a from t2 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 22
|
||||
1 PRIMARY ot hash_ALL NULL #hash#$hj 5 test.it.a 32 Using where; Using join buffer (flat, BNLH join)
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 22 Using where
|
||||
select
|
||||
|
@ -171,7 +171,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
|||
from t2 ot where a in (select a from t1 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY ot ALL NULL NULL NULL NULL 22
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 32
|
||||
select
|
||||
a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
||||
|
@ -205,7 +205,7 @@ explain select
|
|||
a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
|
||||
from t1 ot where a in (select a from t2 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY subselect2 ALL unique_key NULL NULL NULL 22
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 22
|
||||
1 PRIMARY ot hash_ALL NULL #hash#$hj 5 test.it.a 52 Using where; Using join buffer (flat, BNLH join)
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 22 Using where
|
||||
select
|
||||
|
@ -239,7 +239,7 @@ a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
|||
from t2 ot where a in (select a from t1 it);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY ot ALL NULL NULL NULL NULL 22
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY it ALL NULL NULL NULL NULL 52
|
||||
select
|
||||
a, mid(filler1, 1,10), length(filler1)=length(filler2)
|
||||
|
@ -356,7 +356,7 @@ WHERE t1.Code IN (
|
|||
SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 31
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 3 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
|
||||
2 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
|
||||
SELECT Name FROM t1
|
||||
WHERE t1.Code IN (
|
||||
|
@ -367,6 +367,10 @@ Canada
|
|||
China
|
||||
Czech Republic
|
||||
drop table t1, t2;
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
drop procedure if exists p4;
|
||||
CREATE TABLE t1(a INT);
|
||||
CREATE TABLE t2(c INT);
|
||||
CREATE PROCEDURE p1(v1 int)
|
||||
|
@ -702,7 +706,7 @@ The following must use loose index scan over t3, key a:
|
|||
explain select count(a) from t2 where a in ( SELECT a FROM t3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 index a a 5 NULL 1000 Using index
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 5 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
|
||||
2 SUBQUERY t3 index a a 5 NULL 30000 Using index
|
||||
select count(a) from t2 where a in ( SELECT a FROM t3);
|
||||
count(a)
|
||||
|
|
|
@ -819,7 +819,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f
|
|||
EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 13 func 1 1.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func,func 1 100.00
|
||||
2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using MRR
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
|
||||
|
@ -988,7 +988,7 @@ FROM t1
|
|||
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 8 func 1 1.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
|
||||
2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_nokey` = `test`.`t1`.`varchar_key`) and ((`test`.`t1`.`varchar_key` < 'n') xor `test`.`t1`.`pk`))
|
||||
|
@ -1070,8 +1070,8 @@ AND t1.val IN (SELECT t3.val FROM t3
|
|||
WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
|
||||
1 PRIMARY subselect3 eq_ref unique_key unique_key 14 func 1
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 14 func 1
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 14 func 1
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 14 func 1
|
||||
3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
|
||||
SELECT *
|
||||
|
|
1326
mysql-test/r/subselect_sj_mat.result
Normal file
1326
mysql-test/r/subselect_sj_mat.result
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2256,7 +2256,8 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
|
||||
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1_outer index NULL a 10 NULL 15 Using where; Using index
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 15 Using where
|
||||
1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 1 Using index
|
||||
2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
|
||||
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
|
||||
a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
|
||||
|
|
|
@ -55,7 +55,7 @@ id data data
|
|||
2 female no
|
||||
select t1.id from t1 union select t2.id from t2;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def id id 1 4 1 Y 32768 0 63
|
||||
def id id 1 4 1 Y 49152 0 63
|
||||
id
|
||||
1
|
||||
2
|
||||
|
@ -66,7 +66,7 @@ insert into t1 values (2,'two');
|
|||
set @arg00=1 ;
|
||||
select @arg00 FROM t1 where a=1 union distinct select 1 FROM t1 where a=1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def @arg00 @arg00 8 20 1 Y 32768 0 63
|
||||
def @arg00 @arg00 8 20 1 Y 49152 0 63
|
||||
@arg00
|
||||
1
|
||||
select * from (select @arg00) aaa;
|
||||
|
@ -76,7 +76,7 @@ def aaa @arg00 @arg00 8 20 1 Y 32768 0 63
|
|||
1
|
||||
select 1 union select 1;
|
||||
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
|
||||
def 1 1 8 20 1 N 32769 0 63
|
||||
def 1 1 8 20 1 N 49153 0 63
|
||||
1
|
||||
1
|
||||
select * from (select 1 union select 1) aaa;
|
||||
|
|
|
@ -2829,7 +2829,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cac
|
|||
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
|
||||
1 PRIMARY subselect2 eq_ref unique_key unique_key 10 func 1 1.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
|
||||
|
@ -3422,17 +3422,19 @@ EXPLAIN
|
|||
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
||||
ALTER TABLE t1 ADD INDEX(a);
|
||||
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
|
||||
a b
|
||||
AAA 8
|
||||
BBB 4
|
||||
CCC 7
|
||||
AAA 8
|
||||
EXPLAIN
|
||||
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 9 Using where
|
||||
1 PRIMARY t1 ref a a 8 <subquery2>.a 1 Using where
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
||||
DROP TABLE t1;
|
||||
create table t1( f1 int,f2 int);
|
||||
|
|
|
@ -69,10 +69,14 @@ create table t1 (a int not null,
|
|||
insert into t1 (a) values (1), (2), (3), (4);
|
||||
create view v1 as select b+1 from t1 order by 1 desc limit 2;
|
||||
select * from v1;
|
||||
--echo MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
||||
--echo MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||
explain select * from v1;
|
||||
drop view v1;
|
||||
create view v1 as select c+1 from t1 order by 1 desc limit 2;
|
||||
select * from v1;
|
||||
--echo MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
||||
--echo MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||
explain select * from v1;
|
||||
drop view v1;
|
||||
drop table t1;
|
||||
|
|
|
@ -103,6 +103,8 @@ select * from v1;
|
|||
b+1
|
||||
0
|
||||
-1
|
||||
MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||
explain select * from v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||
|
@ -113,6 +115,8 @@ select * from v1;
|
|||
c+1
|
||||
0
|
||||
-1
|
||||
MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||
explain select * from v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||
|
|
|
@ -103,6 +103,8 @@ select * from v1;
|
|||
b+1
|
||||
0
|
||||
-1
|
||||
MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||
explain select * from v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||
|
@ -113,6 +115,8 @@ select * from v1;
|
|||
c+1
|
||||
0
|
||||
-1
|
||||
MariaDB-5.3: the following EXPLAIN produces incorrect #rows for table t1.
|
||||
MariaDB-5.3: this is expected to go away when FROM subquery optimizations are pushed
|
||||
explain select * from v1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
|
||||
|
|
|
@ -3,908 +3,13 @@
|
|||
# (WL#1110: Subquery optimization: materialization)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
||||
drop view if exists v1, v2, v1m, v2m;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (a1 char(8), a2 char(8));
|
||||
create table t2 (b1 char(8), b2 char(8));
|
||||
create table t3 (c1 char(8), c2 char(8));
|
||||
|
||||
insert into t1 values ('1 - 00', '2 - 00');
|
||||
insert into t1 values ('1 - 01', '2 - 01');
|
||||
insert into t1 values ('1 - 02', '2 - 02');
|
||||
|
||||
insert into t2 values ('1 - 01', '2 - 01');
|
||||
insert into t2 values ('1 - 01', '2 - 01');
|
||||
insert into t2 values ('1 - 02', '2 - 02');
|
||||
insert into t2 values ('1 - 02', '2 - 02');
|
||||
insert into t2 values ('1 - 03', '2 - 03');
|
||||
|
||||
insert into t3 values ('1 - 01', '2 - 01');
|
||||
insert into t3 values ('1 - 02', '2 - 02');
|
||||
insert into t3 values ('1 - 03', '2 - 03');
|
||||
insert into t3 values ('1 - 04', '2 - 04');
|
||||
|
||||
# Indexed columns
|
||||
create table t1i (a1 char(8), a2 char(8));
|
||||
create table t2i (b1 char(8), b2 char(8));
|
||||
create table t3i (c1 char(8), c2 char(8));
|
||||
create index it1i1 on t1i (a1);
|
||||
create index it1i2 on t1i (a2);
|
||||
create index it1i3 on t1i (a1, a2);
|
||||
|
||||
create index it2i1 on t2i (b1);
|
||||
create index it2i2 on t2i (b2);
|
||||
create index it2i3 on t2i (b1, b2);
|
||||
|
||||
create index it3i1 on t3i (c1);
|
||||
create index it3i2 on t3i (c2);
|
||||
create index it3i3 on t3i (c1, c2);
|
||||
|
||||
insert into t1i select * from t1;
|
||||
insert into t2i select * from t2;
|
||||
insert into t3i select * from t3;
|
||||
|
||||
# force the use of materialization
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
|
||||
/******************************************************************************
|
||||
* Simple tests.
|
||||
******************************************************************************/
|
||||
# non-indexed nullable fields
|
||||
explain extended
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
|
||||
|
||||
explain extended
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
|
||||
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
|
||||
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
|
||||
|
||||
# indexed columns
|
||||
explain extended
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
|
||||
|
||||
explain extended
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
|
||||
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
|
||||
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
|
||||
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
|
||||
# BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable.
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
|
||||
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
|
||||
|
||||
prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
|
||||
execute st1;
|
||||
execute st1;
|
||||
prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
|
||||
execute st2;
|
||||
execute st2;
|
||||
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
-- error 1235
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
|
||||
|
||||
# test re-optimization/re-execution with different execution methods
|
||||
# prepare once, exec with different modes
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
prepare st1 from
|
||||
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
execute st1;
|
||||
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
prepare st1 from
|
||||
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
|
||||
# materialize the result of ORDER BY
|
||||
# non-indexed fields
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
|
||||
# indexed fields
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
|
||||
|
||||
/******************************************************************************
|
||||
* Views, UNIONs, several levels of nesting.
|
||||
******************************************************************************/
|
||||
# materialize the result of subquery over temp-table view
|
||||
|
||||
create algorithm=merge view v1 as
|
||||
select b1, c2 from t2, t3 where b2 > c2;
|
||||
|
||||
create algorithm=merge view v2 as
|
||||
select b1, c2 from t2, t3 group by b2, c2;
|
||||
|
||||
create algorithm=temptable view v1m as
|
||||
select b1, c2 from t2, t3 where b2 > c2;
|
||||
|
||||
create algorithm=temptable view v2m as
|
||||
select b1, c2 from t2, t3 group by b2, c2;
|
||||
|
||||
select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null);
|
||||
select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
|
||||
|
||||
select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
|
||||
select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
|
||||
|
||||
drop view v1, v2, v1m, v2m;
|
||||
|
||||
# nested subqueries, views
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
explain extended
|
||||
select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
# as above with correlated innermost subquery
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3 t3c
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3 t3c
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
|
||||
# multiple levels of nesting subqueries, unions
|
||||
explain extended
|
||||
(select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')
|
||||
group by b1, b2) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
|
||||
UNION
|
||||
(select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
|
||||
|
||||
(select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')
|
||||
group by b1, b2) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
|
||||
UNION
|
||||
(select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
|
||||
|
||||
|
||||
# UNION of subqueries as a subquery (thus it is not computed via materialization)
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
# as above, with a join conditon between the outer references
|
||||
explain extended
|
||||
select * from t1, t3
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(c1, c2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
|
||||
a1 = c1;
|
||||
select * from t1, t3
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(c1, c2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
|
||||
a1 = c1;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Negative tests, where materialization should not be applied.
|
||||
******************************************************************************/
|
||||
# UNION in a subquery
|
||||
explain extended
|
||||
select * from t3
|
||||
where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
|
||||
select * from t3
|
||||
where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
|
||||
|
||||
# correlation
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3 t3c
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2));
|
||||
|
||||
# subquery has no tables
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Subqueries in other uncovered clauses.
|
||||
******************************************************************************/
|
||||
|
||||
/* SELECT clause */
|
||||
select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
|
||||
|
||||
/* GROUP BY clause */
|
||||
create table columns (col int key);
|
||||
insert into columns values (1), (2);
|
||||
|
||||
explain extended
|
||||
select * from t1 group by (select col from columns limit 1);
|
||||
select * from t1 group by (select col from columns limit 1);
|
||||
|
||||
explain extended
|
||||
select * from t1 group by (a1 in (select col from columns));
|
||||
select * from t1 group by (a1 in (select col from columns));
|
||||
|
||||
/* ORDER BY clause */
|
||||
explain extended
|
||||
select * from t1 order by (select col from columns limit 1);
|
||||
select * from t1 order by (select col from columns limit 1);
|
||||
|
||||
/******************************************************************************
|
||||
* Column types/sizes that affect materialization.
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
Test that BLOBs are not materialized (except when arguments of some functions).
|
||||
*/
|
||||
# force materialization to be always considered
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
set @prefix_len = 6;
|
||||
|
||||
# BLOB == 16 (small blobs that could be stored in HEAP tables)
|
||||
set @blob_len = 16;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_16 (a1 blob(16), a2 blob(16));
|
||||
create table t2_16 (b1 blob(16), b2 blob(16));
|
||||
create table t3_16 (c1 blob(16), c2 blob(16));
|
||||
|
||||
insert into t1_16 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_16 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_16 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_16 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_16 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_16 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_16 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_16 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_16 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_16 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select b1 from t2_16 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select b1 from t2_16 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
# BLOB column at the second (intermediate) level of nesting
|
||||
explain extended
|
||||
select * from t1
|
||||
where concat(a1,'x') IN
|
||||
(select left(a1,8) from t1_16
|
||||
where (a1, a2) IN
|
||||
(select t2_16.b1, t2_16.b2 from t2_16, t2
|
||||
where t2.b2 = substring(t2_16.b2,1,6) and
|
||||
t2.b1 IN (select c1 from t3 where c2 > '0')));
|
||||
|
||||
|
||||
drop table t1_16, t2_16, t3_16;
|
||||
|
||||
|
||||
# BLOB == 512 (CONVERT_IF_BIGGER_TO_BLOB == 512)
|
||||
set @blob_len = 512;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_512 (a1 blob(512), a2 blob(512));
|
||||
create table t2_512 (b1 blob(512), b2 blob(512));
|
||||
create table t3_512 (c1 blob(512), c2 blob(512));
|
||||
|
||||
insert into t1_512 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_512 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_512 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_512 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_512 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_512 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_512 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_512 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_512 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_512 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select b1 from t2_512 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select b1 from t2_512 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
drop table t1_512, t2_512, t3_512;
|
||||
|
||||
|
||||
# BLOB == 1024 (group_concat_max_len == 1024)
|
||||
set @blob_len = 1024;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_1024 (a1 blob(1024), a2 blob(1024));
|
||||
create table t2_1024 (b1 blob(1024), b2 blob(1024));
|
||||
create table t3_1024 (c1 blob(1024), c2 blob(1024));
|
||||
|
||||
insert into t1_1024 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_1024 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_1024 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_1024 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_1024 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_1024 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select b1 from t2_1024 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select b1 from t2_1024 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1024)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
drop table t1_1024, t2_1024, t3_1024;
|
||||
|
||||
|
||||
# BLOB == 1025
|
||||
set @blob_len = 1025;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_1025 (a1 blob(1025), a2 blob(1025));
|
||||
create table t2_1025 (b1 blob(1025), b2 blob(1025));
|
||||
create table t3_1025 (c1 blob(1025), c2 blob(1025));
|
||||
|
||||
insert into t1_1025 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_1025 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_1025 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_1025 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_1025 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_1025 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select b1 from t2_1025 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select b1 from t2_1025 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1025)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
drop table t1_1025, t2_1025, t3_1025;
|
||||
|
||||
# test for BIT fields
|
||||
create table t1bit (a1 bit(3), a2 bit(3));
|
||||
create table t2bit (b1 bit(3), b2 bit(3));
|
||||
|
||||
insert into t1bit values (b'000', b'100');
|
||||
insert into t1bit values (b'001', b'101');
|
||||
insert into t1bit values (b'010', b'110');
|
||||
|
||||
insert into t2bit values (b'001', b'101');
|
||||
insert into t2bit values (b'010', b'110');
|
||||
insert into t2bit values (b'110', b'111');
|
||||
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
|
||||
explain extended select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
||||
select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
||||
drop table t1bit, t2bit;
|
||||
|
||||
# test mixture of BIT and BLOB
|
||||
create table t1bb (a1 bit(3), a2 blob(3));
|
||||
create table t2bb (b1 bit(3), b2 blob(3));
|
||||
|
||||
insert into t1bb values (b'000', '100');
|
||||
insert into t1bb values (b'001', '101');
|
||||
insert into t1bb values (b'010', '110');
|
||||
|
||||
insert into t2bb values (b'001', '101');
|
||||
insert into t2bb values (b'010', '110');
|
||||
insert into t2bb values (b'110', '111');
|
||||
|
||||
explain extended select bin(a1), a2
|
||||
from t1bb
|
||||
where (a1, a2) in (select b1, b2 from t2bb);
|
||||
|
||||
select bin(a1), a2
|
||||
from t1bb
|
||||
where (a1, a2) in (select b1, b2 from t2bb);
|
||||
|
||||
drop table t1bb, t2bb;
|
||||
drop table t1, t2, t3, t1i, t2i, t3i, columns;
|
||||
|
||||
/******************************************************************************
|
||||
* Test the cache of the left operand of IN.
|
||||
******************************************************************************/
|
||||
set @@optimizer_switch='semijoin=off';
|
||||
|
||||
# Test that default values of Cached_item are not used for comparison
|
||||
create table t1 (s1 int);
|
||||
create table t2 (s2 int);
|
||||
insert into t1 values (5),(1),(0);
|
||||
insert into t2 values (0), (1);
|
||||
select s2 from t2 where s2 in (select s1 from t1);
|
||||
drop table t1, t2;
|
||||
|
||||
create table t1 (a int not null, b int not null);
|
||||
create table t2 (c int not null, d int not null);
|
||||
create table t3 (e int not null);
|
||||
|
||||
# the first outer row has no matching inner row
|
||||
insert into t1 values (1,10);
|
||||
insert into t1 values (1,20);
|
||||
insert into t1 values (2,10);
|
||||
insert into t1 values (2,20);
|
||||
insert into t1 values (2,30);
|
||||
insert into t1 values (3,20);
|
||||
insert into t1 values (4,40);
|
||||
|
||||
insert into t2 values (2,10);
|
||||
insert into t2 values (2,20);
|
||||
insert into t2 values (2,40);
|
||||
insert into t2 values (3,20);
|
||||
insert into t2 values (4,10);
|
||||
insert into t2 values (5,10);
|
||||
|
||||
insert into t3 values (10);
|
||||
insert into t3 values (10);
|
||||
insert into t3 values (20);
|
||||
insert into t3 values (30);
|
||||
|
||||
explain extended
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
|
||||
create index it1a on t1(a);
|
||||
|
||||
explain extended
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
|
||||
# the first outer row has a matching inner row
|
||||
insert into t2 values (1,10);
|
||||
|
||||
explain extended
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
|
||||
# cacheing for IN predicates inside a having clause - here the cached
|
||||
# items are changed to point to temporary tables.
|
||||
explain extended
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
|
||||
# create an index that can be used for the outer query GROUP BY
|
||||
create index iab on t1(a, b);
|
||||
explain extended
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
|
||||
explain extended
|
||||
select a from t1 group by a
|
||||
having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
|
||||
select a from t1 group by a
|
||||
having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
|
||||
explain extended
|
||||
select a from t1
|
||||
where a in (select c from t2 where d >= some(select e from t3 where b=e));
|
||||
select a from t1
|
||||
where a in (select c from t2 where d >= some(select e from t3 where b=e));
|
||||
|
||||
drop table t1, t2, t3;
|
||||
|
||||
#
|
||||
# BUG#36133 "Assertion `exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION &&"
|
||||
#
|
||||
create table t2 (a int, b int, key(a), key(b));
|
||||
insert into t2 values (3,3),(3,3),(3,3);
|
||||
select 1 from t2 where
|
||||
t2.a > 1
|
||||
or
|
||||
t2.a = 3 and not t2.a not in (select t2.b from t2);
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# BUG#37896 Assertion on entry of Item_in_subselect::exec on subquery with AND NOT
|
||||
#
|
||||
create table t1 (a1 int key);
|
||||
create table t2 (b1 int);
|
||||
insert into t1 values (5);
|
||||
|
||||
# Query with group by, executed via materialization
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
# Query with group by, executed via IN=>EXISTS
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
|
||||
# Executed with materialization
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
# Executed with semi-join. Notice, this time we get a different result (NULL).
|
||||
# This is the only correct result of all four queries. This difference is
|
||||
# filed as BUG#40037.
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# BUG#36752 "subquery materialization produces wrong results when comparing different types"
|
||||
#
|
||||
create table t1 (a char(2), b varchar(10));
|
||||
insert into t1 values ('a', 'aaa');
|
||||
insert into t1 values ('aa', 'aaaa');
|
||||
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
explain select a,b from t1 where b in (select a from t1);
|
||||
select a,b from t1 where b in (select a from t1);
|
||||
prepare st1 from "select a,b from t1 where b in (select a from t1)";
|
||||
execute st1;
|
||||
execute st1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #44303 Assertion failures in Field_new_decimal::store_decimal
|
||||
# when executing materialized InsideOut semijoin
|
||||
#
|
||||
CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
|
||||
INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
|
||||
INSERT INTO t1 (f1, f2) VALUES (10, 1.668);
|
||||
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t2 VALUES (1, 1.789);
|
||||
INSERT INTO t2 VALUES (13, 1.454);
|
||||
|
||||
SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
||||
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
|
||||
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#
|
||||
# BUG#46548 IN-subqueries return 0 rows with materialization=on
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
pk int,
|
||||
a varchar(1),
|
||||
b varchar(4),
|
||||
c varchar(4),
|
||||
d varchar(4),
|
||||
PRIMARY KEY (pk)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
|
||||
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
|
||||
|
||||
SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
||||
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # BUG#50019: Wrong result for IN-subquery with materialization
|
||||
--echo #
|
||||
create table t1(i int);
|
||||
insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
create table t2(i int);
|
||||
insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
create table t3(i int);
|
||||
insert into t3 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set session optimizer_switch='materialization=off';
|
||||
select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
|
||||
set session optimizer_switch=@save_optimizer_switch;
|
||||
drop table t1, t2, t3;
|
||||
--source t/subselect_sj_mat.test
|
||||
|
||||
set @@optimizer_switch=default;
|
||||
#
|
||||
# Test that the contents of the temp table of a materialized subquery is
|
||||
# cleaned up between PS re-executions.
|
||||
|
@ -1011,6 +116,36 @@ SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
|||
SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
-- echo #
|
||||
-- echo # BUG#724228: Wrong result with materialization=on and three aggregates in maria-5.3-mwl90
|
||||
-- echo #
|
||||
CREATE TABLE t1 ( f2 int(11)) ;
|
||||
INSERT IGNORE INTO t1 VALUES ('7'),('9'),('7'),('4'),('2'),('6'),('8'),('5'),('6'),('188'),('2'),('1'),('1'),('0'),('9'),('4');
|
||||
|
||||
CREATE TABLE t2 ( f1 int(11), f2 int(11)) ENGINE=MyISAM;
|
||||
INSERT IGNORE INTO t2 VALUES ('1','1');
|
||||
|
||||
CREATE TABLE t3 ( f1 int(11), f2 int(11), f3 int(11), PRIMARY KEY (f1)) ;
|
||||
INSERT IGNORE INTO t3 VALUES ('16','6','1'),('18','3','4'),('19',NULL,'9'),('20','0','6'),('41','2','0'),('42','2','5'),('43','9','6'),('44','7','4'),('45','1','4'),('46','222','238'),('47','3','6'),('48','6','6'),('49',NULL,'1'),('50','5','1');
|
||||
|
||||
SET @_save_join_cache_level = @@join_cache_level;
|
||||
SET @_save_optimizer_switch = @@optimizer_switch;
|
||||
|
||||
SET join_cache_level = 1;
|
||||
SET optimizer_switch='materialization=on';
|
||||
|
||||
SELECT f1 FROM t3
|
||||
WHERE
|
||||
f1 NOT IN (SELECT MAX(f2) FROM t1) AND
|
||||
f3 IN (SELECT MIN(f1) FROM t2) AND
|
||||
f1 IN (SELECT COUNT(f2) FROM t1);
|
||||
|
||||
SET @@join_cache_level = @_save_join_cache_level;
|
||||
SET @@optimizer_switch = @_save_optimizer_switch;
|
||||
|
||||
drop table t1, t2, t3;
|
||||
|
||||
--echo #
|
||||
--echo # LPBUG#719198 Ordered_key::cmp_key_with_search_key(rownum_t): Assertion `!compare_pred[i]->null_value'
|
||||
--echo # failed with subquery on both sides of NOT IN and materialization
|
||||
|
|
|
@ -490,6 +490,12 @@ drop table t1, t2;
|
|||
# Bug#33062: subquery in stored routine cause crash
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
drop procedure if exists p4;
|
||||
--enable_warnings
|
||||
CREATE TABLE t1(a INT);
|
||||
CREATE TABLE t2(c INT);
|
||||
|
||||
|
|
938
mysql-test/t/subselect_sj_mat.test
Normal file
938
mysql-test/t/subselect_sj_mat.test
Normal file
|
@ -0,0 +1,938 @@
|
|||
#
|
||||
# Hash semi-join regression tests
|
||||
# (WL#1110: Subquery optimization: materialization)
|
||||
#
|
||||
|
||||
set optimizer_switch='firstmatch=off';
|
||||
--disable_warnings
|
||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
||||
drop view if exists v1, v2, v1m, v2m;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (a1 char(8), a2 char(8));
|
||||
create table t2 (b1 char(8), b2 char(8));
|
||||
create table t3 (c1 char(8), c2 char(8));
|
||||
|
||||
insert into t1 values ('1 - 00', '2 - 00');
|
||||
insert into t1 values ('1 - 01', '2 - 01');
|
||||
insert into t1 values ('1 - 02', '2 - 02');
|
||||
|
||||
insert into t2 values ('1 - 01', '2 - 01');
|
||||
insert into t2 values ('1 - 01', '2 - 01');
|
||||
insert into t2 values ('1 - 02', '2 - 02');
|
||||
insert into t2 values ('1 - 02', '2 - 02');
|
||||
insert into t2 values ('1 - 03', '2 - 03');
|
||||
|
||||
insert into t3 values ('1 - 01', '2 - 01');
|
||||
insert into t3 values ('1 - 02', '2 - 02');
|
||||
insert into t3 values ('1 - 03', '2 - 03');
|
||||
insert into t3 values ('1 - 04', '2 - 04');
|
||||
|
||||
# Indexed columns
|
||||
create table t1i (a1 char(8), a2 char(8));
|
||||
create table t2i (b1 char(8), b2 char(8));
|
||||
create table t3i (c1 char(8), c2 char(8));
|
||||
create index it1i1 on t1i (a1);
|
||||
create index it1i2 on t1i (a2);
|
||||
create index it1i3 on t1i (a1, a2);
|
||||
|
||||
create index it2i1 on t2i (b1);
|
||||
create index it2i2 on t2i (b2);
|
||||
create index it2i3 on t2i (b1, b2);
|
||||
|
||||
create index it3i1 on t3i (c1);
|
||||
create index it3i2 on t3i (c2);
|
||||
create index it3i3 on t3i (c1, c2);
|
||||
|
||||
insert into t1i select * from t1;
|
||||
insert into t2i select * from t2;
|
||||
insert into t3i select * from t3;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Simple tests.
|
||||
******************************************************************************/
|
||||
# non-indexed nullable fields
|
||||
explain extended
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
|
||||
|
||||
explain extended
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
|
||||
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
|
||||
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
|
||||
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
|
||||
|
||||
# indexed columns
|
||||
--replace_column 7 #
|
||||
--replace_regex /it1.*/_it1_idx/ /test.t2i.*/_ref_/ /Using index$// /Using where$//
|
||||
explain extended
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
|
||||
|
||||
--replace_column 6 # 8 # 11 #
|
||||
explain extended
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
|
||||
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
|
||||
|
||||
--replace_column 7 #
|
||||
--replace_regex /it1.*/_it1_idx/ /test.t2i.*/_ref_/ /Using index$// /Using where$//
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
|
||||
|
||||
--replace_column 6 # 7 # 8 # 11 #
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
|
||||
|
||||
--replace_column 6 # 7 # 8 # 11 #
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
|
||||
# BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable.
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
|
||||
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
|
||||
|
||||
prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
|
||||
execute st1;
|
||||
execute st1;
|
||||
prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
|
||||
execute st2;
|
||||
execute st2;
|
||||
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
|
||||
-- error 1235
|
||||
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
|
||||
|
||||
# test re-optimization/re-execution with different execution methods
|
||||
# prepare once, exec with different modes
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
prepare st1 from
|
||||
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
execute st1;
|
||||
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
prepare st1 from
|
||||
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
# materialize the result of ORDER BY
|
||||
# non-indexed fields
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
|
||||
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
|
||||
# indexed fields
|
||||
explain extended
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
|
||||
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
|
||||
|
||||
/******************************************************************************
|
||||
* Views, UNIONs, several levels of nesting.
|
||||
******************************************************************************/
|
||||
# materialize the result of subquery over temp-table view
|
||||
|
||||
create algorithm=merge view v1 as
|
||||
select b1, c2 from t2, t3 where b2 > c2;
|
||||
|
||||
create algorithm=merge view v2 as
|
||||
select b1, c2 from t2, t3 group by b2, c2;
|
||||
|
||||
create algorithm=temptable view v1m as
|
||||
select b1, c2 from t2, t3 where b2 > c2;
|
||||
|
||||
create algorithm=temptable view v2m as
|
||||
select b1, c2 from t2, t3 group by b2, c2;
|
||||
|
||||
select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null);
|
||||
select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
|
||||
|
||||
select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
|
||||
select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
|
||||
|
||||
drop view v1, v2, v1m, v2m;
|
||||
|
||||
# nested subqueries, views
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
--replace_column 6 # 7 # 8 # 11 #
|
||||
explain extended
|
||||
select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
# as above with correlated innermost subquery
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3 t3c
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3 t3c
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
|
||||
|
||||
# multiple levels of nesting subqueries, unions
|
||||
--replace_column 6 # 7 # 8 # 11 #
|
||||
explain extended
|
||||
(select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')
|
||||
group by b1, b2) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
|
||||
UNION
|
||||
(select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
|
||||
|
||||
(select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 where c2 LIKE '%02') or
|
||||
b2 in (select c2 from t3 where c2 LIKE '%03')
|
||||
group by b1, b2) and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
|
||||
UNION
|
||||
(select * from t1i
|
||||
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
|
||||
(a1, a2) in (select c1, c2 from t3i
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
|
||||
|
||||
|
||||
# UNION of subqueries as a subquery (thus it is not computed via materialization)
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
select * from t1
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(a1, a2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
|
||||
# as above, with a join conditon between the outer references
|
||||
explain extended
|
||||
select * from t1, t3
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(c1, c2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
|
||||
a1 = c1;
|
||||
select * from t1, t3
|
||||
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
|
||||
(c1, c2) in (select c1, c2 from t3
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
|
||||
a1 = c1;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Negative tests, where materialization should not be applied.
|
||||
******************************************************************************/
|
||||
# UNION in a subquery
|
||||
explain extended
|
||||
select * from t3
|
||||
where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
|
||||
select * from t3
|
||||
where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
|
||||
|
||||
# correlation
|
||||
explain extended
|
||||
select * from t1
|
||||
where (a1, a2) in (select b1, b2 from t2
|
||||
where b2 in (select c2 from t3 t3a where c1 = a1) or
|
||||
b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
|
||||
(a1, a2) in (select c1, c2 from t3 t3c
|
||||
where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2));
|
||||
|
||||
# subquery has no tables
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
|
||||
explain extended
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
|
||||
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Subqueries in other uncovered clauses.
|
||||
******************************************************************************/
|
||||
|
||||
/* SELECT clause */
|
||||
select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
|
||||
|
||||
/* GROUP BY clause */
|
||||
create table columns (col int key);
|
||||
insert into columns values (1), (2);
|
||||
|
||||
explain extended
|
||||
select * from t1 group by (select col from columns limit 1);
|
||||
select * from t1 group by (select col from columns limit 1);
|
||||
|
||||
explain extended
|
||||
select * from t1 group by (a1 in (select col from columns));
|
||||
select * from t1 group by (a1 in (select col from columns));
|
||||
|
||||
/* ORDER BY clause */
|
||||
explain extended
|
||||
select * from t1 order by (select col from columns limit 1);
|
||||
select * from t1 order by (select col from columns limit 1);
|
||||
|
||||
/******************************************************************************
|
||||
* Column types/sizes that affect materialization.
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
Test that BLOBs are not materialized (except when arguments of some functions).
|
||||
*/
|
||||
# force materialization to be always considered
|
||||
set @prefix_len = 6;
|
||||
|
||||
# BLOB == 16 (small blobs that could be stored in HEAP tables)
|
||||
set @blob_len = 16;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_16 (a1 blob(16), a2 blob(16));
|
||||
create table t2_16 (b1 blob(16), b2 blob(16));
|
||||
create table t3_16 (c1 blob(16), c2 blob(16));
|
||||
|
||||
insert into t1_16 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_16 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_16 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_16 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_16 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_16 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_16 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_16 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_16 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_16 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select b1 from t2_16 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select b1 from t2_16 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_16
|
||||
where a1 in (select group_concat(b1) from t2_16 group by b2);
|
||||
|
||||
# BLOB column at the second (intermediate) level of nesting
|
||||
explain extended
|
||||
select * from t1
|
||||
where concat(a1,'x') IN
|
||||
(select left(a1,8) from t1_16
|
||||
where (a1, a2) IN
|
||||
(select t2_16.b1, t2_16.b2 from t2_16, t2
|
||||
where t2.b2 = substring(t2_16.b2,1,6) and
|
||||
t2.b1 IN (select c1 from t3 where c2 > '0')));
|
||||
|
||||
|
||||
drop table t1_16, t2_16, t3_16;
|
||||
|
||||
|
||||
# BLOB == 512 (CONVERT_IF_BIGGER_TO_BLOB == 512)
|
||||
set @blob_len = 512;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_512 (a1 blob(512), a2 blob(512));
|
||||
create table t2_512 (b1 blob(512), b2 blob(512));
|
||||
create table t3_512 (c1 blob(512), c2 blob(512));
|
||||
|
||||
insert into t1_512 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_512 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_512 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_512 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_512 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_512 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_512 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_512 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_512 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_512 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select b1 from t2_512 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select b1 from t2_512 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_512
|
||||
where a1 in (select group_concat(b1) from t2_512 group by b2);
|
||||
|
||||
drop table t1_512, t2_512, t3_512;
|
||||
|
||||
|
||||
# BLOB == 1024 (group_concat_max_len == 1024)
|
||||
set @blob_len = 1024;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_1024 (a1 blob(1024), a2 blob(1024));
|
||||
create table t2_1024 (b1 blob(1024), b2 blob(1024));
|
||||
create table t3_1024 (c1 blob(1024), c2 blob(1024));
|
||||
|
||||
insert into t1_1024 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_1024 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_1024 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_1024 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_1024 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_1024 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_1024 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select b1 from t2_1024 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select b1 from t2_1024 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1024)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1024
|
||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||
|
||||
drop table t1_1024, t2_1024, t3_1024;
|
||||
|
||||
|
||||
# BLOB == 1025
|
||||
set @blob_len = 1025;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
||||
create table t1_1025 (a1 blob(1025), a2 blob(1025));
|
||||
create table t2_1025 (b1 blob(1025), b2 blob(1025));
|
||||
create table t3_1025 (c1 blob(1025), c2 blob(1025));
|
||||
|
||||
insert into t1_1025 values
|
||||
(concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
|
||||
insert into t1_1025 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t1_1025 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t2_1025 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t2_1025 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t2_1025 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
|
||||
insert into t3_1025 values
|
||||
(concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
|
||||
|
||||
# single value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select b1 from t2_1025 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select b1 from t2_1025 where b1 > '0');
|
||||
|
||||
# row value transformer
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
|
||||
|
||||
# string function with a blob argument, the return type may be != blob
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
||||
|
||||
# group_concat with a blob argument - depends on
|
||||
# the variable group_concat_max_len, and
|
||||
# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1025)
|
||||
|
||||
explain extended select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
select left(a1,7), left(a2,7)
|
||||
from t1_1025
|
||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||
|
||||
drop table t1_1025, t2_1025, t3_1025;
|
||||
|
||||
# test for BIT fields
|
||||
create table t1bit (a1 bit(3), a2 bit(3));
|
||||
create table t2bit (b1 bit(3), b2 bit(3));
|
||||
|
||||
insert into t1bit values (b'000', b'100');
|
||||
insert into t1bit values (b'001', b'101');
|
||||
insert into t1bit values (b'010', b'110');
|
||||
|
||||
insert into t2bit values (b'001', b'101');
|
||||
insert into t2bit values (b'010', b'110');
|
||||
insert into t2bit values (b'110', b'111');
|
||||
|
||||
explain extended select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
||||
select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
||||
drop table t1bit, t2bit;
|
||||
|
||||
# test mixture of BIT and BLOB
|
||||
create table t1bb (a1 bit(3), a2 blob(3));
|
||||
create table t2bb (b1 bit(3), b2 blob(3));
|
||||
|
||||
insert into t1bb values (b'000', '100');
|
||||
insert into t1bb values (b'001', '101');
|
||||
insert into t1bb values (b'010', '110');
|
||||
|
||||
insert into t2bb values (b'001', '101');
|
||||
insert into t2bb values (b'010', '110');
|
||||
insert into t2bb values (b'110', '111');
|
||||
|
||||
explain extended select bin(a1), a2
|
||||
from t1bb
|
||||
where (a1, a2) in (select b1, b2 from t2bb);
|
||||
|
||||
select bin(a1), a2
|
||||
from t1bb
|
||||
where (a1, a2) in (select b1, b2 from t2bb);
|
||||
|
||||
drop table t1bb, t2bb;
|
||||
drop table t1, t2, t3, t1i, t2i, t3i, columns;
|
||||
|
||||
/******************************************************************************
|
||||
* Test the cache of the left operand of IN.
|
||||
******************************************************************************/
|
||||
|
||||
# Test that default values of Cached_item are not used for comparison
|
||||
create table t1 (s1 int);
|
||||
create table t2 (s2 int);
|
||||
insert into t1 values (5),(1),(0);
|
||||
insert into t2 values (0), (1);
|
||||
select s2 from t2 where s2 in (select s1 from t1);
|
||||
drop table t1, t2;
|
||||
|
||||
create table t1 (a int not null, b int not null);
|
||||
create table t2 (c int not null, d int not null);
|
||||
create table t3 (e int not null);
|
||||
|
||||
# the first outer row has no matching inner row
|
||||
insert into t1 values (1,10);
|
||||
insert into t1 values (1,20);
|
||||
insert into t1 values (2,10);
|
||||
insert into t1 values (2,20);
|
||||
insert into t1 values (2,30);
|
||||
insert into t1 values (3,20);
|
||||
insert into t1 values (4,40);
|
||||
|
||||
insert into t2 values (2,10);
|
||||
insert into t2 values (2,20);
|
||||
insert into t2 values (2,40);
|
||||
insert into t2 values (3,20);
|
||||
insert into t2 values (4,10);
|
||||
insert into t2 values (5,10);
|
||||
|
||||
insert into t3 values (10);
|
||||
insert into t3 values (10);
|
||||
insert into t3 values (20);
|
||||
insert into t3 values (30);
|
||||
|
||||
explain extended
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
|
||||
create index it1a on t1(a);
|
||||
|
||||
explain extended
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
|
||||
# the first outer row has a matching inner row
|
||||
insert into t2 values (1,10);
|
||||
|
||||
explain extended
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
select a from t1 where a in (select c from t2 where d >= 20);
|
||||
|
||||
# cacheing for IN predicates inside a having clause - here the cached
|
||||
# items are changed to point to temporary tables.
|
||||
explain extended
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
|
||||
# create an index that can be used for the outer query GROUP BY
|
||||
create index iab on t1(a, b);
|
||||
explain extended
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
select a from t1 group by a having a in (select c from t2 where d >= 20);
|
||||
|
||||
explain extended
|
||||
select a from t1 group by a
|
||||
having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
|
||||
select a from t1 group by a
|
||||
having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
|
||||
explain extended
|
||||
select a from t1
|
||||
where a in (select c from t2 where d >= some(select e from t3 where b=e));
|
||||
select a from t1
|
||||
where a in (select c from t2 where d >= some(select e from t3 where b=e));
|
||||
|
||||
drop table t1, t2, t3;
|
||||
|
||||
#
|
||||
# BUG#36133 "Assertion `exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION &&"
|
||||
#
|
||||
create table t2 (a int, b int, key(a), key(b));
|
||||
insert into t2 values (3,3),(3,3),(3,3);
|
||||
select 1 from t2 where
|
||||
t2.a > 1
|
||||
or
|
||||
t2.a = 3 and not t2.a not in (select t2.b from t2);
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# BUG#37896 Assertion on entry of Item_in_subselect::exec on subquery with AND NOT
|
||||
#
|
||||
create table t1 (a1 int key);
|
||||
create table t2 (b1 int);
|
||||
insert into t1 values (5);
|
||||
|
||||
# Query with group by, executed via materialization
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
# Query with group by, executed via IN=>EXISTS
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
|
||||
|
||||
# Executed with materialization
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
# Executed with semi-join. Notice, this time we get a different result (NULL).
|
||||
# This is the only correct result of all four queries. This difference is
|
||||
# filed as BUG#40037.
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
-- echo # with MariaDB and MWL#90, this particular case is solved:
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
select min(a1) from t1 where 7 in (select b1 from t2);
|
||||
-- echo # but when we go around MWL#90 code, the problem still shows up:
|
||||
explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
|
||||
select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
|
||||
set @@optimizer_switch= @save_optimizer_switch;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# BUG#36752 "subquery materialization produces wrong results when comparing different types"
|
||||
#
|
||||
create table t1 (a char(2), b varchar(10));
|
||||
insert into t1 values ('a', 'aaa');
|
||||
insert into t1 values ('aa', 'aaaa');
|
||||
|
||||
explain select a,b from t1 where b in (select a from t1);
|
||||
select a,b from t1 where b in (select a from t1);
|
||||
prepare st1 from "select a,b from t1 where b in (select a from t1)";
|
||||
execute st1;
|
||||
execute st1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #44303 Assertion failures in Field_new_decimal::store_decimal
|
||||
# when executing materialized InsideOut semijoin
|
||||
#
|
||||
CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
|
||||
INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
|
||||
INSERT INTO t1 (f1, f2) VALUES (10, 1.668);
|
||||
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t2 VALUES (1, 1.789);
|
||||
INSERT INTO t2 VALUES (13, 1.454);
|
||||
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
||||
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
|
||||
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
|
||||
set @@optimizer_switch= @save_optimizer_switch;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#
|
||||
# BUG#46548 IN-subqueries return 0 rows with materialization=on
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
pk int,
|
||||
a varchar(1),
|
||||
b varchar(4),
|
||||
c varchar(4),
|
||||
d varchar(4),
|
||||
PRIMARY KEY (pk)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
|
||||
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
|
||||
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
SET @@optimizer_switch='default,semijoin=on,materialization=on';
|
||||
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
|
||||
DROP TABLE t1, t2;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
--echo #
|
||||
--echo # BUG#50019: Wrong result for IN-subquery with materialization
|
||||
--echo #
|
||||
create table t1(i int);
|
||||
insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
create table t2(i int);
|
||||
insert into t2 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
create table t3(i int);
|
||||
insert into t3 values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set session optimizer_switch='materialization=off';
|
||||
select * from t1 where t1.i in (select t2.i from t2 join t3 where t2.i + t3.i = 5);
|
||||
set session optimizer_switch=@save_optimizer_switch;
|
||||
drop table t1, t2, t3;
|
||||
|
||||
#
|
||||
# Test that the contentes of the temp table of a materialized subquery is
|
||||
# cleanup up between PS reexecutions.
|
||||
#
|
||||
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2);
|
||||
create table t1 (a int);
|
||||
insert into t1 values (0),(1),(2);
|
||||
explain select a, a in (select a from t1) from t0;
|
||||
select a, a in (select a from t1) from t0;
|
||||
prepare s from 'select a, a in (select a from t1) from t0';
|
||||
execute s;
|
||||
update t1 set a=123;
|
||||
execute s;
|
||||
drop table t0, t1;
|
||||
set optimizer_switch='firstmatch=on';
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#!@PERL@
|
||||
# Test of table elimination feature
|
||||
|
||||
|
|
|
@ -5905,28 +5905,12 @@ Item_field* Item_equal::get_first(Item_field *field)
|
|||
{
|
||||
/*
|
||||
It's a field from an materialized semi-join. We can substitute it only
|
||||
for a field from the same semi-join.
|
||||
for a field from the same semi-join. Find the first of such items.
|
||||
*/
|
||||
JOIN_TAB *first= field_tab;
|
||||
JOIN *join= field_tab->join;
|
||||
int tab_idx= field_tab - field_tab->join->join_tab;
|
||||
|
||||
DBUG_ASSERT(join->join_tab[tab_idx].table->map &
|
||||
emb_nest->sj_inner_tables);
|
||||
|
||||
/* Find the first table of this semi-join nest */
|
||||
for (int i= tab_idx-1; i >= (int)join->const_tables; i--)
|
||||
{
|
||||
if (join->join_tab[i].table->map & emb_nest->sj_inner_tables)
|
||||
first= join->join_tab + i;
|
||||
else
|
||||
// Found first tab that doesn't belong to current SJ.
|
||||
break;
|
||||
}
|
||||
/* Find an item to substitute for. */
|
||||
while ((item= it++))
|
||||
{
|
||||
if (item->field->table->reginfo.join_tab >= first)
|
||||
if (item->field->table->pos_in_table_list->embedding == emb_nest)
|
||||
{
|
||||
/*
|
||||
If we found given field then return NULL to avoid unnecessary
|
||||
|
@ -5938,32 +5922,27 @@ Item_field* Item_equal::get_first(Item_field *field)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
/*
|
||||
The field is not in SJ-Materialization nest. We must return the first
|
||||
field that's not embedded in a SJ-Materialization nest.
|
||||
Example: suppose we have a join order:
|
||||
field in the join order. The field may be inside a semi-join nest, i.e
|
||||
a join order may look like this:
|
||||
|
||||
SJ-Mat(it1 it2) ot1 ot2
|
||||
|
||||
and equality ot2.col = ot1.col = it2.col
|
||||
If we're looking for best substitute for 'ot2.col', we should pick ot1.col
|
||||
and not it2.col, because when we run a join between ot1 and ot2
|
||||
execution of SJ-Mat(...) has already finished and we can't rely on the
|
||||
value of it*.*.
|
||||
psergey-fix-fix: ^^ THAT IS INCORRECT ^^. Pick the first, whatever that
|
||||
is.
|
||||
where we're looking what to substitute ot2.col for. In this case we must
|
||||
still return it1.col, here's a proof why:
|
||||
|
||||
First let's note that either it1.col or it2.col participates in
|
||||
subquery's IN-equality. It can't be otherwise, because materialization is
|
||||
only applicable to uncorrelated subqueries, so the only way we could
|
||||
infer "it1.col=ot1.col" is from the IN-equality. Ok, so IN-eqality has
|
||||
it1.col or it2.col on its inner side. it1.col is first such item in the
|
||||
join order, so it's not possible for SJ-Mat to be
|
||||
SJ-Materialization-lookup, it is SJ-Materialization-Scan. The scan part
|
||||
of this strategy will unpack value of it1.col=it2.col into it1.col
|
||||
(that's the first equal item inside the subquery), and we'll be able to
|
||||
get it from there. qed.
|
||||
*/
|
||||
while ((item= it++))
|
||||
{
|
||||
TABLE_LIST *emb_nest= item->field->table->pos_in_table_list->embedding;
|
||||
if (!emb_nest || !emb_nest->sj_mat_info ||
|
||||
!emb_nest->sj_mat_info->is_used)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return fields.head();
|
||||
}
|
||||
// Shouldn't get here.
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), value_assigned(0), thd(0), substitution(0),
|
||||
expr_cache(0), engine(0), old_engine(0), used_tables_cache(0),
|
||||
have_to_be_excluded(0), const_item_cache(1), inside_first_fix_fields(0),
|
||||
done_first_fix_fields(FALSE), eliminated(FALSE), engine_changed(0),
|
||||
changed(0), is_correlated(FALSE)
|
||||
Item_result_field(), value_assigned(0), thd(0), old_engine(0),
|
||||
used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1),
|
||||
inside_first_fix_fields(0), done_first_fix_fields(FALSE),
|
||||
substitution(0), expr_cache(0), engine(0), eliminated(FALSE),
|
||||
engine_changed(0), changed(0), is_correlated(FALSE)
|
||||
{
|
||||
with_subselect= 1;
|
||||
reset();
|
||||
|
@ -195,11 +195,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
|||
{
|
||||
// all transformation is done (used by prepared statements)
|
||||
changed= 1;
|
||||
inside_first_fix_fields= FALSE;
|
||||
|
||||
|
||||
// all transformation is done (used by prepared statements)
|
||||
changed= 1;
|
||||
inside_first_fix_fields= FALSE;
|
||||
|
||||
/*
|
||||
Substitute the current item with an Item_in_optimizer that was
|
||||
|
@ -224,13 +220,13 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
|||
if (!(*ref)->fixed)
|
||||
res= (*ref)->fix_fields(thd, ref);
|
||||
goto end;
|
||||
//psergey-merge: done_first_fix_fields= FALSE;
|
||||
|
||||
}
|
||||
// Is it one field subselect?
|
||||
if (engine->cols() > max_columns)
|
||||
{
|
||||
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
|
||||
//psergey-merge: done_first_fix_fields= FALSE;
|
||||
|
||||
goto end;
|
||||
}
|
||||
fix_length_and_dec();
|
||||
|
@ -248,6 +244,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
|||
|
||||
end:
|
||||
done_first_fix_fields= FALSE;
|
||||
inside_first_fix_fields= FALSE;
|
||||
thd->where= save_where;
|
||||
return res;
|
||||
}
|
||||
|
@ -478,6 +475,12 @@ bool Item_subselect::exec()
|
|||
return (res);
|
||||
}
|
||||
|
||||
int Item_subselect::optimize()
|
||||
{
|
||||
int res;
|
||||
res= engine->optimize();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
Check if an expression cache is needed for this subquery
|
||||
|
@ -784,9 +787,6 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
|
|||
void Item_singlerow_subselect::store(uint i, Item *item)
|
||||
{
|
||||
row[i]->store(item);
|
||||
//psergey-merge: can do without that: row[i]->cache_value();
|
||||
//psergey-backport-timours: ^ really, without that ^
|
||||
//psergey-try-merge-again:
|
||||
row[i]->cache_value();
|
||||
}
|
||||
|
||||
|
@ -1009,7 +1009,7 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
|
|||
st_select_lex *select_lex):
|
||||
Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
|
||||
is_constant(FALSE), optimizer(0), pushed_cond_guards(NULL),
|
||||
exec_method(NOT_TRANSFORMED), upper_item(0)
|
||||
exec_method(NOT_TRANSFORMED), is_flattenable_semijoin(FALSE), upper_item(0)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
|
||||
left_expr= left_exp;
|
||||
|
@ -2230,7 +2230,7 @@ void Item_in_subselect::update_used_tables()
|
|||
@retval FALSE an execution method was chosen successfully
|
||||
*/
|
||||
|
||||
bool Item_in_subselect::setup_engine()
|
||||
bool Item_in_subselect::setup_engine(bool dont_switch_arena)
|
||||
{
|
||||
subselect_hash_sj_engine *new_engine= NULL;
|
||||
bool res= FALSE;
|
||||
|
@ -2245,14 +2245,15 @@ bool Item_in_subselect::setup_engine()
|
|||
|
||||
old_engine= (subselect_single_select_engine*) engine;
|
||||
|
||||
if (arena->is_conventional())
|
||||
if (arena->is_conventional() || dont_switch_arena)
|
||||
arena= 0;
|
||||
else
|
||||
thd->set_n_backup_active_arena(arena, &backup);
|
||||
|
||||
if (!(new_engine= new subselect_hash_sj_engine(thd, this,
|
||||
old_engine)) ||
|
||||
new_engine->init_permanent(unit->get_unit_column_types()))
|
||||
new_engine->init_permanent(unit->get_unit_column_types(),
|
||||
old_engine->get_identifier()))
|
||||
{
|
||||
Item_subselect::trans_res trans_res;
|
||||
/*
|
||||
|
@ -2323,7 +2324,7 @@ bool Item_in_subselect::init_left_expr_cache()
|
|||
An IN predicate might be evaluated in a query for which all tables have
|
||||
been optimzied away.
|
||||
*/
|
||||
if (!outer_join || !outer_join->tables || !outer_join->tables_list)
|
||||
if (!outer_join || !outer_join->table_count || !outer_join->tables_list)
|
||||
return TRUE;
|
||||
|
||||
if (!(left_expr_cache= new List<Cached_item>))
|
||||
|
@ -2708,9 +2709,9 @@ int subselect_single_select_engine::exec()
|
|||
pushed down into the subquery. Those optimizations are ref[_or_null]
|
||||
acceses. Change them to be full table scans.
|
||||
*/
|
||||
for (uint i=join->const_tables ; i < join->tables ; i++)
|
||||
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
|
||||
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
|
||||
{
|
||||
JOIN_TAB *tab=join->join_tab+i;
|
||||
if (tab && tab->keyuse)
|
||||
{
|
||||
for (uint i= 0; i < tab->ref.key_parts; i++)
|
||||
|
@ -3794,6 +3795,8 @@ bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
|
|||
reexecution.
|
||||
|
||||
@param tmp_columns the items that produce the data for the temp table
|
||||
@param subquery_id subquery's identifier (to make "<subquery%d>" name for
|
||||
EXPLAIN)
|
||||
|
||||
@details
|
||||
- Create a temporary table to store the result of the IN subquery. The
|
||||
|
@ -3809,7 +3812,8 @@ bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
|
|||
@retval FALSE otherwise
|
||||
*/
|
||||
|
||||
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
|
||||
bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns,
|
||||
uint subquery_id)
|
||||
{
|
||||
/* Options to create_tmp_table. */
|
||||
ulonglong tmp_create_options= thd->options | TMP_TABLE_ALL_COLUMNS;
|
||||
|
@ -3844,12 +3848,19 @@ bool subselect_hash_sj_engine::init_permanent(List<Item> *tmp_columns)
|
|||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
*/
|
||||
char buf[32];
|
||||
uint len= my_snprintf(buf, sizeof(buf), "<subquery%d>", subquery_id);
|
||||
char *name;
|
||||
if (!(name= (char*)thd->alloc(len + 1)))
|
||||
DBUG_RETURN(TRUE);
|
||||
memcpy(name, buf, len+1);
|
||||
|
||||
if (!(result= new select_materialize_with_stats))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (((select_union*) result)->create_result_table(
|
||||
thd, tmp_columns, TRUE, tmp_create_options,
|
||||
"materialized subselect", TRUE))
|
||||
name, TRUE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
tmp_table= ((select_union*) result)->table;
|
||||
|
@ -3930,7 +3941,7 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
|
|||
if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
tmp_table_ref->init_one_table("", "materialized subselect", TL_READ);
|
||||
tmp_table_ref->init_one_table("", tmp_table->alias.c_ptr(), TL_READ);
|
||||
tmp_table_ref->table= tmp_table;
|
||||
|
||||
context= new Name_resolution_context;
|
||||
|
@ -4075,6 +4086,17 @@ void subselect_hash_sj_engine::cleanup()
|
|||
}
|
||||
|
||||
|
||||
int subselect_hash_sj_engine::optimize()
|
||||
{
|
||||
int res;
|
||||
SELECT_LEX *save_select= thd->lex->current_select;
|
||||
thd->lex->current_select= materialize_join->select_lex;
|
||||
res= materialize_join->optimize();
|
||||
thd->lex->current_select= save_select;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
Execute a subquery IN predicate via materialization.
|
||||
|
||||
|
|
|
@ -36,26 +36,6 @@ class Item_subselect :public Item_result_field
|
|||
protected:
|
||||
/* thread handler, will be assigned in fix_fields only */
|
||||
THD *thd;
|
||||
/*
|
||||
Used inside Item_subselect::fix_fields() according to this scenario:
|
||||
> Item_subselect::fix_fields
|
||||
> engine->prepare
|
||||
> child_join->prepare
|
||||
(Here we realize we need to do the rewrite and set
|
||||
substitution= some new Item, eg. Item_in_optimizer )
|
||||
< child_join->prepare
|
||||
< engine->prepare
|
||||
*ref= substitution;
|
||||
< Item_subselect::fix_fields
|
||||
*/
|
||||
Item *substitution;
|
||||
public:
|
||||
/* unit of subquery */
|
||||
st_select_lex_unit *unit;
|
||||
protected:
|
||||
Item *expr_cache;
|
||||
/* engine that perform execution of subselect (single select or union) */
|
||||
subselect_engine *engine;
|
||||
/* old engine if engine was changed */
|
||||
subselect_engine *old_engine;
|
||||
/* cache of used external tables */
|
||||
|
@ -72,6 +52,25 @@ protected:
|
|||
bool inside_first_fix_fields;
|
||||
bool done_first_fix_fields;
|
||||
public:
|
||||
/*
|
||||
Used inside Item_subselect::fix_fields() according to this scenario:
|
||||
> Item_subselect::fix_fields
|
||||
> engine->prepare
|
||||
> child_join->prepare
|
||||
(Here we realize we need to do the rewrite and set
|
||||
substitution= some new Item, eg. Item_in_optimizer )
|
||||
< child_join->prepare
|
||||
< engine->prepare
|
||||
*ref= substitution;
|
||||
substitution= NULL;
|
||||
< Item_subselect::fix_fields
|
||||
*/
|
||||
Item *substitution;
|
||||
/* unit of subquery */
|
||||
st_select_lex_unit *unit;
|
||||
Item *expr_cache;
|
||||
/* engine that perform execution of subselect (single select or union) */
|
||||
subselect_engine *engine;
|
||||
/* A reference from inside subquery predicate to somewhere outside of it */
|
||||
class Ref_to_outside : public Sql_alloc
|
||||
{
|
||||
|
@ -148,6 +147,7 @@ public:
|
|||
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
|
||||
void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);
|
||||
virtual int optimize();
|
||||
virtual bool exec();
|
||||
virtual void fix_length_and_dec();
|
||||
table_map used_tables() const;
|
||||
|
@ -312,6 +312,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
TABLE_LIST * const NO_JOIN_NEST=(TABLE_LIST*)0x1;
|
||||
|
||||
/**
|
||||
Representation of IN subquery predicates of the form
|
||||
"left_expr IN (SELECT ...)".
|
||||
|
@ -350,10 +352,10 @@ protected:
|
|||
all JOIN in UNION
|
||||
*/
|
||||
Item *expr;
|
||||
Item_in_optimizer *optimizer;
|
||||
bool was_null;
|
||||
bool abort_on_null;
|
||||
public:
|
||||
Item_in_optimizer *optimizer;
|
||||
/* Used to trigger on/off conditions that were pushed down to subselect */
|
||||
bool *pushed_cond_guards;
|
||||
|
||||
|
@ -362,7 +364,7 @@ public:
|
|||
/*
|
||||
Used by subquery optimizations to keep track about in which clause this
|
||||
subquery predicate is located:
|
||||
(TABLE_LIST*) 1 - the predicate is an AND-part of the WHERE
|
||||
NO_JOIN_NEST - the predicate is an AND-part of the WHERE
|
||||
join nest pointer - the predicate is an AND-part of ON expression
|
||||
of a join nest
|
||||
NULL - for all other locations
|
||||
|
@ -374,7 +376,7 @@ public:
|
|||
- pointer to join nest if the subquery predicate is in the ON expression
|
||||
- (TABLE_LIST*)1 if the predicate is in the WHERE.
|
||||
*/
|
||||
TABLE_LIST *expr_join_nest;
|
||||
//TABLE_LIST *expr_join_nest;
|
||||
/*
|
||||
Types of left_expr and subquery's select list allow to perform subquery
|
||||
materialization. Currently, we set this to FALSE when it as well could
|
||||
|
@ -396,6 +398,11 @@ public:
|
|||
};
|
||||
enum_exec_method exec_method;
|
||||
|
||||
/*
|
||||
TRUE<=>this is a flattenable semi-join, false overwise.
|
||||
*/
|
||||
bool is_flattenable_semijoin;
|
||||
|
||||
bool *get_cond_guard(int i)
|
||||
{
|
||||
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
|
||||
|
@ -412,7 +419,7 @@ public:
|
|||
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
|
||||
Item_in_subselect()
|
||||
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
|
||||
is_constant(FALSE), optimizer(0), abort_on_null(0),
|
||||
is_constant(FALSE), abort_on_null(0), optimizer(0),
|
||||
pushed_cond_guards(NULL), exec_method(NOT_TRANSFORMED), upper_item(0)
|
||||
{}
|
||||
void cleanup();
|
||||
|
@ -445,7 +452,7 @@ public:
|
|||
bool fix_fields(THD *thd, Item **ref);
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
|
||||
void update_used_tables();
|
||||
bool setup_engine();
|
||||
bool setup_engine(bool dont_switch_arena);
|
||||
bool init_left_expr_cache();
|
||||
/* Inform 'this' that it was computed, and contains a valid result. */
|
||||
void set_first_execution() { if (first_execution) first_execution= FALSE; }
|
||||
|
@ -521,6 +528,7 @@ public:
|
|||
THD * get_thd() { return thd; }
|
||||
virtual int prepare()= 0;
|
||||
virtual void fix_length_and_dec(Item_cache** row)= 0;
|
||||
virtual int optimize() { DBUG_ASSERT(0); return 0; }
|
||||
/*
|
||||
Execute the engine
|
||||
|
||||
|
@ -751,7 +759,7 @@ inline bool Item_subselect::is_uncacheable() const
|
|||
|
||||
class subselect_hash_sj_engine : public subselect_engine
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
/* The table into which the subquery is materialized. */
|
||||
TABLE *tmp_table;
|
||||
/* TRUE if the subquery was materialized into a temp table. */
|
||||
|
@ -763,64 +771,34 @@ protected:
|
|||
of subselect_single_select_engine::[prepare | cols].
|
||||
*/
|
||||
subselect_single_select_engine *materialize_engine;
|
||||
/* The engine used to compute the IN predicate. */
|
||||
subselect_engine *lookup_engine;
|
||||
/*
|
||||
QEP to execute the subquery and materialize its result into a
|
||||
temporary table. Created during the first call to exec().
|
||||
*/
|
||||
JOIN *materialize_join;
|
||||
|
||||
/* Keyparts of the only non-NULL composite index in a rowid merge. */
|
||||
MY_BITMAP non_null_key_parts;
|
||||
/* Keyparts of the single column indexes with NULL, one keypart per index. */
|
||||
MY_BITMAP partial_match_key_parts;
|
||||
uint count_partial_match_columns;
|
||||
uint count_null_only_columns;
|
||||
/*
|
||||
A conjunction of all the equality condtions between all pairs of expressions
|
||||
that are arguments of an IN predicate. We need these to post-filter some
|
||||
IN results because index lookups sometimes match values that are actually
|
||||
not equal to the search key in SQL terms.
|
||||
*/
|
||||
*/
|
||||
Item_cond_and *semi_join_conds;
|
||||
/* Possible execution strategies that can be used to compute hash semi-join.*/
|
||||
enum exec_strategy {
|
||||
UNDEFINED,
|
||||
COMPLETE_MATCH, /* Use regular index lookups. */
|
||||
PARTIAL_MATCH, /* Use some partial matching strategy. */
|
||||
PARTIAL_MATCH_MERGE, /* Use partial matching through index merging. */
|
||||
PARTIAL_MATCH_SCAN, /* Use partial matching through table scan. */
|
||||
IMPOSSIBLE /* Subquery materialization is not applicable. */
|
||||
};
|
||||
/* The chosen execution strategy. Computed after materialization. */
|
||||
exec_strategy strategy;
|
||||
protected:
|
||||
exec_strategy get_strategy_using_schema();
|
||||
exec_strategy get_strategy_using_data();
|
||||
ulonglong rowid_merge_buff_size(bool has_non_null_key,
|
||||
bool has_covering_null_row,
|
||||
MY_BITMAP *partial_match_key_parts);
|
||||
void choose_partial_match_strategy(bool has_non_null_key,
|
||||
bool has_covering_null_row,
|
||||
MY_BITMAP *partial_match_key_parts);
|
||||
bool make_semi_join_conds();
|
||||
subselect_uniquesubquery_engine* make_unique_engine();
|
||||
|
||||
public:
|
||||
subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate,
|
||||
subselect_single_select_engine *old_engine)
|
||||
:subselect_engine(thd, in_predicate, NULL), tmp_table(NULL),
|
||||
is_materialized(FALSE), materialize_engine(old_engine), lookup_engine(NULL),
|
||||
materialize_join(NULL), count_partial_match_columns(0),
|
||||
count_null_only_columns(0), semi_join_conds(NULL), strategy(UNDEFINED)
|
||||
: subselect_engine(thd, in_predicate, NULL),
|
||||
tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
|
||||
materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
|
||||
count_partial_match_columns(0), count_null_only_columns(0),
|
||||
strategy(UNDEFINED)
|
||||
{}
|
||||
~subselect_hash_sj_engine();
|
||||
|
||||
bool init_permanent(List<Item> *tmp_columns);
|
||||
bool init_permanent(List<Item> *tmp_columns, uint subquery_id);
|
||||
bool init_runtime();
|
||||
void cleanup();
|
||||
int prepare() { return 0; } /* Override virtual function in base class. */
|
||||
int optimize();
|
||||
int exec();
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
uint cols()
|
||||
|
@ -840,6 +818,38 @@ public:
|
|||
//=>base class
|
||||
bool change_result(Item_subselect *si, select_result_interceptor *result);
|
||||
bool no_tables();//=>base class
|
||||
|
||||
protected:
|
||||
/* The engine used to compute the IN predicate. */
|
||||
subselect_engine *lookup_engine;
|
||||
/* Keyparts of the only non-NULL composite index in a rowid merge. */
|
||||
MY_BITMAP non_null_key_parts;
|
||||
/* Keyparts of the single column indexes with NULL, one keypart per index. */
|
||||
MY_BITMAP partial_match_key_parts;
|
||||
uint count_partial_match_columns;
|
||||
uint count_null_only_columns;
|
||||
/* Possible execution strategies that can be used to compute hash semi-join.*/
|
||||
enum exec_strategy {
|
||||
UNDEFINED,
|
||||
COMPLETE_MATCH, /* Use regular index lookups. */
|
||||
PARTIAL_MATCH, /* Use some partial matching strategy. */
|
||||
PARTIAL_MATCH_MERGE, /* Use partial matching through index merging. */
|
||||
PARTIAL_MATCH_SCAN, /* Use partial matching through table scan. */
|
||||
IMPOSSIBLE /* Subquery materialization is not applicable. */
|
||||
};
|
||||
/* The chosen execution strategy. Computed after materialization. */
|
||||
exec_strategy strategy;
|
||||
exec_strategy get_strategy_using_schema();
|
||||
exec_strategy get_strategy_using_data();
|
||||
ulonglong rowid_merge_buff_size(bool has_non_null_key,
|
||||
bool has_covering_null_row,
|
||||
MY_BITMAP *partial_match_key_parts);
|
||||
void choose_partial_match_strategy(bool has_non_null_key,
|
||||
bool has_covering_null_row,
|
||||
MY_BITMAP *partial_match_key_parts);
|
||||
bool make_semi_join_conds();
|
||||
subselect_uniquesubquery_engine* make_unique_engine();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -341,8 +341,9 @@ public:
|
|||
SEL_ARG(Field *field, uint8 part, uchar *min_value, uchar *max_value,
|
||||
uint8 min_flag, uint8 max_flag, uint8 maybe_flag);
|
||||
SEL_ARG(enum Type type_arg)
|
||||
:min_flag(0),elements(1),use_count(1),left(0),right(0),next_key_part(0),
|
||||
color(BLACK), type(type_arg)
|
||||
:min_flag(0), max_part_no(0) /* first key part means 1. 0 mean 'no parts'*/,
|
||||
elements(1),use_count(1),left(0),right(0),
|
||||
next_key_part(0), color(BLACK), type(type_arg)
|
||||
{}
|
||||
inline bool is_same(SEL_ARG *arg)
|
||||
{
|
||||
|
@ -2909,7 +2910,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
|
|||
quick=0;
|
||||
needed_reg.clear_all();
|
||||
quick_keys.clear_all();
|
||||
if (keys_to_use.is_clear_all())
|
||||
DBUG_ASSERT(!head->is_filled_at_execution());
|
||||
if (keys_to_use.is_clear_all() || head->is_filled_at_execution())
|
||||
DBUG_RETURN(0);
|
||||
records= head->file->stats.records;
|
||||
if (!records)
|
||||
|
@ -4317,7 +4319,7 @@ double get_sweep_read_cost(const PARAM *param, ha_rows records)
|
|||
return 1;
|
||||
*/
|
||||
JOIN *join= param->thd->lex->select_lex.join;
|
||||
if (!join || join->tables == 1)
|
||||
if (!join || join->table_count == 1)
|
||||
{
|
||||
/* No join, assume reading is done in one 'sweep' */
|
||||
result= busy_blocks*(DISK_SEEK_BASE_COST +
|
||||
|
@ -11268,7 +11270,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
|
|||
/* Perform few 'cheap' tests whether this access method is applicable. */
|
||||
if (!join)
|
||||
DBUG_RETURN(NULL); /* This is not a select statement. */
|
||||
if ((join->tables != 1) || /* The query must reference one table. */
|
||||
if ((join->table_count != 1) || /* The query must reference one table. */
|
||||
((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
|
||||
(!join->select_distinct)) ||
|
||||
(join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@file
|
||||
|
||||
@brief
|
||||
Subquery optimization code here.
|
||||
Semi-join subquery optimizations code
|
||||
|
||||
*/
|
||||
|
||||
|
@ -16,7 +16,162 @@
|
|||
|
||||
#include <my_bit.h>
|
||||
|
||||
// Our own:
|
||||
/*
|
||||
This file contains optimizations for semi-join subqueries.
|
||||
|
||||
Contents
|
||||
--------
|
||||
1. What is a semi-join subquery
|
||||
2. General idea about semi-join execution
|
||||
2.1 Correlated vs uncorrelated semi-joins
|
||||
2.2 Mergeable vs non-mergeable semi-joins
|
||||
3. Code-level view of semi-join processing
|
||||
3.1 Conversion
|
||||
3.1.1 Merged semi-join TABLE_LIST object
|
||||
3.1.2 Non-merged semi-join data structure
|
||||
3.2 Semi-joins and query optimization
|
||||
3.2.1 Non-merged semi-joins and join optimization
|
||||
3.2.2 Merged semi-joins and join optimization
|
||||
3.3 Semi-joins and query execution
|
||||
|
||||
1. What is a semi-join subquery
|
||||
-------------------------------
|
||||
We use this definition of semi-join:
|
||||
|
||||
outer_tbl SEMI JOIN inner_tbl ON cond = {set of outer_tbl.row such that
|
||||
exist inner_tbl.row, for which
|
||||
cond(outer_tbl.row,inner_tbl.row)
|
||||
is satisfied}
|
||||
|
||||
That is, semi-join operation is similar to inner join operation, with
|
||||
exception that we don't care how many matches a row from outer_tbl has in
|
||||
inner_tbl.
|
||||
|
||||
In SQL terms: a semi-join subquery is an IN subquery that is an AND-part of
|
||||
the WHERE/ON clause.
|
||||
|
||||
2. General idea about semi-join execution
|
||||
-----------------------------------------
|
||||
We can execute semi-join in a way similar to inner join, with exception that
|
||||
we need to somehow ensure that we do not generate record combinations that
|
||||
differ only in rows of inner tables.
|
||||
There is a number of different ways to achieve this property, implemented by
|
||||
a number of semi-join execution strategies.
|
||||
Some strategies can handle any semi-joins, other can be applied only to
|
||||
semi-joins that have certain properties that are described below:
|
||||
|
||||
2.1 Correlated vs uncorrelated semi-joins
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Uncorrelated semi-joins are special in the respect that they allow to
|
||||
- execute the subquery (possible as it's uncorrelated)
|
||||
- somehow make sure that generated set does not have duplicates
|
||||
- perform an inner join with outer tables.
|
||||
|
||||
or, rephrasing in SQL form:
|
||||
|
||||
SELECT ... FROM ot WHERE ot.col IN (SELECT it.col FROM it WHERE uncorr_cond)
|
||||
->
|
||||
SELECT ... FROM ot JOIN (SELECT DISTINCT it.col FROM it WHERE uncorr_cond)
|
||||
|
||||
2.2 Mergeable vs non-mergeable semi-joins
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Semi-join operation has some degree of commutability with inner join
|
||||
operation: we can join subquery's tables with ouside table(s) and eliminate
|
||||
duplicate record combination after that:
|
||||
|
||||
ot1 JOIN ot2 SEMI_JOIN{it1,it2} (it1 JOIN it2) ON sjcond(ot2,it*) ->
|
||||
|
|
||||
+-------------------------------+
|
||||
v
|
||||
ot1 SEMI_JOIN{it1,it2} (it1 JOIN it2 JOIN ot2) ON sjcond(ot2,it*)
|
||||
|
||||
In order for this to work, subquery's top-level operation must be join, and
|
||||
grouping or ordering with limit (grouping or ordering with limit are not
|
||||
commutative with duplicate removal). In other words, the conversion is
|
||||
possible when the subquery doesn't have GROUP BY clause, any aggregate
|
||||
functions*, or ORDER BY ... LIMIT clause.
|
||||
|
||||
Definitions:
|
||||
- Subquery whose top-level operation is a join is called *mergeable semi-join*
|
||||
- All other kinds of semi-join subqueries are considered non-mergeable.
|
||||
|
||||
*- this requirement is actually too strong, but its exceptions are too
|
||||
complicated to be considered here.
|
||||
|
||||
3. Code-level view of semi-join processing
|
||||
------------------------------------------
|
||||
|
||||
3.1 Conversion and pre-optimization data structures
|
||||
---------------------------------------------------
|
||||
* When doing JOIN::prepare for the subquery, we detect that it can be
|
||||
converted into a semi-join and register it in parent_join->sj_subselects
|
||||
|
||||
* At the start of parent_join->optimize(), the predicate is converted into
|
||||
a semi-join node. A semi-join node is a TABLE_LIST object that is linked
|
||||
somewhere in parent_join->join_list (either it is just present there, or
|
||||
it is a descendant of some of its members).
|
||||
|
||||
There are two kinds of semi-joins:
|
||||
- Merged semi-joins
|
||||
- Non-merged semi-joins
|
||||
|
||||
3.1.1 Merged semi-join TABLE_LIST object
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Merged semi-join object is a TABLE_LIST that contains a sub-join of
|
||||
subquery tables and the semi-join ON expression (in this respect it is
|
||||
very similar to nested outer join representation)
|
||||
Merged semi-join represents this SQL:
|
||||
|
||||
... SEMI JOIN (inner_tbl1 JOIN ... JOIN inner_tbl_n) ON sj_on_expr
|
||||
|
||||
Semi-join objects of this kind have TABLE_LIST::sj_subq_pred set.
|
||||
|
||||
3.1.2 Non-merged semi-join data structure
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Non-merged semi-join object is a leaf TABLE_LIST object that has a subquery
|
||||
that produces rows. It is similar to a base table and represents this SQL:
|
||||
|
||||
... SEMI_JOIN (SELECT non_mergeable_select) ON sj_on_expr
|
||||
|
||||
Subquery items that were converted into semi-joins are removed from the WHERE
|
||||
clause. (They do remain in PS-saved WHERE clause, and they replace themselves
|
||||
with Item_int(1) on subsequent re-executions).
|
||||
|
||||
3.2 Semi-joins and join optimization
|
||||
------------------------------------
|
||||
|
||||
3.2.1 Non-merged semi-joins and join optimization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
For join optimization purposes, non-merged semi-join nests are similar to
|
||||
base tables - they've got one JOIN_TAB, which can be accessed with one of
|
||||
two methods:
|
||||
- full table scan (representing SJ-Materialization-Scan strategy)
|
||||
- eq_ref-like table lookup (representing SJ-Materialization-Lookup)
|
||||
|
||||
Unlike regular base tables, non-merged semi-joins have:
|
||||
- non-zero JOIN_TAB::startup_cost, and
|
||||
- join_tab->table->is_filled_at_execution()==TRUE, which means one
|
||||
cannot do const table detection or range analysis or other table data-
|
||||
dependent inferences
|
||||
// instead, get_delayed_table_estimates() runs optimization on the nest so that
|
||||
// we get an idea about temptable size
|
||||
|
||||
3.2.2 Merged semi-joins and join optimization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
- optimize_semijoin_nests() does pre-optimization
|
||||
- during join optimization, the join has one JOIN_TAB (or is it POSITION?)
|
||||
array, and suffix-based detection is used, see advance_sj_state()
|
||||
- after join optimization is done, get_best_combination() switches
|
||||
the data-structure to prefix-based, multiple JOIN_TAB ranges format.
|
||||
|
||||
3.3 Semi-joins and query execution
|
||||
----------------------------------
|
||||
* Join executor has hooks for all semi-join strategies.
|
||||
TODO elaborate.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static
|
||||
bool subquery_types_allow_materialization(Item_in_subselect *in_subs);
|
||||
static bool replace_where_subcondition(JOIN *join, Item **expr,
|
||||
|
@ -25,6 +180,8 @@ static bool replace_where_subcondition(JOIN *join, Item **expr,
|
|||
static int subq_sj_candidate_cmp(Item_in_subselect* const *el1,
|
||||
Item_in_subselect* const *el2);
|
||||
static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred);
|
||||
static bool convert_subq_to_jtbm(JOIN *parent_join,
|
||||
Item_in_subselect *subq_pred, bool *remove);
|
||||
static TABLE_LIST *alloc_join_nest(THD *thd);
|
||||
static
|
||||
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist);
|
||||
|
@ -46,21 +203,29 @@ static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
|
|||
static Item *remove_additional_cond(Item* conds);
|
||||
static void remove_subq_pushed_predicates(JOIN *join, Item **where);
|
||||
|
||||
enum_nested_loop_state
|
||||
end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
|
||||
|
||||
|
||||
/*
|
||||
Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
|
||||
|
||||
SYNOPSIS
|
||||
check_and_do_in_subquery_rewrites()
|
||||
join Subquery's join
|
||||
|
||||
DESCRIPTION
|
||||
Check if we need to do
|
||||
- subquery->semi-join rewrite
|
||||
- subquery -> mergeable semi-join rewrite
|
||||
- if the subquery can be handled with materialization
|
||||
- 'substitution' rewrite for table-less subqueries like "(select 1)"
|
||||
|
||||
and mark appropriately
|
||||
- IN->EXISTS rewrite
|
||||
and, depending on the rewrite, either do it, or record it to be done at a
|
||||
later phase.
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - Some sort of query error
|
||||
0 - OK
|
||||
Other - Some sort of query error
|
||||
*/
|
||||
|
||||
int check_and_do_in_subquery_rewrites(JOIN *join)
|
||||
|
@ -166,11 +331,11 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||
(void)subquery_types_allow_materialization(in_subs);
|
||||
|
||||
in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
|
||||
in_subs->is_flattenable_semijoin= TRUE;
|
||||
|
||||
/* Register the subquery for further processing in flatten_subqueries() */
|
||||
select_lex->
|
||||
outer_select()->join->sj_subselects.append(thd->mem_root, in_subs);
|
||||
in_subs->expr_join_nest= thd->thd_marker.emb_on_expr_nest;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -220,10 +385,24 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||
(in_subs->is_top_level_item() ||
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) ||
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) &&//4
|
||||
!in_subs->is_correlated && // 5
|
||||
in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED) // 6
|
||||
!in_subs->is_correlated) // 5
|
||||
{
|
||||
if (in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED)
|
||||
in_subs->exec_method= Item_in_subselect::MATERIALIZATION;
|
||||
|
||||
/*
|
||||
If the subquery is an AND-part of WHERE register for being processed
|
||||
with jtbm strategy
|
||||
*/
|
||||
if (in_subs->exec_method == Item_in_subselect::MATERIALIZATION &&
|
||||
thd->thd_marker.emb_on_expr_nest == NO_JOIN_NEST &&
|
||||
optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN))
|
||||
{
|
||||
in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
|
||||
in_subs->is_flattenable_semijoin= FALSE;
|
||||
select_lex->outer_select()->
|
||||
join->sj_subselects.append(thd->mem_root, in_subs);
|
||||
}
|
||||
}
|
||||
|
||||
Item_subselect::trans_res trans_res;
|
||||
|
@ -338,6 +517,69 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Finalize IN->EXISTS conversion in case we couldn't use materialization.
|
||||
|
||||
DESCRIPTION Invoke the IN->EXISTS converter
|
||||
Replace the Item_in_subselect with its wrapper Item_in_optimizer in WHERE.
|
||||
|
||||
RETURN
|
||||
FALSE - Ok
|
||||
TRUE - Fatal error
|
||||
*/
|
||||
|
||||
static
|
||||
bool make_in_exists_conversion(THD *thd, JOIN *join, Item_in_subselect *item)
|
||||
{
|
||||
DBUG_ENTER("make_in_exists_conversion");
|
||||
JOIN *child_join= item->unit->first_select()->join;
|
||||
Item_subselect::trans_res res;
|
||||
item->changed= 0;
|
||||
item->fixed= 0;
|
||||
|
||||
SELECT_LEX *save_select_lex= thd->lex->current_select;
|
||||
thd->lex->current_select= item->unit->first_select();
|
||||
|
||||
res= item->select_transformer(child_join);
|
||||
|
||||
thd->lex->current_select= save_select_lex;
|
||||
|
||||
if (res == Item_subselect::RES_ERROR)
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
item->changed= 1;
|
||||
item->fixed= 1;
|
||||
|
||||
Item *substitute= item->substitution;
|
||||
bool do_fix_fields= !item->substitution->fixed;
|
||||
/*
|
||||
The Item_subselect has already been wrapped with Item_in_optimizer, so we
|
||||
should search for item->optimizer, not 'item'.
|
||||
*/
|
||||
Item *replace_me= item->optimizer;
|
||||
DBUG_ASSERT(replace_me==substitute);
|
||||
|
||||
Item **tree= (item->emb_on_expr_nest == NO_JOIN_NEST)?
|
||||
&join->conds : &(item->emb_on_expr_nest->on_expr);
|
||||
if (replace_where_subcondition(join, tree, replace_me, substitute,
|
||||
do_fix_fields))
|
||||
DBUG_RETURN(TRUE);
|
||||
item->substitution= NULL;
|
||||
|
||||
if (!thd->stmt_arena->is_conventional())
|
||||
{
|
||||
tree= (item->emb_on_expr_nest == (TABLE_LIST*)NO_JOIN_NEST)?
|
||||
&join->select_lex->prep_where :
|
||||
&(item->emb_on_expr_nest->prep_on_expr);
|
||||
|
||||
if (replace_where_subcondition(join, tree, replace_me, substitute,
|
||||
FALSE))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert semi-join subquery predicates into semi-join join nests
|
||||
|
||||
|
@ -404,7 +646,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
|
|||
{
|
||||
st_select_lex *child_select= (*in_subq)->get_select_lex();
|
||||
JOIN *child_join= child_select->join;
|
||||
child_join->outer_tables = child_join->tables;
|
||||
child_join->outer_tables = child_join->table_count;
|
||||
|
||||
/*
|
||||
child_select->where contains only the WHERE predicate of the
|
||||
|
@ -445,25 +687,45 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
|
|||
// #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
|
||||
/* Replace all subqueries to be flattened with Item_int(1) */
|
||||
arena= thd->activate_stmt_arena_if_needed(&backup);
|
||||
for (in_subq= join->sj_subselects.front();
|
||||
in_subq != in_subq_end &&
|
||||
join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
|
||||
in_subq++)
|
||||
{
|
||||
Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
|
||||
&join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
|
||||
if (replace_where_subcondition(join, tree, *in_subq, new Item_int(1),
|
||||
FALSE))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
}
|
||||
|
||||
for (in_subq= join->sj_subselects.front();
|
||||
in_subq != in_subq_end &&
|
||||
join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES;
|
||||
in_subq != in_subq_end;
|
||||
in_subq++)
|
||||
{
|
||||
if (convert_subq_to_sj(join, *in_subq))
|
||||
DBUG_RETURN(TRUE);
|
||||
bool remove_item= TRUE;
|
||||
if ((*in_subq)->is_flattenable_semijoin)
|
||||
{
|
||||
if (join->table_count +
|
||||
(*in_subq)->unit->first_select()->join->table_count >= MAX_TABLES)
|
||||
break;
|
||||
if (convert_subq_to_sj(join, *in_subq))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (join->table_count + 1 >= MAX_TABLES)
|
||||
break;
|
||||
if (convert_subq_to_jtbm(join, *in_subq, &remove_item))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (remove_item)
|
||||
{
|
||||
Item **tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?
|
||||
&join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
|
||||
Item *replace_me= *in_subq;
|
||||
/*
|
||||
JTBM: the subquery was already mapped with Item_in_optimizer, so we
|
||||
should search for that, not for original Item_in_subselect.
|
||||
TODO: what about delaying that rewrite until here?
|
||||
*/
|
||||
if (!(*in_subq)->is_flattenable_semijoin)
|
||||
{
|
||||
replace_me= (*in_subq)->optimizer;
|
||||
}
|
||||
if (replace_where_subcondition(join, tree, replace_me, new Item_int(1),
|
||||
FALSE))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
}
|
||||
}
|
||||
skip_conversion:
|
||||
/*
|
||||
|
@ -492,20 +754,32 @@ skip_conversion:
|
|||
|
||||
Item *substitute= (*in_subq)->substitution;
|
||||
bool do_fix_fields= !(*in_subq)->substitution->fixed;
|
||||
Item **tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
|
||||
Item **tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?
|
||||
&join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
|
||||
if (replace_where_subcondition(join, tree, *in_subq, substitute,
|
||||
|
||||
Item *replace_me= *in_subq;
|
||||
/*
|
||||
JTBM: the subquery was already mapped with Item_in_optimizer, so we
|
||||
should search for that, not for original Item_in_subselect.
|
||||
TODO: what about delaying that rewrite until here?
|
||||
*/
|
||||
if (!(*in_subq)->is_flattenable_semijoin)
|
||||
{
|
||||
replace_me= (*in_subq)->optimizer;
|
||||
}
|
||||
|
||||
if (replace_where_subcondition(join, tree, replace_me, substitute,
|
||||
do_fix_fields))
|
||||
DBUG_RETURN(TRUE);
|
||||
(*in_subq)->substitution= NULL;
|
||||
|
||||
if (!thd->stmt_arena->is_conventional())
|
||||
{
|
||||
tree= ((*in_subq)->emb_on_expr_nest == (TABLE_LIST*)1)?
|
||||
tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?
|
||||
&join->select_lex->prep_where :
|
||||
&((*in_subq)->emb_on_expr_nest->prep_on_expr);
|
||||
|
||||
if (replace_where_subcondition(join, tree, *in_subq, substitute,
|
||||
if (replace_where_subcondition(join, tree, replace_me, substitute,
|
||||
FALSE))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
@ -517,6 +791,59 @@ skip_conversion:
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get #output_rows and scan_time estimates for a "delayed" table.
|
||||
|
||||
SYNOPSIS
|
||||
get_delayed_table_estimates()
|
||||
table IN Table to get estimates for
|
||||
out_rows OUT E(#rows in the table)
|
||||
scan_time OUT E(scan_time).
|
||||
startup_cost OUT cost to populate the table.
|
||||
|
||||
DESCRIPTION
|
||||
Get #output_rows and scan_time estimates for a "delayed" table. By
|
||||
"delayed" here we mean that the table is filled at the start of query
|
||||
execution. This means that the optimizer can't use table statistics to
|
||||
get #rows estimate for it, it has to call this function instead.
|
||||
|
||||
This function is expected to make different actions depending on the nature
|
||||
of the table. At the moment there is only one kind of delayed tables,
|
||||
non-flattenable semi-joins.
|
||||
*/
|
||||
|
||||
void get_delayed_table_estimates(TABLE *table,
|
||||
ha_rows *out_rows,
|
||||
double *scan_time,
|
||||
double *startup_cost)
|
||||
{
|
||||
Item_in_subselect *item= table->pos_in_table_list->jtbm_subselect;
|
||||
item->optimize();
|
||||
|
||||
DBUG_ASSERT(item->engine->engine_type() ==
|
||||
subselect_engine::HASH_SJ_ENGINE);
|
||||
|
||||
subselect_hash_sj_engine *hash_sj_engine=
|
||||
((subselect_hash_sj_engine*)item->engine);
|
||||
JOIN *join= hash_sj_engine->materialize_join;
|
||||
|
||||
double rows;
|
||||
double read_time;
|
||||
|
||||
/* Calculate #rows and cost of join execution */
|
||||
get_partial_join_cost(join, join->table_count - join->const_tables,
|
||||
&read_time, &rows);
|
||||
|
||||
*out_rows= (ha_rows)rows;
|
||||
*startup_cost= read_time;
|
||||
/* Calculate cost of scanning the temptable */
|
||||
double data_size= rows * hash_sj_engine->tmp_table->s->reclength;
|
||||
/* Do like in handler::read_time */
|
||||
*scan_time= data_size/IO_SIZE + 2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Replaces an expression destructively inside the expression tree of
|
||||
the WHERE clase.
|
||||
|
@ -534,6 +861,7 @@ skip_conversion:
|
|||
@return <code>true</code> if there was an error, <code>false</code> if
|
||||
successful.
|
||||
*/
|
||||
|
||||
static bool replace_where_subcondition(JOIN *join, Item **expr,
|
||||
Item *old_cond, Item *new_cond,
|
||||
bool do_fix_fields)
|
||||
|
@ -615,9 +943,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||
1. Find out where to put the predicate into.
|
||||
Note: for "t1 LEFT JOIN t2" this will be t2, a leaf.
|
||||
*/
|
||||
if ((void*)subq_pred->expr_join_nest != (void*)1)
|
||||
if ((void*)subq_pred->emb_on_expr_nest != (void*)NO_JOIN_NEST)
|
||||
{
|
||||
if (subq_pred->expr_join_nest->nested_join)
|
||||
if (subq_pred->emb_on_expr_nest->nested_join)
|
||||
{
|
||||
/*
|
||||
We're dealing with
|
||||
|
@ -626,10 +954,10 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||
|
||||
The sj-nest will be inserted into the brackets nest.
|
||||
*/
|
||||
emb_tbl_nest= subq_pred->expr_join_nest;
|
||||
emb_tbl_nest= subq_pred->emb_on_expr_nest;
|
||||
emb_join_list= &emb_tbl_nest->nested_join->join_list;
|
||||
}
|
||||
else if (!subq_pred->expr_join_nest->outer_join)
|
||||
else if (!subq_pred->emb_on_expr_nest->outer_join)
|
||||
{
|
||||
/*
|
||||
We're dealing with
|
||||
|
@ -639,13 +967,13 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||
The sj-nest will be tblX's "sibling", i.e. another child of its
|
||||
parent. This is ok because tblX is joined as an inner join.
|
||||
*/
|
||||
emb_tbl_nest= subq_pred->expr_join_nest->embedding;
|
||||
emb_tbl_nest= subq_pred->emb_on_expr_nest->embedding;
|
||||
if (emb_tbl_nest)
|
||||
emb_join_list= &emb_tbl_nest->nested_join->join_list;
|
||||
}
|
||||
else if (!subq_pred->expr_join_nest->nested_join)
|
||||
else if (!subq_pred->emb_on_expr_nest->nested_join)
|
||||
{
|
||||
TABLE_LIST *outer_tbl= subq_pred->expr_join_nest;
|
||||
TABLE_LIST *outer_tbl= subq_pred->emb_on_expr_nest;
|
||||
TABLE_LIST *wrap_nest;
|
||||
/*
|
||||
We're dealing with
|
||||
|
@ -769,12 +1097,11 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||
/* 3. Remove the original subquery predicate from the WHERE/ON */
|
||||
|
||||
// The subqueries were replaced for Item_int(1) earlier
|
||||
subq_pred->exec_method=
|
||||
Item_in_subselect::SEMI_JOIN; // for subsequent executions
|
||||
subq_pred->exec_method= Item_in_subselect::SEMI_JOIN; // for subsequent executions
|
||||
/*TODO: also reset the 'with_subselect' there. */
|
||||
|
||||
/* n. Adjust the parent_join->tables counter */
|
||||
uint table_no= parent_join->tables;
|
||||
/* n. Adjust the parent_join->table_count counter */
|
||||
uint table_no= parent_join->table_count;
|
||||
/* n. Walk through child's tables and adjust table->map */
|
||||
for (tl= subq_lex->leaf_tables; tl; tl= tl->next_leaf, table_no++)
|
||||
{
|
||||
|
@ -787,7 +1114,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||
emb= emb->embedding)
|
||||
emb->select_lex= parent_join->select_lex;
|
||||
}
|
||||
parent_join->tables += subq_lex->join->tables;
|
||||
parent_join->table_count += subq_lex->join->table_count;
|
||||
|
||||
/*
|
||||
Put the subquery's WHERE into semi-join's sj_on_expr
|
||||
|
@ -887,6 +1214,133 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
const int SUBQERY_TEMPTABLE_NAME_MAX_LEN= 20;
|
||||
|
||||
static void create_subquery_temptable_name(char *to, uint number)
|
||||
{
|
||||
DBUG_ASSERT(number < 10000);
|
||||
to= strmov(to, "<subquery");
|
||||
to= int10_to_str((int) number, to, 10);
|
||||
to[0]= '>';
|
||||
to[1]= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Convert subquery predicate into non-mergeable semi-join nest.
|
||||
|
||||
TODO:
|
||||
why does this do IN-EXISTS conversion? Can't we unify it with mergeable
|
||||
semi-joins? currently, convert_subq_to_sj() cannot fail to convert (unless
|
||||
fatal errors)
|
||||
|
||||
|
||||
RETURN
|
||||
FALSE - Ok
|
||||
TRUE - Fatal error
|
||||
*/
|
||||
|
||||
static bool convert_subq_to_jtbm(JOIN *parent_join,
|
||||
Item_in_subselect *subq_pred,
|
||||
bool *remove_item)
|
||||
{
|
||||
SELECT_LEX *parent_lex= parent_join->select_lex;
|
||||
List<TABLE_LIST> *emb_join_list= &parent_lex->top_join_list;
|
||||
TABLE_LIST *emb_tbl_nest= NULL; // will change when we learn to handle outer joins
|
||||
TABLE_LIST *tl;
|
||||
DBUG_ENTER("convert_subq_to_jtbm");
|
||||
|
||||
if (subq_pred->setup_engine(TRUE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (subq_pred->engine->engine_type() != subselect_engine::HASH_SJ_ENGINE)
|
||||
{
|
||||
*remove_item= FALSE;
|
||||
bool res;
|
||||
res= make_in_exists_conversion(parent_join->thd, parent_join, subq_pred);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
*remove_item= TRUE;
|
||||
|
||||
TABLE_LIST *jtbm;
|
||||
char *tbl_alias;
|
||||
if (!(tbl_alias= (char*)parent_join->thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) ||
|
||||
!(jtbm= alloc_join_nest(parent_join->thd))) //todo: this is not a join nest!
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
jtbm->join_list= emb_join_list;
|
||||
jtbm->embedding= emb_tbl_nest;
|
||||
jtbm->jtbm_subselect= subq_pred;
|
||||
jtbm->nested_join= NULL;
|
||||
|
||||
/* Nests do not participate in those 'chains', so: */
|
||||
/* jtbm->next_leaf= jtbm->next_local= jtbm->next_global == NULL*/
|
||||
emb_join_list->push_back(jtbm);
|
||||
|
||||
/*
|
||||
Inject the jtbm table into TABLE_LIST::next_leaf list, so that
|
||||
make_join_statistics() and co. can find it.
|
||||
*/
|
||||
for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf)
|
||||
{}
|
||||
tl->next_leaf= jtbm;
|
||||
|
||||
/*
|
||||
Same as above for TABLE_LIST::next_local chain
|
||||
(a theory: a next_local chain always starts with ::leaf_tables
|
||||
because view's tables are inserted after the view)
|
||||
*/
|
||||
for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local)
|
||||
{}
|
||||
tl->next_local= jtbm;
|
||||
|
||||
/* A theory: no need to re-connect the next_global chain */
|
||||
|
||||
subselect_hash_sj_engine *hash_sj_engine=
|
||||
((subselect_hash_sj_engine*)subq_pred->engine);
|
||||
jtbm->table= hash_sj_engine->tmp_table;
|
||||
|
||||
jtbm->table->tablenr= parent_join->table_count;
|
||||
jtbm->table->map= table_map(1) << (parent_join->table_count);
|
||||
|
||||
parent_join->table_count++;
|
||||
DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
|
||||
|
||||
Item *conds= hash_sj_engine->semi_join_conds;
|
||||
conds->fix_after_pullout(parent_lex, &conds);
|
||||
|
||||
DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY););
|
||||
|
||||
create_subquery_temptable_name(tbl_alias, hash_sj_engine->materialize_join->
|
||||
select_lex->select_number);
|
||||
jtbm->alias= tbl_alias;
|
||||
|
||||
/* Inject sj_on_expr into the parent's WHERE or ON */
|
||||
if (emb_tbl_nest)
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
/*emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
|
||||
sj_nest->sj_on_expr);
|
||||
emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Inject into the WHERE */
|
||||
parent_join->conds= and_items(parent_join->conds, conds);
|
||||
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
|
||||
parent_join->select_lex->where= parent_join->conds;
|
||||
}
|
||||
|
||||
/* Don't unlink the child subselect, as the subquery will be used. */
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
static TABLE_LIST *alloc_join_nest(THD *thd)
|
||||
{
|
||||
TABLE_LIST *tbl;
|
||||
|
@ -1245,6 +1699,7 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
|
|||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get estimated record length for semi-join materialization temptable
|
||||
|
||||
|
@ -1301,7 +1756,7 @@ static uint get_tmp_table_rec_length(List<Item> &items)
|
|||
return len;
|
||||
}
|
||||
|
||||
//psergey-todo: is the below a kind of table elimination??
|
||||
|
||||
/*
|
||||
Check if table's KEYUSE elements have an eq_ref(outer_tables) candidate
|
||||
|
||||
|
@ -1318,6 +1773,8 @@ static uint get_tmp_table_rec_length(List<Item> &items)
|
|||
Check again if it is feasible to factor common parts with constant table
|
||||
search
|
||||
|
||||
Also check if it's feasible to factor common parts with table elimination
|
||||
|
||||
RETURN
|
||||
TRUE - There exists an eq_ref(outer-tables) candidate
|
||||
FALSE - Otherwise
|
||||
|
@ -1368,6 +1825,7 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Do semi-join optimization step after we've added a new tab to join prefix
|
||||
|
||||
|
@ -2024,7 +2482,7 @@ at_sjmat_pos(const JOIN *join, table_map remaining_tables, const JOIN_TAB *tab,
|
|||
|
||||
void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
||||
{
|
||||
uint table_count=join->tables;
|
||||
uint table_count=join->table_count;
|
||||
uint tablenr;
|
||||
table_map remaining_tables= 0;
|
||||
table_map handled_tabs= 0;
|
||||
|
@ -2188,6 +2646,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Setup semi-join materialization strategy for one semi-join nest
|
||||
|
||||
|
@ -2209,10 +2668,11 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
|
|||
TRUE Error
|
||||
*/
|
||||
|
||||
bool setup_sj_materialization(JOIN_TAB *tab)
|
||||
bool setup_sj_materialization(JOIN_TAB *sjm_tab)
|
||||
{
|
||||
uint i;
|
||||
DBUG_ENTER("setup_sj_materialization");
|
||||
JOIN_TAB *tab= sjm_tab->bush_children->start;
|
||||
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
|
||||
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
|
||||
THD *thd= tab->join->thd;
|
||||
|
@ -2240,10 +2700,13 @@ bool setup_sj_materialization(JOIN_TAB *tab)
|
|||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
sjm->table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
sjm->table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
|
||||
tab->join->sj_tmp_tables.push_back(sjm->table);
|
||||
tab->join->sjm_info_list.push_back(sjm);
|
||||
|
||||
sjm->materialized= FALSE;
|
||||
sjm_tab->table= sjm->table;
|
||||
|
||||
if (!sjm->is_sj_scan)
|
||||
{
|
||||
KEY *tmp_key; /* The only index on the temporary table. */
|
||||
|
@ -2256,8 +2719,7 @@ bool setup_sj_materialization(JOIN_TAB *tab)
|
|||
temptable.
|
||||
*/
|
||||
TABLE_REF *tab_ref;
|
||||
if (!(tab_ref= (TABLE_REF*) thd->alloc(sizeof(TABLE_REF))))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
tab_ref= &sjm_tab->ref;
|
||||
tab_ref->key= 0; /* The only temp table index. */
|
||||
tab_ref->key_length= tmp_key->key_length;
|
||||
if (!(tab_ref->key_buff=
|
||||
|
@ -2290,12 +2752,22 @@ bool setup_sj_materialization(JOIN_TAB *tab)
|
|||
use that information instead.
|
||||
*/
|
||||
cur_ref_buff + null_count,
|
||||
null_count ? tab_ref->key_buff : 0,
|
||||
null_count ? cur_ref_buff : 0,
|
||||
cur_key_part->length, tab_ref->items[i],
|
||||
FALSE);
|
||||
cur_ref_buff+= cur_key_part->store_length;
|
||||
}
|
||||
*ref_key= NULL; /* End marker. */
|
||||
|
||||
/*
|
||||
We don't ever have guarded conditions for SJM tables, but code at SQL
|
||||
layer depends on cond_guards array being alloced.
|
||||
*/
|
||||
if (!(tab_ref->cond_guards= (bool**) thd->calloc(sizeof(uint*)*tmp_key_parts)))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
tab_ref->key_err= 1;
|
||||
tab_ref->key_parts= tmp_key_parts;
|
||||
sjm->tab_ref= tab_ref;
|
||||
|
@ -2315,6 +2787,8 @@ bool setup_sj_materialization(JOIN_TAB *tab)
|
|||
if (!(sjm->in_equality= create_subq_in_equalities(thd, sjm,
|
||||
emb_sj_nest->sj_subq_pred)))
|
||||
DBUG_RETURN(TRUE); /* purecov: inspected */
|
||||
sjm_tab->type= JT_EQ_REF;
|
||||
sjm_tab->select_cond= sjm->in_equality;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2367,9 +2841,11 @@ bool setup_sj_materialization(JOIN_TAB *tab)
|
|||
then substitute_for_best_equal_field() will change the conditions
|
||||
according to the join order:
|
||||
|
||||
it1
|
||||
it2 it1.col=it2.col
|
||||
ot cond(it1.col)
|
||||
table | attached condition
|
||||
------+--------------------
|
||||
it1 |
|
||||
it2 | it1.col=it2.col
|
||||
ot | cond(it1.col)
|
||||
|
||||
although we've originally had "SELECT it2.col", conditions attached
|
||||
to subsequent outer tables will refer to it1.col, so SJM-Scan will
|
||||
|
@ -2398,8 +2874,18 @@ bool setup_sj_materialization(JOIN_TAB *tab)
|
|||
/* The write_set for source tables must be set up to allow the copying */
|
||||
bitmap_set_bit(copy_to->table->write_set, copy_to->field_index);
|
||||
}
|
||||
sjm_tab->type= JT_ALL;
|
||||
|
||||
/* Initialize full scan */
|
||||
sjm_tab->read_first_record= join_read_record_no_init;
|
||||
sjm_tab->read_record.copy_field= sjm->copy_field;
|
||||
sjm_tab->read_record.copy_field_end= sjm->copy_field +
|
||||
sjm->sjm_table_cols.elements;
|
||||
sjm_tab->read_record.read_record= rr_sequential_and_unpack;
|
||||
}
|
||||
|
||||
sjm_tab->bush_children->end[-1].next_select= end_sj_materialize;
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
@ -3020,6 +3506,7 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
|
|||
FALSE OK
|
||||
TRUE Out of memory error
|
||||
*/
|
||||
JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls);
|
||||
|
||||
int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
|
||||
uint no_jbuf_after)
|
||||
|
@ -3027,17 +3514,19 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
|
|||
uint i;
|
||||
THD *thd= join->thd;
|
||||
DBUG_ENTER("setup_semijoin_dups_elimination");
|
||||
|
||||
for (i= join->const_tables ; i < join->tables; )
|
||||
|
||||
POSITION *pos= join->best_positions + join->const_tables;
|
||||
for (i= join->const_tables ; i < join->top_join_tab_count; )
|
||||
{
|
||||
JOIN_TAB *tab=join->join_tab + i;
|
||||
POSITION *pos= join->best_positions + i;
|
||||
//POSITION *pos= join->best_positions + i;
|
||||
uint keylen, keyno;
|
||||
switch (pos->sj_strategy) {
|
||||
case SJ_OPT_MATERIALIZE:
|
||||
case SJ_OPT_MATERIALIZE_SCAN:
|
||||
/* Do nothing */
|
||||
i+= pos->n_sj_tables;
|
||||
i+= 1;// It used to be pos->n_sj_tables, but now they are embedded in a nest
|
||||
pos += pos->n_sj_tables;
|
||||
break;
|
||||
case SJ_OPT_LOOSE_SCAN:
|
||||
{
|
||||
|
@ -3054,6 +3543,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
|
|||
if (pos->n_sj_tables > 1)
|
||||
tab[pos->n_sj_tables - 1].do_firstmatch= tab;
|
||||
i+= pos->n_sj_tables;
|
||||
pos+= pos->n_sj_tables;
|
||||
break;
|
||||
}
|
||||
case SJ_OPT_DUPS_WEEDOUT:
|
||||
|
@ -3151,6 +3641,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
|
|||
join->join_tab[i + pos->n_sj_tables - 1].check_weed_out_table= sjtbl;
|
||||
|
||||
i+= pos->n_sj_tables;
|
||||
pos+= pos->n_sj_tables;
|
||||
break;
|
||||
}
|
||||
case SJ_OPT_FIRST_MATCH:
|
||||
|
@ -3173,10 +3664,12 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
|
|||
}
|
||||
j[-1].do_firstmatch= jump_to;
|
||||
i+= pos->n_sj_tables;
|
||||
pos+= pos->n_sj_tables;
|
||||
break;
|
||||
}
|
||||
case SJ_OPT_NONE:
|
||||
i++;
|
||||
pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3363,7 +3856,7 @@ int rewrite_to_index_subquery_engine(JOIN *join)
|
|||
if (!join->group_list && !join->order &&
|
||||
join->unit->item &&
|
||||
join->unit->item->substype() == Item_subselect::IN_SUBS &&
|
||||
join->tables == 1 && join->conds &&
|
||||
join->table_count == 1 && join->conds &&
|
||||
!join->unit->is_union())
|
||||
{
|
||||
if (!join->having)
|
||||
|
@ -3500,3 +3993,77 @@ static void remove_subq_pushed_predicates(JOIN *join, Item **where)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Join tab execution startup function.
|
||||
|
||||
SYNOPSIS
|
||||
join_tab_execution_startup()
|
||||
tab Join tab to perform startup actions for
|
||||
|
||||
DESCRIPTION
|
||||
Join tab execution startup function. This is different from
|
||||
tab->read_first_record in the regard that this has actions that are to be
|
||||
done once per join execution.
|
||||
|
||||
Currently there are only two possible startup functions, so we have them
|
||||
both here inside if (...) branches. In future we could switch to function
|
||||
pointers.
|
||||
|
||||
RETURN
|
||||
NESTED_LOOP_OK - OK
|
||||
NESTED_LOOP_ERROR| NESTED_LOOP_KILLED - Error, abort the join execution
|
||||
*/
|
||||
|
||||
enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab)
|
||||
{
|
||||
Item_in_subselect *in_subs;
|
||||
DBUG_ENTER("join_tab_execution_startup");
|
||||
|
||||
if (tab->table->pos_in_table_list &&
|
||||
(in_subs= tab->table->pos_in_table_list->jtbm_subselect))
|
||||
{
|
||||
/* It's a non-merged SJM nest */
|
||||
DBUG_ASSERT(in_subs->engine->engine_type() ==
|
||||
subselect_engine::HASH_SJ_ENGINE);
|
||||
|
||||
subselect_hash_sj_engine *hash_sj_engine=
|
||||
((subselect_hash_sj_engine*)in_subs->engine);
|
||||
if (!hash_sj_engine->is_materialized)
|
||||
{
|
||||
hash_sj_engine->materialize_join->exec();
|
||||
hash_sj_engine->is_materialized= TRUE;
|
||||
|
||||
if (hash_sj_engine->materialize_join->error || tab->join->thd->is_fatal_error)
|
||||
DBUG_RETURN(NESTED_LOOP_ERROR);
|
||||
}
|
||||
}
|
||||
else if (tab->bush_children)
|
||||
{
|
||||
/* It's a merged SJM nest */
|
||||
enum_nested_loop_state rc;
|
||||
SJ_MATERIALIZATION_INFO *sjm= tab->bush_children->start->emb_sj_nest->sj_mat_info;
|
||||
|
||||
if (!sjm->materialized)
|
||||
{
|
||||
JOIN *join= tab->join;
|
||||
JOIN_TAB *join_tab= tab->bush_children->start;
|
||||
JOIN_TAB *save_return_tab= join->return_tab;
|
||||
/*
|
||||
Now run the join for the inner tables. The first call is to run the
|
||||
join, the second one is to signal EOF (this is essential for some
|
||||
join strategies, e.g. it will make join buffering flush the records)
|
||||
*/
|
||||
if ((rc= sub_select(join, join_tab, FALSE/* no EOF */)) < 0 ||
|
||||
(rc= sub_select(join, join_tab, TRUE/* now EOF */)) < 0)
|
||||
{
|
||||
join->return_tab= save_return_tab;
|
||||
DBUG_RETURN(rc); /* it's NESTED_LOOP_(ERROR|KILLED)*/
|
||||
}
|
||||
join->return_tab= save_return_tab;
|
||||
sjm->materialized= TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(NESTED_LOOP_OK);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
/* */
|
||||
/*
|
||||
Semi-join subquery optimization code definitions
|
||||
*/
|
||||
|
||||
#ifdef USE_PRAGMA_INTERFACE
|
||||
#pragma interface /* gcc class implementation */
|
||||
|
@ -366,4 +368,10 @@ int clear_sj_tmp_tables(JOIN *join);
|
|||
int rewrite_to_index_subquery_engine(JOIN *join);
|
||||
|
||||
|
||||
void get_delayed_table_estimates(TABLE *table,
|
||||
ha_rows *out_rows,
|
||||
double *scan_time,
|
||||
double *startup_cost);
|
||||
|
||||
enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab);
|
||||
|
||||
|
|
|
@ -7797,6 +7797,18 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||
if (res)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (table_list->jtbm_subselect)
|
||||
{
|
||||
Item *item= table_list->jtbm_subselect;
|
||||
if (item->fix_fields(thd, &item))
|
||||
{
|
||||
my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); /* psergey-todo: WHY ER_TOO_MANY_TABLES ???*/
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_ASSERT(item == table_list->jtbm_subselect);
|
||||
if (table_list->jtbm_subselect->setup_engine(FALSE))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Precompute and store the row types of NATURAL/USING joins. */
|
||||
|
@ -8195,7 +8207,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
|
|||
goto err_no_arena;
|
||||
}
|
||||
|
||||
thd->thd_marker.emb_on_expr_nest= (TABLE_LIST*)1;
|
||||
thd->thd_marker.emb_on_expr_nest= NO_JOIN_NEST;
|
||||
if (*conds)
|
||||
{
|
||||
thd->where="where clause";
|
||||
|
|
|
@ -381,14 +381,14 @@ Sensitive_cursor::open(JOIN *join_arg)
|
|||
|
||||
/* Prepare JOIN for reading rows. */
|
||||
join->tmp_table= 0;
|
||||
join->join_tab[join->tables-1].next_select= setup_end_select_func(join);
|
||||
join->join_tab[join->top_join_tab_count - 1].next_select= setup_end_select_func(join);
|
||||
join->send_records= 0;
|
||||
join->fetch_limit= join->unit->offset_limit_cnt;
|
||||
|
||||
/* Disable JOIN CACHE as it is not working with cursors yet */
|
||||
for (JOIN_TAB *tab= join_tab;
|
||||
tab != join->join_tab + join->tables - 1;
|
||||
tab++)
|
||||
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
|
||||
tab != join->join_tab + join->top_join_tab_count - 1;
|
||||
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
|
||||
{
|
||||
if (tab->next_select == sub_select_cache)
|
||||
tab->next_select= sub_select;
|
||||
|
|
|
@ -677,9 +677,10 @@ multi_delete::initialize_tables(JOIN *join)
|
|||
|
||||
|
||||
walk= delete_tables;
|
||||
for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
|
||||
tab < end;
|
||||
tab++)
|
||||
|
||||
for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
|
||||
tab;
|
||||
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
|
||||
{
|
||||
if (tab->table->map & tables_to_delete_from)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#define NO_MORE_RECORDS_IN_BUFFER (uint)(-1)
|
||||
|
||||
static void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save);
|
||||
|
||||
/*****************************************************************************
|
||||
* Join cache module
|
||||
|
@ -138,52 +139,6 @@ uint add_table_data_fields_to_join_cache(JOIN_TAB *tab,
|
|||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
Get the next table whose records are stored in the join buffer of this cache
|
||||
|
||||
SYNOPSIS
|
||||
get_next_table()
|
||||
tab the table for which the next table is to be returned
|
||||
|
||||
DESCRIPTION
|
||||
For a given table whose records are stored in this cache the function
|
||||
returns the next such table if there is any.
|
||||
The function takes into account that the tables whose records are
|
||||
are stored in the same cache now can interleave with tables from
|
||||
materialized semijoin subqueries.
|
||||
|
||||
TODO
|
||||
This function should be modified/simplified after the new code for
|
||||
materialized semijoins is merged.
|
||||
|
||||
RETURN
|
||||
The next join table whose records are stored in the buffer of this cache
|
||||
if such table exists, 0 - otherwise
|
||||
*/
|
||||
|
||||
JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab)
|
||||
{
|
||||
|
||||
if (++tab == join_tab)
|
||||
return NULL;
|
||||
if (join_tab->first_sjm_sibling)
|
||||
return 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) &&
|
||||
i < join->tables)
|
||||
i+= join->best_positions[i].n_sj_tables;
|
||||
|
||||
*/
|
||||
return join->join_tab+i < join_tab ? join->join_tab+i : NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Determine different counters of fields associated with a record in the cache
|
||||
|
||||
|
@ -203,12 +158,55 @@ JOIN_TAB *JOIN_CACHE::get_next_table(JOIN_TAB *tab)
|
|||
|
||||
void JOIN_CACHE::calc_record_fields()
|
||||
{
|
||||
JOIN_TAB *tab = prev_cache ? prev_cache->join_tab :
|
||||
(join_tab->first_sjm_sibling ?
|
||||
join_tab->first_sjm_sibling :
|
||||
join->join_tab+join->const_tables);
|
||||
tables= join_tab-tab;
|
||||
JOIN_TAB *tab;
|
||||
|
||||
if (prev_cache)
|
||||
tab= prev_cache->join_tab;
|
||||
else
|
||||
{
|
||||
if (join_tab->bush_root_tab)
|
||||
{
|
||||
/*
|
||||
--ot1--SJM1--------------ot2--...
|
||||
|
|
||||
|
|
||||
+-it1--...--itN
|
||||
^____________ this->join_tab is somewhere here,
|
||||
inside an sjm nest.
|
||||
|
||||
The join buffer should store the values of it1.*, it2.*, ..
|
||||
It should not store values of ot1.*.
|
||||
*/
|
||||
tab= join_tab->bush_root_tab->bush_children->start;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
-ot1--ot2--SJM1--SJM2--------------ot3--...--otN
|
||||
| | ^
|
||||
| +-it21--...--it2N |
|
||||
| \-- we're somewhere here,
|
||||
+-it11--...--it1N at the top level
|
||||
|
||||
The join buffer should store the values of
|
||||
|
||||
ot1.*, ot2.*, it1{i}, it2{j}.*, ot3.*, ...
|
||||
|
||||
that is, we should start from the first non-const top-level table.
|
||||
|
||||
We will need to store columns of SJ-inner tables (it_X_Y.*), but we're
|
||||
not interested in storing the columns of materialization tables
|
||||
themselves. Beause of that, if the first non-const top-level table is a
|
||||
materialized table, we move to its bush_children:
|
||||
*/
|
||||
tab= join->join_tab + join->const_tables;
|
||||
if (tab->bush_children)
|
||||
tab= tab->bush_children->start;
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(!tab->bush_children);
|
||||
|
||||
start_tab= tab;
|
||||
fields= 0;
|
||||
blobs= 0;
|
||||
flag_fields= 0;
|
||||
|
@ -216,7 +214,11 @@ void JOIN_CACHE::calc_record_fields()
|
|||
data_field_ptr_count= 0;
|
||||
referenced_fields= 0;
|
||||
|
||||
for ( ; tab ; tab= get_next_table(tab))
|
||||
/*
|
||||
The following loop will get inside SJM nests, because data may be unpacked
|
||||
to sjm-inner tables.
|
||||
*/
|
||||
for (; tab != join_tab ; tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
tab->calc_used_field_length(FALSE);
|
||||
flag_fields+= test(tab->used_null_fields || tab->used_uneven_bit_fields);
|
||||
|
@ -245,7 +247,8 @@ void JOIN_CACHE::calc_record_fields()
|
|||
that occur in the ref expressions and marks these fields in the bitmap
|
||||
tab->table->tmp_set. The function counts the number of them stored
|
||||
in this cache and the total number of them stored in the previous caches
|
||||
and saves the results of the counting in 'local_key_arg_fields' and 'external_key_arg_fields' respectively.
|
||||
and saves the results of the counting in 'local_key_arg_fields' and
|
||||
'external_key_arg_fields' respectively.
|
||||
|
||||
NOTES
|
||||
The function does not do anything if no key is used to join the records
|
||||
|
@ -269,8 +272,8 @@ void JOIN_CACHE::collect_info_on_key_args()
|
|||
cache= this;
|
||||
do
|
||||
{
|
||||
for (tab= cache->join_tab-cache->tables; tab ;
|
||||
tab= cache->get_next_table(tab))
|
||||
for (tab= cache->start_tab; tab != cache->join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
uint key_args;
|
||||
bitmap_clear_all(&tab->table->tmp_set);
|
||||
|
@ -386,7 +389,8 @@ void JOIN_CACHE::create_flag_fields()
|
|||
©);
|
||||
|
||||
/* Create fields for all null bitmaps and null row flags that are needed */
|
||||
for (tab= join_tab-tables; tab; tab= get_next_table(tab))
|
||||
for (tab= start_tab; tab != join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
TABLE *table= tab->table;
|
||||
|
||||
|
@ -473,8 +477,8 @@ void JOIN_CACHE::create_key_arg_fields()
|
|||
while (ext_key_arg_cnt)
|
||||
{
|
||||
cache= cache->prev_cache;
|
||||
for (tab= cache->join_tab-cache->tables; tab;
|
||||
tab= cache->get_next_table(tab))
|
||||
for (tab= cache->start_tab; tab != cache->join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
CACHE_FIELD *copy_end;
|
||||
MY_BITMAP *key_read_set= &tab->table->tmp_set;
|
||||
|
@ -524,7 +528,8 @@ void JOIN_CACHE::create_key_arg_fields()
|
|||
|
||||
/* Now create local fields that are used to build ref for this key access */
|
||||
copy= field_descr+flag_fields;
|
||||
for (tab= join_tab-tables; tab; tab= get_next_table(tab))
|
||||
for (tab= start_tab; tab != join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
length+= add_table_data_fields_to_join_cache(tab, &tab->table->tmp_set,
|
||||
&data_field_count, ©,
|
||||
|
@ -573,14 +578,15 @@ void JOIN_CACHE::create_key_arg_fields()
|
|||
none
|
||||
*/
|
||||
|
||||
void JOIN_CACHE:: create_remaining_fields()
|
||||
void JOIN_CACHE::create_remaining_fields()
|
||||
{
|
||||
JOIN_TAB *tab;
|
||||
bool all_read_fields= !is_key_access();
|
||||
CACHE_FIELD *copy= field_descr+flag_fields+data_field_count;
|
||||
CACHE_FIELD **copy_ptr= blob_ptr+data_field_ptr_count;
|
||||
|
||||
for (tab= join_tab-tables; tab; tab= get_next_table(tab))
|
||||
for (tab= start_tab; tab != join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
MY_BITMAP *rem_field_set;
|
||||
TABLE *table= tab->table;
|
||||
|
@ -737,8 +743,11 @@ ulong JOIN_CACHE::get_min_join_buffer_size()
|
|||
if (!min_buff_size)
|
||||
{
|
||||
size_t len= 0;
|
||||
for (JOIN_TAB *tab= join_tab-tables; tab < join_tab; tab++)
|
||||
for (JOIN_TAB *tab= start_tab; tab != join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
len+= tab->get_max_used_fieldlength();
|
||||
}
|
||||
len+= get_record_max_affix_length() + get_max_key_addon_space_per_record();
|
||||
size_t min_sz= len*min_records;
|
||||
size_t add_sz= 0;
|
||||
|
@ -790,8 +799,11 @@ ulong JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
|
|||
size_t max_sz;
|
||||
size_t min_sz= get_min_join_buffer_size();
|
||||
size_t len= 0;
|
||||
for (JOIN_TAB *tab= join_tab-tables; tab < join_tab; tab++)
|
||||
for (JOIN_TAB *tab= start_tab; tab != join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
len+= tab->get_used_fieldlength();
|
||||
}
|
||||
len+= get_record_max_affix_length();
|
||||
avg_record_length= len;
|
||||
len+= get_max_key_addon_space_per_record() + avg_aux_buffer_incr;
|
||||
|
@ -865,7 +877,9 @@ int JOIN_CACHE::alloc_buffer()
|
|||
set_if_bigger(max_records, 10);
|
||||
min_buff_size= get_min_join_buffer_size();
|
||||
buff_size= get_max_join_buffer_size(optimize_buff_size);
|
||||
for (tab= join->join_tab+join->const_tables; tab <= join_tab; tab++)
|
||||
|
||||
for (tab= start_tab; tab!= join_tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
cache= tab->cache;
|
||||
if (cache)
|
||||
|
@ -2154,10 +2168,19 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
|
|||
join_tab->select->quick= 0;
|
||||
}
|
||||
|
||||
/* Prepare to retrieve all records of the joined table */
|
||||
if ((error= join_tab_scan->open()))
|
||||
goto finish; /* psergey-note: if this returns error, we will assert in net_send_statement() */
|
||||
if ((rc= join_tab_execution_startup(join_tab)) < 0)
|
||||
goto finish2;
|
||||
|
||||
/* Prepare to retrieve all records of the joined table */
|
||||
if ((error= join_tab_scan->open()))
|
||||
{
|
||||
/*
|
||||
TODO: if we get here, we will assert in net_send_statement(). Add test
|
||||
coverage and fix.
|
||||
*/
|
||||
goto finish;
|
||||
}
|
||||
|
||||
while (!(error= join_tab_scan->next()))
|
||||
{
|
||||
if (join->thd->killed)
|
||||
|
@ -2199,6 +2222,7 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
|
|||
finish:
|
||||
if (error)
|
||||
rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
|
||||
finish2:
|
||||
join_tab_scan->close();
|
||||
return rc;
|
||||
}
|
||||
|
@ -3191,12 +3215,7 @@ uint JOIN_CACHE_HASHED::get_next_key(uchar ** key)
|
|||
|
||||
int JOIN_TAB_SCAN::open()
|
||||
{
|
||||
JOIN_TAB *bound= join_tab-cache->tables;
|
||||
for (JOIN_TAB *tab= join_tab-1; tab != bound && !tab->cache; tab--)
|
||||
{
|
||||
tab->status= tab->table->status;
|
||||
tab->table->status= 0;
|
||||
}
|
||||
save_or_restore_used_tabs(join_tab, FALSE);
|
||||
is_first_record= TRUE;
|
||||
return join_init_read_record(join_tab);
|
||||
}
|
||||
|
@ -3251,6 +3270,49 @@ int JOIN_TAB_SCAN::next()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Walk back in join order from join_tab until we encounter a join tab with
|
||||
tab->cache!=NULL, and save/restore tab->table->status along the way.
|
||||
|
||||
@param save TRUE save
|
||||
FALSE restore
|
||||
*/
|
||||
|
||||
static void save_or_restore_used_tabs(JOIN_TAB *join_tab, bool save)
|
||||
{
|
||||
JOIN_TAB *first= join_tab->bush_root_tab?
|
||||
join_tab->bush_root_tab->bush_children->start :
|
||||
join_tab->join->join_tab + join_tab->join->const_tables;
|
||||
|
||||
for (JOIN_TAB *tab= join_tab-1; tab != first && !tab->cache; tab--)
|
||||
{
|
||||
if (tab->bush_children)
|
||||
{
|
||||
for (JOIN_TAB *child= tab->bush_children->start;
|
||||
child != tab->bush_children->end;
|
||||
child++)
|
||||
{
|
||||
if (save)
|
||||
child->table->status= child->status;
|
||||
else
|
||||
{
|
||||
tab->status= tab->table->status;
|
||||
tab->table->status= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (save)
|
||||
tab->table->status= tab->status;
|
||||
else
|
||||
{
|
||||
tab->status= tab->table->status;
|
||||
tab->table->status= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Perform finalizing actions for a scan over the table records
|
||||
|
||||
|
@ -3267,9 +3329,7 @@ int JOIN_TAB_SCAN::next()
|
|||
|
||||
void JOIN_TAB_SCAN::close()
|
||||
{
|
||||
JOIN_TAB *bound= join_tab-cache->tables;
|
||||
for (JOIN_TAB *tab= join_tab-1; tab != bound && !tab->cache; tab--)
|
||||
tab->table->status= tab->status;
|
||||
save_or_restore_used_tabs(join_tab, TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3669,12 +3729,7 @@ int JOIN_TAB_SCAN_MRR::open()
|
|||
/* Dynamic range access is never used with BKA */
|
||||
DBUG_ASSERT(join_tab->use_quick != 2);
|
||||
|
||||
JOIN_TAB *bound= join_tab-cache->tables;
|
||||
for (JOIN_TAB *tab= join_tab-1; tab != bound && !tab->cache; tab--)
|
||||
{
|
||||
tab->status= tab->table->status;
|
||||
tab->table->status= 0;
|
||||
}
|
||||
save_or_restore_used_tabs(join_tab, FALSE);
|
||||
|
||||
init_mrr_buff();
|
||||
|
||||
|
|
|
@ -121,11 +121,14 @@ protected:
|
|||
*/
|
||||
JOIN *join;
|
||||
|
||||
/*
|
||||
Cardinality of the range of join tables whose fields can be put into the
|
||||
cache. A table from the range not necessarily contributes to the cache.
|
||||
/*
|
||||
JOIN_TAB of the first table that can have it's fields in the join cache.
|
||||
That is, tables in the [start_tab, tab) range can have their fields in the
|
||||
join cache.
|
||||
If a join tab in the range represents an SJM-nest, then all tables from the
|
||||
nest can have their fields in the join cache, too.
|
||||
*/
|
||||
uint tables;
|
||||
JOIN_TAB *start_tab;
|
||||
|
||||
/*
|
||||
The total number of flag and data fields that can appear in a record
|
||||
|
@ -647,8 +650,6 @@ public:
|
|||
buff= 0;
|
||||
}
|
||||
|
||||
JOIN_TAB *get_next_table(JOIN_TAB *tab);
|
||||
|
||||
friend class JOIN_CACHE_HASHED;
|
||||
friend class JOIN_CACHE_BNL;
|
||||
friend class JOIN_CACHE_BKA;
|
||||
|
|
1367
sql/sql_select.cc
1367
sql/sql_select.cc
File diff suppressed because it is too large
Load diff
|
@ -165,13 +165,25 @@ enum enum_nested_loop_state
|
|||
|
||||
typedef enum_nested_loop_state
|
||||
(*Next_select_func)(JOIN *, struct st_join_table *, bool);
|
||||
|
||||
/*
|
||||
Function prototype for reading first record for a join tab
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - Record not found
|
||||
Other - A fatal error
|
||||
*/
|
||||
typedef int (*Read_record_func)(struct st_join_table *tab);
|
||||
|
||||
Next_select_func setup_end_select_func(JOIN *join);
|
||||
int rr_sequential(READ_RECORD *info);
|
||||
int rr_sequential_and_unpack(READ_RECORD *info);
|
||||
|
||||
|
||||
class JOIN_CACHE;
|
||||
class SJ_TMP_TABLE;
|
||||
class JOIN_TAB_RANGE;
|
||||
|
||||
typedef struct st_join_table {
|
||||
st_join_table() {} /* Remove gcc warning */
|
||||
|
@ -200,6 +212,21 @@ typedef struct st_join_table {
|
|||
st_join_table *last_inner; /**< last table table for embedding outer join */
|
||||
st_join_table *first_upper; /**< first inner table for embedding outer join */
|
||||
st_join_table *first_unmatched; /**< used for optimization purposes only */
|
||||
|
||||
/*
|
||||
For join tabs that are inside an SJM bush: root of the bush
|
||||
*/
|
||||
st_join_table *bush_root_tab;
|
||||
|
||||
/* TRUE <=> This join_tab is inside an SJM bush and is the last leaf tab here */
|
||||
bool last_leaf_in_bush;
|
||||
|
||||
/*
|
||||
ptr - this is a bush, and ptr points to description of child join_tab
|
||||
range
|
||||
NULL - this join tab has no bush children
|
||||
*/
|
||||
JOIN_TAB_RANGE *bush_children;
|
||||
|
||||
/* Special content for EXPLAIN 'Extra' column or NULL if none */
|
||||
const char *info;
|
||||
|
@ -237,7 +264,13 @@ typedef struct st_join_table {
|
|||
method (but not 'index' for some reason), i.e. this matches method which
|
||||
E(#records) is in found_records.
|
||||
*/
|
||||
ha_rows read_time;
|
||||
double read_time;
|
||||
|
||||
/* psergey-todo: make the below have type double, like POSITION::records_read? */
|
||||
ha_rows records_read;
|
||||
|
||||
/* Startup cost for execution */
|
||||
double startup_cost;
|
||||
|
||||
double partial_join_cardinality;
|
||||
|
||||
|
@ -330,12 +363,10 @@ typedef struct st_join_table {
|
|||
/*
|
||||
Semi-join strategy to be used for this join table. This is a copy of
|
||||
POSITION::sj_strategy field. This field is set up by the
|
||||
fix_semijion_strategies_for_picked_join_order.
|
||||
fix_semijoin_strategies_for_picked_join_order.
|
||||
*/
|
||||
uint sj_strategy;
|
||||
|
||||
struct st_join_table *first_sjm_sibling;
|
||||
|
||||
void cleanup();
|
||||
inline bool is_using_loose_index_scan()
|
||||
{
|
||||
|
@ -450,9 +481,6 @@ enum_nested_loop_state sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool
|
|||
end_of_records);
|
||||
enum_nested_loop_state sub_select(JOIN *join,JOIN_TAB *join_tab, bool
|
||||
end_of_records);
|
||||
enum_nested_loop_state sub_select_sjm(JOIN *join, JOIN_TAB *join_tab,
|
||||
bool end_of_records);
|
||||
|
||||
enum_nested_loop_state
|
||||
end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
||||
bool end_of_records);
|
||||
|
@ -598,26 +626,53 @@ inline bool sj_is_materialize_strategy(uint strategy)
|
|||
return strategy >= SJ_OPT_MATERIALIZE;
|
||||
}
|
||||
|
||||
class JOIN_TAB_RANGE: public Sql_alloc
|
||||
{
|
||||
public:
|
||||
JOIN_TAB *start;
|
||||
JOIN_TAB *end;
|
||||
};
|
||||
|
||||
|
||||
class JOIN :public Sql_alloc
|
||||
{
|
||||
JOIN(const JOIN &rhs); /**< not implemented */
|
||||
JOIN& operator=(const JOIN &rhs); /**< not implemented */
|
||||
public:
|
||||
JOIN_TAB *join_tab,**best_ref;
|
||||
JOIN_TAB *join_tab, **best_ref;
|
||||
JOIN_TAB **map2table; ///< mapping between table indexes and JOIN_TABs
|
||||
JOIN_TAB *join_tab_save; ///< saved join_tab for subquery reexecution
|
||||
|
||||
List<JOIN_TAB_RANGE> join_tab_ranges;
|
||||
|
||||
/*
|
||||
Base tables participating in the join. After join optimization is done, the
|
||||
tables are stored in the join order (but the only really important part is
|
||||
that const tables are first).
|
||||
*/
|
||||
TABLE **table;
|
||||
TABLE **all_tables;
|
||||
/**
|
||||
The table which has an index that allows to produce the requried ordering.
|
||||
A special value of 0x1 means that the ordering will be produced by
|
||||
passing 1st non-const table to filesort(). NULL means no such table exists.
|
||||
*/
|
||||
TABLE *sort_by_table;
|
||||
uint tables; /**< Number of tables in the join */
|
||||
/*
|
||||
Number of tables in the join.
|
||||
(In MySQL, it is named 'tables' and is also the number of elements in
|
||||
join->join_tab array. In MariaDB, the latter is not true, so we've renamed
|
||||
the variable)
|
||||
*/
|
||||
uint table_count;
|
||||
uint outer_tables; /**< Number of tables that are not inside semijoin */
|
||||
uint const_tables;
|
||||
/*
|
||||
Number of tables in the top join_tab array. Normally this matches
|
||||
(join_tab_ranges.head()->end - join_tab_ranges.head()->start).
|
||||
|
||||
We keep it here so that it is saved/restored with JOIN::restore_tmp.
|
||||
*/
|
||||
uint top_join_tab_count;
|
||||
uint send_group_parts;
|
||||
bool group; /**< If query contains GROUP BY clause */
|
||||
/**
|
||||
|
@ -693,7 +748,6 @@ public:
|
|||
|
||||
/* We also maintain a stack of join optimization states in * join->positions[] */
|
||||
/******* Join optimization state members end *******/
|
||||
Next_select_func first_select;
|
||||
/*
|
||||
The cost of best complete join plan found so far during optimization,
|
||||
after optimization phase - cost of picked join order (not taking into
|
||||
|
@ -824,8 +878,12 @@ public:
|
|||
bool union_part; ///< this subselect is part of union
|
||||
bool optimized; ///< flag to avoid double optimization in EXPLAIN
|
||||
|
||||
/*
|
||||
Subqueries that will need to be converted to semi-join nests, including
|
||||
those converted to jtbm nests. The list is emptied when conversion is done.
|
||||
*/
|
||||
Array<Item_in_subselect> sj_subselects;
|
||||
|
||||
|
||||
/* Temporary tables used to weed-out semi-join duplicates */
|
||||
List<TABLE> sj_tmp_tables;
|
||||
/* SJM nests that are executed with SJ-Materialization strategy */
|
||||
|
@ -858,7 +916,8 @@ public:
|
|||
{
|
||||
join_tab= join_tab_save= 0;
|
||||
table= 0;
|
||||
tables= 0;
|
||||
table_count= 0;
|
||||
top_join_tab_count= 0;
|
||||
const_tables= 0;
|
||||
eliminated_tables= 0;
|
||||
join_list= 0;
|
||||
|
@ -913,7 +972,6 @@ public:
|
|||
rollup.state= ROLLUP::STATE_NONE;
|
||||
|
||||
no_const_tables= FALSE;
|
||||
first_select= sub_select;
|
||||
outer_ref_cond= 0;
|
||||
}
|
||||
|
||||
|
@ -975,7 +1033,7 @@ public:
|
|||
}
|
||||
inline table_map all_tables_map()
|
||||
{
|
||||
return (table_map(1) << tables) - 1;
|
||||
return (table_map(1) << table_count) - 1;
|
||||
}
|
||||
/*
|
||||
Return the table for which an index scan can be used to satisfy
|
||||
|
@ -1008,6 +1066,12 @@ private:
|
|||
void cleanup_item_list(List<Item> &items) const;
|
||||
};
|
||||
|
||||
enum enum_with_bush_roots { WITH_BUSH_ROOTS, WITHOUT_BUSH_ROOTS};
|
||||
enum enum_with_const_tables { WITH_CONST_TABLES, WITHOUT_CONST_TABLES};
|
||||
|
||||
JOIN_TAB *first_linear_tab(JOIN *join, enum enum_with_const_tables const_tbls);
|
||||
JOIN_TAB *next_linear_tab(JOIN* join, JOIN_TAB* tab,
|
||||
enum enum_with_bush_roots include_bush_roots);
|
||||
|
||||
typedef struct st_select_check {
|
||||
uint const_ref,reg_ref;
|
||||
|
@ -1255,6 +1319,7 @@ int safe_index_read(JOIN_TAB *tab);
|
|||
COND *remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value);
|
||||
int test_if_item_cache_changed(List<Cached_item> &list);
|
||||
int join_init_read_record(JOIN_TAB *tab);
|
||||
int join_read_record_no_init(JOIN_TAB *tab);
|
||||
void set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key);
|
||||
inline Item * and_items(Item* cond, Item *item)
|
||||
{
|
||||
|
|
|
@ -6615,14 +6615,15 @@ int make_schema_select(THD *thd, SELECT_LEX *sel,
|
|||
bool get_schema_tables_result(JOIN *join,
|
||||
enum enum_schema_table_state executed_place)
|
||||
{
|
||||
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
|
||||
THD *thd= join->thd;
|
||||
LEX *lex= thd->lex;
|
||||
bool result= 0;
|
||||
DBUG_ENTER("get_schema_tables_result");
|
||||
|
||||
thd->no_warnings_for_error= 1;
|
||||
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
|
||||
for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
|
||||
tab;
|
||||
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
|
||||
{
|
||||
if (!tab->table || !tab->table->pos_in_table_list)
|
||||
break;
|
||||
|
|
|
@ -166,58 +166,67 @@ void TEST_filesort(SORT_FIELD *sortorder,uint s_length)
|
|||
void
|
||||
TEST_join(JOIN *join)
|
||||
{
|
||||
uint i,ref;
|
||||
uint ref;
|
||||
int i;
|
||||
List_iterator<JOIN_TAB_RANGE> it(join->join_tab_ranges);
|
||||
JOIN_TAB_RANGE *jt_range;
|
||||
DBUG_ENTER("TEST_join");
|
||||
|
||||
/*
|
||||
Assemble results of all the calls to full_name() first,
|
||||
in order not to garble the tabular output below.
|
||||
*/
|
||||
String ref_key_parts[MAX_TABLES];
|
||||
for (i= 0; i < join->tables; i++)
|
||||
{
|
||||
JOIN_TAB *tab= join->join_tab + i;
|
||||
for (ref= 0; ref < tab->ref.key_parts; ref++)
|
||||
{
|
||||
ref_key_parts[i].append(tab->ref.items[ref]->full_name());
|
||||
ref_key_parts[i].append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_LOCK_FILE;
|
||||
VOID(fputs("\nInfo about JOIN\n",DBUG_FILE));
|
||||
for (i=0 ; i < join->tables ; i++)
|
||||
|
||||
while ((jt_range= it++))
|
||||
{
|
||||
JOIN_TAB *tab=join->join_tab+i;
|
||||
TABLE *form=tab->table;
|
||||
char key_map_buff[128];
|
||||
fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n",
|
||||
form->alias.c_ptr(),
|
||||
join_type_str[tab->type],
|
||||
tab->keys.print(key_map_buff),
|
||||
tab->ref.key_parts,
|
||||
tab->ref.key,
|
||||
tab->ref.key_length);
|
||||
if (tab->select)
|
||||
/*
|
||||
Assemble results of all the calls to full_name() first,
|
||||
in order not to garble the tabular output below.
|
||||
*/
|
||||
String ref_key_parts[MAX_TABLES];
|
||||
int tables_in_range= jt_range->end - jt_range->start;
|
||||
for (i= 0; i < tables_in_range; i++)
|
||||
{
|
||||
char buf[MAX_KEY/8+1];
|
||||
if (tab->use_quick == 2)
|
||||
fprintf(DBUG_FILE,
|
||||
" quick select checked for each record (keys: %s)\n",
|
||||
tab->select->quick_keys.print(buf));
|
||||
else if (tab->select->quick)
|
||||
JOIN_TAB *tab= jt_range->start + i;
|
||||
for (ref= 0; ref < tab->ref.key_parts; ref++)
|
||||
{
|
||||
fprintf(DBUG_FILE, " quick select used:\n");
|
||||
tab->select->quick->dbug_dump(18, FALSE);
|
||||
ref_key_parts[i].append(tab->ref.items[ref]->full_name());
|
||||
ref_key_parts[i].append(" ");
|
||||
}
|
||||
else
|
||||
VOID(fputs(" select used\n",DBUG_FILE));
|
||||
}
|
||||
if (tab->ref.key_parts)
|
||||
|
||||
for (i= 0; i < tables_in_range; i++)
|
||||
{
|
||||
fprintf(DBUG_FILE,
|
||||
JOIN_TAB *tab= jt_range->start + i;
|
||||
TABLE *form=tab->table;
|
||||
char key_map_buff[128];
|
||||
fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n",
|
||||
form->alias.c_ptr(),
|
||||
join_type_str[tab->type],
|
||||
tab->keys.print(key_map_buff),
|
||||
tab->ref.key_parts,
|
||||
tab->ref.key,
|
||||
tab->ref.key_length);
|
||||
if (tab->select)
|
||||
{
|
||||
char buf[MAX_KEY/8+1];
|
||||
if (tab->use_quick == 2)
|
||||
fprintf(DBUG_FILE,
|
||||
" quick select checked for each record (keys: %s)\n",
|
||||
tab->select->quick_keys.print(buf));
|
||||
else if (tab->select->quick)
|
||||
{
|
||||
fprintf(DBUG_FILE, " quick select used:\n");
|
||||
tab->select->quick->dbug_dump(18, FALSE);
|
||||
}
|
||||
else
|
||||
VOID(fputs(" select used\n",DBUG_FILE));
|
||||
}
|
||||
if (tab->ref.key_parts)
|
||||
{
|
||||
fprintf(DBUG_FILE,
|
||||
" refs: %s\n", ref_key_parts[i].c_ptr_safe());
|
||||
}
|
||||
}
|
||||
VOID(fputs("\n",DBUG_FILE));
|
||||
}
|
||||
DBUG_UNLOCK_FILE;
|
||||
DBUG_VOID_RETURN;
|
||||
|
|
|
@ -690,7 +690,8 @@ bool st_select_lex_unit::cleanup()
|
|||
if ((join= fake_select_lex->join))
|
||||
{
|
||||
join->tables_list= 0;
|
||||
join->tables= 0;
|
||||
join->table_count= 0;
|
||||
join->top_join_tab_count= 0;
|
||||
}
|
||||
error|= fake_select_lex->cleanup();
|
||||
/*
|
||||
|
|
13
sql/table.cc
13
sql/table.cc
|
@ -5340,6 +5340,19 @@ bool st_table::is_children_attached(void)
|
|||
(parent && parent->children_attached));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return TRUE if the table is filled at execution phase
|
||||
|
||||
(and so, the optimizer must not do anything that depends on the contents of
|
||||
the table, like range analysis or constant table detection)
|
||||
*/
|
||||
|
||||
bool st_table::is_filled_at_execution()
|
||||
{
|
||||
return test(pos_in_table_list->jtbm_subselect);
|
||||
}
|
||||
|
||||
/*
|
||||
Cleanup this table for re-execution.
|
||||
|
||||
|
|
18
sql/table.h
18
sql/table.h
|
@ -967,6 +967,12 @@ struct st_table {
|
|||
file->extra(HA_EXTRA_KEYREAD);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
/*
|
||||
Returns TRUE if the table is filled at execution phase (and so, the
|
||||
optimizer must not do anything that depends on the contents of the table,
|
||||
like range analysis or constant table detection)
|
||||
*/
|
||||
bool is_filled_at_execution();
|
||||
inline void disable_keyread()
|
||||
{
|
||||
DBUG_ENTER("disable_keyread");
|
||||
|
@ -1195,7 +1201,7 @@ class Item_in_subselect;
|
|||
1) table (TABLE_LIST::view == NULL)
|
||||
- base table
|
||||
(TABLE_LIST::derived == NULL)
|
||||
- subquery - TABLE_LIST::table is a temp table
|
||||
- FROM-clause subquery - TABLE_LIST::table is a temp table
|
||||
(TABLE_LIST::derived != NULL)
|
||||
- information schema table
|
||||
(TABLE_LIST::schema_table != NULL)
|
||||
|
@ -1214,6 +1220,8 @@ class Item_in_subselect;
|
|||
(TABLE_LIST::natural_join != NULL)
|
||||
- JOIN ... USING
|
||||
(TABLE_LIST::join_using_fields != NULL)
|
||||
- semi-join nest (sj_on_expr!= NULL && sj_subq_pred!=NULL)
|
||||
4) jtbm semi-join (jtbm_subselect != NULL)
|
||||
*/
|
||||
|
||||
class Index_hint;
|
||||
|
@ -1256,8 +1264,14 @@ struct TABLE_LIST
|
|||
*/
|
||||
table_map sj_inner_tables;
|
||||
/* Number of IN-compared expressions */
|
||||
uint sj_in_exprs;
|
||||
uint sj_in_exprs;
|
||||
|
||||
/* If this is a non-jtbm semi-join nest: corresponding subselect predicate */
|
||||
Item_in_subselect *sj_subq_pred;
|
||||
|
||||
/* If this is a jtbm semi-join object: corresponding subselect predicate */
|
||||
Item_in_subselect *jtbm_subselect;
|
||||
|
||||
SJ_MATERIALIZATION_INFO *sj_mat_info;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue