mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Merge 5.3->main -> 5.3-mwl90
This commit is contained in:
commit
5cd18326c2
40 changed files with 5352 additions and 1933 deletions
|
@ -1364,7 +1364,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);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
drop table if exists t1,t2,t3,t4,t5,t6;
|
||||
#
|
||||
# Bug #46791: Assertion failed:(table->key_read==0),function unknown
|
||||
# function,file sql_base.cc
|
||||
|
@ -356,7 +357,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 +372,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 +395,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 +410,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 +432,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 +447,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 +580,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 +595,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 +618,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 +633,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 +655,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 +670,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 +736,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
|
||||
SELECT * FROM t1
|
||||
WHERE f3 = (
|
||||
|
@ -749,6 +751,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
|
||||
SELECT * FROM t1
|
||||
WHERE f3 = (
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
||||
drop table if exists columns;
|
||||
drop table if exists t1_16, t2_16, t3_16;
|
||||
drop view if exists v1, v2, v1m, v2m;
|
||||
create table t1 (a1 char(8), a2 char(8));
|
||||
create table t2 (b1 char(8), b2 char(8));
|
||||
|
@ -30,7 +33,7 @@ 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='materialization=on,in_to_exists=off,semijoin=off';
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,firstmatch=off';
|
||||
/******************************************************************************
|
||||
* Simple tests.
|
||||
******************************************************************************/
|
||||
|
@ -41,7 +44,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 +55,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
|
||||
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 +66,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
|
||||
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 +77,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
|
||||
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 +85,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 +96,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 +107,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 +118,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 +129,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 +143,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,47 +172,48 @@ 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 @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=on';
|
||||
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='materialization=off,in_to_exists=on,semijoin=on';
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
execute st1;
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
1 - 02 2 - 02
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=on';
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
execute st1;
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
1 - 02 2 - 02
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=on';
|
||||
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='materialization=on,in_to_exists=off,semijoin=off';
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
execute st1;
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
1 - 02 2 - 02
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=on';
|
||||
set @@optimizer_switch='default,materialization=off';
|
||||
execute st1;
|
||||
a1 a2
|
||||
1 - 01 2 - 01
|
||||
1 - 02 2 - 02
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,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 +224,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 +279,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 +293,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 +321,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 +346,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 `test`.`t3a`.`c2` 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 `test`.`t3a`.`c2` 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 +370,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
|
||||
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 +411,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 +434,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 +480,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 `test`.`t3a`.`c2` 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 `test`.`t3a`.`c2` 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 +553,6 @@ a1 a2
|
|||
Test that BLOBs are not materialized (except when arguments of some functions).
|
||||
*/
|
||||
# force materialization to be always considered
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||
set @prefix_len = 6;
|
||||
set @blob_len = 16;
|
||||
set @suffix_len = @blob_len - @prefix_len;
|
||||
|
@ -611,7 +614,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 +643,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 +665,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 left(`test`.`t1_16`.`a1`,8) 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 left(`test`.`t1_16`.`a1`,8) 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 +727,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 +741,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 +754,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 +834,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 +847,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 +927,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 +940,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 +954,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='materialization=on,in_to_exists=off,semijoin=off';
|
||||
explain extended select bin(a1), bin(a2)
|
||||
from t1bit
|
||||
where (a1, a2) in (select b1, b2 from t2bit);
|
||||
|
@ -959,7 +961,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 +996,7 @@ drop table t1, t2, t3, t1i, t2i, t3i, columns;
|
|||
/******************************************************************************
|
||||
* Test the cache of the left operand of IN.
|
||||
******************************************************************************/
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,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 +1032,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 +1046,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 +1060,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 +1073,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 +1085,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
|
||||
|
@ -1136,47 +1138,47 @@ drop table t2;
|
|||
create table t1 (a1 int key);
|
||||
create table t2 (b1 int);
|
||||
insert into t1 values (5);
|
||||
Only the last query returns correct result. Filed as BUG#40037.
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=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
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
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 @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
|
||||
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
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
2 DEPENDENT 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 @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||
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 Select tables optimized away
|
||||
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);
|
||||
min(a1)
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
|
||||
set @@optimizer_switch='default,semijoin=off';
|
||||
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 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);
|
||||
min(a1)
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=off,semijoin=on';
|
||||
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='materialization=on,in_to_exists=off,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
|
||||
|
@ -1196,15 +1198,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 @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=on';
|
||||
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,
|
||||
|
@ -1217,11 +1221,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 @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=on';
|
||||
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; Rowid-ordered scan
|
||||
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
pk
|
||||
|
@ -1230,6 +1235,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
|
||||
#
|
||||
|
@ -1281,6 +1287,66 @@ a a in (select a from t1)
|
|||
1 0
|
||||
2 0
|
||||
drop table t0, t1;
|
||||
set optimizer_switch='firstmatch=on';
|
||||
#
|
||||
# MWL#90, review feedback: check what happens when the subquery
|
||||
# looks like candidate for MWL#90 checking at the first glance
|
||||
# but then subselect_hash_sj_engine::init_permanent() discovers
|
||||
# that it's not possible to perform duplicate removal for the
|
||||
# selected datatypes, and so materialization isn't applicable after
|
||||
# all.
|
||||
#
|
||||
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));
|
||||
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)));
|
||||
explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
|
||||
2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 Using where
|
||||
select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
|
||||
left(a1,7) left(a2,7)
|
||||
1 - 01x 2 - 01x
|
||||
drop table t1_1024, t2_1024;
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||
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
|
||||
|
@ -1371,7 +1437,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; Rowid-ordered scan
|
||||
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
|
||||
pk
|
||||
|
@ -1381,6 +1447,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
|
||||
#
|
||||
|
|
|
@ -1368,7 +1368,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);
|
||||
|
|
|
@ -961,7 +961,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 t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 105.00 Using where; FirstMatch(t2)
|
||||
1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 100.00 Using where; FirstMatch(t2)
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_key` = `test`.`t2`.`varchar_nokey`) and (`test`.`t1`.`varchar_nokey` = `test`.`t2`.`varchar_nokey`) and ((`test`.`t2`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
|
||||
SELECT varchar_nokey
|
||||
|
|
|
@ -354,6 +354,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)
|
||||
|
|
|
@ -361,6 +361,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)
|
||||
|
|
|
@ -33,7 +33,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);
|
||||
|
@ -53,7 +53,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
|
||||
|
@ -76,7 +76,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;
|
||||
|
@ -103,7 +103,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
|
||||
|
@ -131,7 +131,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
|
||||
|
@ -165,7 +165,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)
|
||||
|
@ -199,7 +199,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
|
||||
|
@ -233,7 +233,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)
|
||||
|
@ -353,7 +353,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 (
|
||||
|
@ -364,6 +364,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)
|
||||
|
@ -697,7 +701,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)
|
||||
|
|
|
@ -969,7 +969,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 t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 105.00 Using where; FirstMatch(t2); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
|
||||
1 PRIMARY t1 ref varchar_key varchar_key 3 test.t2.varchar_nokey 2 100.00 Using where; FirstMatch(t2); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`varchar_nokey` AS `varchar_nokey` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`varchar_key` = `test`.`t2`.`varchar_nokey`) and (`test`.`t1`.`varchar_nokey` = `test`.`t2`.`varchar_nokey`) and ((`test`.`t2`.`varchar_nokey` < 'n') xor `test`.`t1`.`pk`))
|
||||
SELECT varchar_nokey
|
||||
|
|
1360
mysql-test/r/subselect_sj_mat.result
Normal file
1360
mysql-test/r/subselect_sj_mat.result
Normal file
File diff suppressed because it is too large
Load diff
103
mysql-test/r/subselect_sj_nonmerged.result
Normal file
103
mysql-test/r/subselect_sj_nonmerged.result
Normal file
|
@ -0,0 +1,103 @@
|
|||
drop table if exists t0, t1, t2, t3, t4;
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set optimizer_switch='materialization=on';
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
create table t1 as select * from t0;
|
||||
# The following should use full scan on <subquery2> and it must scan 1 row:
|
||||
explain select * from t0 where a in (select max(a) from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
a
|
||||
9
|
||||
insert into t1 values (11);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
a
|
||||
delete from t1 where a=11;
|
||||
insert into t0 values (NULL);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
a
|
||||
9
|
||||
delete from t0 where a is NULL;
|
||||
delete from t1;
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
a
|
||||
insert into t0 values (NULL);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
a
|
||||
delete from t0 where a is NULL;
|
||||
drop table t1;
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 select a,a from t0;
|
||||
create table t2 as select * from t1 where a<5;
|
||||
create table t3 as select (A.a + 10*B.a) as a from t0 A, t0 B;
|
||||
alter table t3 add primary key(a);
|
||||
# The following should have do a full scan on <subquery2> and scan 5 rows
|
||||
# (despite that subquery's join output estimate is 50 rows)
|
||||
explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
# Compare to this which really will have 50 record combinations:
|
||||
explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 50 Using where
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
# Outer joins also work:
|
||||
explain select * from t3
|
||||
where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 50 Using where
|
||||
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using temporary
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
|
||||
create table t4 (a int, b int, filler char(20), unique key(a,b));
|
||||
insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B;
|
||||
explain select * from t0, t4 where
|
||||
t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
|
||||
1 PRIMARY t4 ALL a NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t4.a 1
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B;
|
||||
explain select * from t4 where
|
||||
t4.a in (select max(t2.a) from t1, t2 group by t2.b) and
|
||||
t4.b in (select max(t2.a) from t1, t2 group by t2.b);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
|
||||
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
|
||||
1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
|
||||
3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||
3 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
|
||||
2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
|
||||
drop table t1,t2,t3,t4;
|
||||
drop table t0;
|
||||
#
|
||||
# BUG#780359: Crash with get_fanout_with_deps in maria-5.3-mwl90
|
||||
#
|
||||
CREATE TABLE t1 (f1 int);
|
||||
INSERT INTO t1 VALUES (2),(2);
|
||||
CREATE TABLE t2 (f3 int);
|
||||
INSERT INTO t2 VALUES (2),(2);
|
||||
SELECT *
|
||||
FROM t1
|
||||
WHERE ( f1 ) IN (
|
||||
SELECT t2.f3
|
||||
FROM t2
|
||||
WHERE t2.f3 = 97
|
||||
AND t2.f3 = 50
|
||||
GROUP BY 1
|
||||
);
|
||||
f1
|
||||
DROP TABLE t1, t2;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
# General purpose bug fix tests go here : subselect.test too large
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1,t2,t3,t4,t5,t6;
|
||||
--enable_warnings
|
||||
|
||||
--echo #
|
||||
--echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown
|
||||
|
|
|
@ -3,913 +3,12 @@
|
|||
# (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='materialization=on,in_to_exists=off,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='materialization=on,in_to_exists=off,semijoin=on';
|
||||
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='materialization=off,in_to_exists=on,semijoin=on';
|
||||
execute st1;
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=on';
|
||||
execute st1;
|
||||
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=on';
|
||||
prepare st1 from
|
||||
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
|
||||
--source t/subselect_sj_mat.test
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||
execute st1;
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=on';
|
||||
execute st1;
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,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='materialization=on,in_to_exists=off,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='materialization=on,in_to_exists=off,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='materialization=on,in_to_exists=off,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);
|
||||
-- echo Only the last query returns correct result. Filed as BUG#40037.
|
||||
# Query with group by, executed via materialization
|
||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=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);
|
||||
# Query with group by, executed via IN=>EXISTS
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=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='materialization=on,in_to_exists=off,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 via IN=>EXISTS
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=on,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 five queries. This difference is
|
||||
# filed as BUG#40037.
|
||||
set @@optimizer_switch='materialization=off,in_to_exists=off,semijoin=on';
|
||||
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='materialization=on,in_to_exists=off,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='materialization=on,in_to_exists=off,semijoin=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='materialization=on,in_to_exists=off,semijoin=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,in_to_exists=on';
|
||||
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 contents of the temp table of a materialized subquery is
|
||||
# cleaned up between PS re-executions.
|
||||
|
@ -1016,6 +115,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
|
||||
|
|
|
@ -494,6 +494,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);
|
||||
|
||||
|
|
974
mysql-test/t/subselect_sj_mat.test
Normal file
974
mysql-test/t/subselect_sj_mat.test
Normal file
|
@ -0,0 +1,974 @@
|
|||
#
|
||||
# Hash semi-join regression tests
|
||||
# (WL#1110: Subquery optimization: materialization)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
||||
drop table if exists columns;
|
||||
drop table if exists t1_16, t2_16, t3_16;
|
||||
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='materialization=on,in_to_exists=off,firstmatch=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
|
||||
--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,in_to_exists=on';
|
||||
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 contents of the temp table of a materialized subquery is
|
||||
# cleaned up between PS re-executions.
|
||||
#
|
||||
|
||||
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';
|
||||
|
||||
--echo #
|
||||
--echo # MWL#90, review feedback: check what happens when the subquery
|
||||
--echo # looks like candidate for MWL#90 checking at the first glance
|
||||
--echo # but then subselect_hash_sj_engine::init_permanent() discovers
|
||||
--echo # that it's not possible to perform duplicate removal for the
|
||||
--echo # selected datatypes, and so materialization isn't applicable after
|
||||
--echo # all.
|
||||
--echo #
|
||||
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));
|
||||
|
||||
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)));
|
||||
|
||||
explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
|
||||
select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
|
||||
|
||||
drop table t1_1024, t2_1024;
|
99
mysql-test/t/subselect_sj_nonmerged.test
Normal file
99
mysql-test/t/subselect_sj_nonmerged.test
Normal file
|
@ -0,0 +1,99 @@
|
|||
#
|
||||
# Tests for non-merged semi-joins
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t0, t1, t2, t3, t4;
|
||||
--enable_warnings
|
||||
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set optimizer_switch='materialization=on';
|
||||
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
|
||||
|
||||
# Check the case of subquery having agggregates but not having grouping
|
||||
|
||||
create table t1 as select * from t0;
|
||||
--echo # The following should use full scan on <subquery2> and it must scan 1 row:
|
||||
explain select * from t0 where a in (select max(a) from t1);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
|
||||
# Ok, now check the trivial match/no-match/NULL on the left/NULL on the right cases
|
||||
insert into t1 values (11);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
delete from t1 where a=11;
|
||||
|
||||
insert into t0 values (NULL);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
delete from t0 where a is NULL;
|
||||
|
||||
delete from t1;
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
|
||||
insert into t0 values (NULL);
|
||||
select * from t0 where a in (select max(a) from t1);
|
||||
delete from t0 where a is NULL;
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Try with join subqueries
|
||||
#
|
||||
|
||||
create table t1 (a int, b int);
|
||||
insert into t1 select a,a from t0; # 10 rows
|
||||
create table t2 as select * from t1 where a<5; # 5 rows
|
||||
create table t3 as select (A.a + 10*B.a) as a from t0 A, t0 B; # 100 rows
|
||||
alter table t3 add primary key(a);
|
||||
|
||||
--echo # The following should have do a full scan on <subquery2> and scan 5 rows
|
||||
--echo # (despite that subquery's join output estimate is 50 rows)
|
||||
explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b);
|
||||
|
||||
--echo # Compare to this which really will have 50 record combinations:
|
||||
explain select * from t3 where a in (select max(t2.a) from t1, t2 group by t2.b, t1.b);
|
||||
|
||||
--echo # Outer joins also work:
|
||||
explain select * from t3
|
||||
where a in (select max(t2.a) from t1 left join t2 on t1.a=t2.a group by t2.b, t1.b);
|
||||
|
||||
#
|
||||
# Check if joins on the outer side also work
|
||||
#
|
||||
create table t4 (a int, b int, filler char(20), unique key(a,b));
|
||||
insert into t4 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t0 A, t0 B; # 100 rows
|
||||
explain select * from t0, t4 where
|
||||
t4.b=t0.a and t4.a in (select max(t2.a) from t1, t2 group by t2.b);
|
||||
|
||||
insert into t4 select 100 + (B.a *100 + A.a), 100 + (B.a*100 + A.a), 'filler' from t4 A, t0 B;
|
||||
explain select * from t4 where
|
||||
t4.a in (select max(t2.a) from t1, t2 group by t2.b) and
|
||||
t4.b in (select max(t2.a) from t1, t2 group by t2.b);
|
||||
|
||||
drop table t1,t2,t3,t4;
|
||||
|
||||
drop table t0;
|
||||
|
||||
--echo #
|
||||
--echo # BUG#780359: Crash with get_fanout_with_deps in maria-5.3-mwl90
|
||||
--echo #
|
||||
CREATE TABLE t1 (f1 int);
|
||||
INSERT INTO t1 VALUES (2),(2);
|
||||
|
||||
CREATE TABLE t2 (f3 int);
|
||||
INSERT INTO t2 VALUES (2),(2);
|
||||
|
||||
SELECT *
|
||||
FROM t1
|
||||
WHERE ( f1 ) IN (
|
||||
SELECT t2.f3
|
||||
FROM t2
|
||||
WHERE t2.f3 = 97
|
||||
AND t2.f3 = 50
|
||||
GROUP BY 1
|
||||
);
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#!@PERL@
|
||||
# Test of table elimination feature
|
||||
|
||||
|
|
|
@ -1249,7 +1249,8 @@ public:
|
|||
virtual Item_equal *find_item_equal(COND_EQUAL *cond_equal) { return NULL; }
|
||||
/**
|
||||
Set the join tab index to the minimal (left-most) JOIN_TAB to which this
|
||||
Item is attached.
|
||||
Item is attached. The number is an index is depth_first_tab() traversal
|
||||
order.
|
||||
*/
|
||||
virtual void set_join_tab_idx(uint join_tab_idx_arg)
|
||||
{
|
||||
|
|
|
@ -5813,28 +5813,12 @@ Item* Item_equal::get_first(Item *field_item)
|
|||
{
|
||||
/*
|
||||
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 (it.get_curr_field()->table->reginfo.join_tab >= first)
|
||||
if (it.get_curr_field()->table->pos_in_table_list->embedding == emb_nest)
|
||||
{
|
||||
/*
|
||||
If we found given field then return NULL to avoid unnecessary
|
||||
|
@ -5846,33 +5830,28 @@ Item* Item_equal::get_first(Item *field_item)
|
|||
}
|
||||
else
|
||||
{
|
||||
#if TO_BE_DELETED
|
||||
/*
|
||||
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++))
|
||||
{
|
||||
Item_field *fld_item= (Item_field *) (item->real_item());
|
||||
TABLE_LIST *emb_nest= fld_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 equal_items.head();
|
||||
}
|
||||
// Shouldn't get here.
|
||||
|
|
|
@ -31,13 +31,14 @@
|
|||
#include "mysql_priv.h"
|
||||
#include "sql_select.h"
|
||||
|
||||
double get_post_group_estimate(JOIN* join, double join_op_rows);
|
||||
|
||||
|
||||
Item_subselect::Item_subselect():
|
||||
Item_result_field(), value_assigned(0), own_engine(TRUE),
|
||||
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), forced_const(FALSE), eliminated(FALSE),
|
||||
Item_result_field(), value_assigned(0), own_engine(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), forced_const(FALSE), eliminated(FALSE),
|
||||
engine_changed(0), changed(0), is_correlated(FALSE)
|
||||
{
|
||||
DBUG_ENTER("Item_subselect::Item_subselect");
|
||||
|
@ -238,13 +239,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();
|
||||
|
@ -262,6 +263,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;
|
||||
}
|
||||
|
@ -556,6 +558,64 @@ bool Item_subselect::exec()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
int Item_subselect::optimize(double *out_rows, double *cost)
|
||||
{
|
||||
int res;
|
||||
DBUG_ASSERT(0);
|
||||
res= engine->optimize(out_rows, cost);
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int Item_in_subselect::optimize(double *out_rows, double *cost)
|
||||
{
|
||||
int res;
|
||||
DBUG_ENTER("Item_in_subselect::optimize");
|
||||
SELECT_LEX *save_select= thd->lex->current_select;
|
||||
JOIN *join= unit->first_select()->join;
|
||||
|
||||
thd->lex->current_select= join->select_lex;
|
||||
if ((res= join->optimize()))
|
||||
DBUG_RETURN(res);
|
||||
|
||||
/* Calculate #rows and cost of join execution */
|
||||
join->get_partial_cost_and_fanout(join->table_count - join->const_tables,
|
||||
table_map(-1),
|
||||
cost, out_rows);
|
||||
|
||||
/*
|
||||
Adjust join output cardinality. There can be these cases:
|
||||
- Have no GROUP BY and no aggregate funcs: we won't get into this
|
||||
function because such join will be processed as a merged semi-join
|
||||
(TODO: does it really mean we don't need to handle such cases here at
|
||||
all? put ASSERT)
|
||||
- Have no GROUP BY but have aggregate funcs: output is 1 record.
|
||||
- Have GROUP BY and have (or not) aggregate funcs: need to adjust output
|
||||
cardinality.
|
||||
*/
|
||||
thd->lex->current_select= save_select;
|
||||
if (!join->group_list && !join->group_optimized_away &&
|
||||
join->tmp_table_param.sum_func_count)
|
||||
{
|
||||
DBUG_PRINT("info",("Materialized join will have only 1 row (it has "
|
||||
"aggregates but no GROUP BY"));
|
||||
*out_rows= 1;
|
||||
}
|
||||
|
||||
/* Now with grouping */
|
||||
if (join->group_list)
|
||||
{
|
||||
DBUG_PRINT("info",("Materialized join has grouping, trying to estimate it"));
|
||||
double output_rows= get_post_group_estimate(join, *out_rows);
|
||||
DBUG_PRINT("info",("Got value of %g", output_rows));
|
||||
*out_rows= output_rows;
|
||||
}
|
||||
|
||||
DBUG_RETURN(res);
|
||||
|
||||
}
|
||||
/**
|
||||
Check if an expression cache is needed for this subquery
|
||||
|
||||
|
@ -865,9 +925,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();
|
||||
}
|
||||
|
||||
|
@ -1089,7 +1146,9 @@ bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
|
|||
Item_in_subselect::Item_in_subselect(Item * left_exp,
|
||||
st_select_lex *select_lex):
|
||||
Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
|
||||
optimizer(0), pushed_cond_guards(NULL), in_strategy(0), upper_item(0)
|
||||
optimizer(0), pushed_cond_guards(NULL), in_strategy(0),
|
||||
is_jtbm_merged(FALSE), is_flattenable_semijoin(FALSE),
|
||||
upper_item(0)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
|
||||
left_expr= left_exp;
|
||||
|
@ -2415,7 +2474,8 @@ bool Item_in_subselect::setup_mat_engine()
|
|||
if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (mat_engine->init(&select_engine->join->fields_list))
|
||||
if (mat_engine->init(&select_engine->join->fields_list,
|
||||
engine->get_identifier()))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
engine= mat_engine;
|
||||
|
@ -2444,7 +2504,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>))
|
||||
|
@ -2829,9 +2889,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++)
|
||||
|
@ -3943,6 +4003,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
|
||||
|
@ -3958,7 +4020,7 @@ bitmap_init_memroot(MY_BITMAP *map, uint n_bits, MEM_ROOT *mem_root)
|
|||
@retval FALSE otherwise
|
||||
*/
|
||||
|
||||
bool subselect_hash_sj_engine::init(List<Item> *tmp_columns)
|
||||
bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
|
||||
{
|
||||
select_union *result_sink;
|
||||
/* Options to create_tmp_table. */
|
||||
|
@ -3996,10 +4058,18 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns)
|
|||
*/
|
||||
if (!(result_sink= new select_materialize_with_stats))
|
||||
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);
|
||||
|
||||
result_sink->get_tmp_table_param()->materialized_subquery= true;
|
||||
if (result_sink->create_result_table(thd, tmp_columns, TRUE,
|
||||
tmp_create_options,
|
||||
"materialized subselect", TRUE))
|
||||
name, TRUE))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
tmp_table= result_sink->table;
|
||||
|
@ -4092,13 +4162,14 @@ 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;
|
||||
context->init();
|
||||
context->first_name_resolution_table=
|
||||
context->last_name_resolution_table= tmp_table_ref;
|
||||
semi_join_conds_context= context;
|
||||
|
||||
for (uint i= 0; i < item_in->left_expr->cols(); i++)
|
||||
{
|
||||
|
@ -4227,6 +4298,223 @@ void subselect_hash_sj_engine::cleanup()
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Get fanout produced by tables specified in the table_map
|
||||
*/
|
||||
|
||||
double get_fanout_with_deps(JOIN *join, table_map tset)
|
||||
{
|
||||
/* Handle the case of "Impossible WHERE" */
|
||||
if (join->table_count == 0)
|
||||
return 0.0;
|
||||
|
||||
/* First, recursively get all tables we depend on */
|
||||
table_map deps_to_check= tset;
|
||||
table_map checked_deps= 0;
|
||||
table_map further_deps;
|
||||
do
|
||||
{
|
||||
further_deps= 0;
|
||||
Table_map_iterator tm_it(deps_to_check);
|
||||
int tableno;
|
||||
while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
|
||||
{
|
||||
/* get tableno's dependency tables that are not in needed_set */
|
||||
further_deps |= join->map2table[tableno]->ref.depend_map & ~checked_deps;
|
||||
}
|
||||
|
||||
checked_deps |= deps_to_check;
|
||||
deps_to_check= further_deps;
|
||||
} while (further_deps != 0);
|
||||
|
||||
|
||||
/* Now, walk the join order and calculate the fanout */
|
||||
double fanout= 1;
|
||||
for (JOIN_TAB *tab= first_top_level_tab(join, WITHOUT_CONST_TABLES); tab;
|
||||
tab= next_top_level_tab(join, tab))
|
||||
{
|
||||
if ((tab->table->map & checked_deps) && !tab->emb_sj_nest &&
|
||||
tab->records_read != 0)
|
||||
{
|
||||
fanout *= rows2double(tab->records_read);
|
||||
}
|
||||
}
|
||||
return fanout;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void check_out_index_stats(JOIN *join)
|
||||
{
|
||||
ORDER *order;
|
||||
uint n_order_items;
|
||||
|
||||
/*
|
||||
First, collect the keys that we can use in each table.
|
||||
We can use a key if
|
||||
- all tables refer to it.
|
||||
*/
|
||||
key_map key_start_use[MAX_TABLES];
|
||||
key_map key_infix_use[MAX_TABLES];
|
||||
table_map key_used=0;
|
||||
table_map non_key_used= 0;
|
||||
|
||||
bzero(&key_start_use, sizeof(key_start_use)); //psergey-todo: safe initialization!
|
||||
bzero(&key_infix_use, sizeof(key_infix_use));
|
||||
|
||||
for (order= join->group_list; order; order= order->next)
|
||||
{
|
||||
Item *item= order->item[0];
|
||||
|
||||
if (item->real_type() == Item::FIELD_ITEM)
|
||||
{
|
||||
if (item->used_tables() & OUTER_REF_TABLE_BIT)
|
||||
continue; /* outside references are like constants for us */
|
||||
|
||||
Field *field= ((Item_field*)item->real_item())->field;
|
||||
uint table_no= field->table->tablenr;
|
||||
if (!(non_key_used && table_map(1) << table_no) &&
|
||||
!field->part_of_key.is_clear_all())
|
||||
{
|
||||
key_map infix_map= field->part_of_key;
|
||||
infix_map.subtract(field->key_start);
|
||||
key_start_use[table_no].merge(field->key_start);
|
||||
key_infix_use[table_no].merge(infix_map);
|
||||
key_used |= table_no;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
Note: the below will cause clauses like GROUP BY YEAR(date) not to be
|
||||
handled.
|
||||
*/
|
||||
non_key_used |= item->used_tables();
|
||||
}
|
||||
|
||||
Table_map_iterator tm_it(key_used & ~non_key_used);
|
||||
int tableno;
|
||||
while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
|
||||
{
|
||||
key_map::iterator key_it(key_start_use);
|
||||
int keyno;
|
||||
while ((keyno = tm_it.next_bit()) != key_map::iterator::BITMAP_END)
|
||||
{
|
||||
for (order= join->group_list; order; order= order->next)
|
||||
{
|
||||
Item *item= order->item[0];
|
||||
if (item->used_tables() & (table_map(1) << tableno))
|
||||
{
|
||||
DBUG_ASSERT(item->real_type() == Item::FIELD_ITEM);
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (continuation)
|
||||
{
|
||||
walk through list and find which key parts are occupied;
|
||||
// note that the above can't be made any faster.
|
||||
}
|
||||
else
|
||||
use rec_per_key[0];
|
||||
|
||||
find out the cardinality.
|
||||
check if cardinality decreases if we use it;
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Get an estimate of how many records will be produced after the GROUP BY
|
||||
operation.
|
||||
|
||||
@param join Join we're operating on
|
||||
@param join_op_rows How many records will be produced by the join
|
||||
operations (this is what join optimizer produces)
|
||||
|
||||
@seealso
|
||||
See also optimize_semijoin_nests(), grep for "Adjust output cardinality
|
||||
estimates". Very similar code there that is not joined with this one
|
||||
because we operate on different data structs and too much effort is
|
||||
needed to abstract them out.
|
||||
|
||||
@return
|
||||
Number of records we expect to get after the GROUP BY operation
|
||||
*/
|
||||
|
||||
double get_post_group_estimate(JOIN* join, double join_op_rows)
|
||||
{
|
||||
table_map tables_in_group_list= table_map(0);
|
||||
|
||||
/* Find out which tables are used in GROUP BY list */
|
||||
for (ORDER *order= join->group_list; order; order= order->next)
|
||||
{
|
||||
Item *item= order->item[0];
|
||||
if (item->used_tables() & RAND_TABLE_BIT)
|
||||
{
|
||||
/* Each join output record will be in its own group */
|
||||
return join_op_rows;
|
||||
}
|
||||
tables_in_group_list|= item->used_tables();
|
||||
}
|
||||
tables_in_group_list &= ~PSEUDO_TABLE_BITS;
|
||||
|
||||
/*
|
||||
Use join fanouts to calculate the max. number of records in the group-list
|
||||
*/
|
||||
double fanout_rows[MAX_KEY];
|
||||
bzero(&fanout_rows, sizeof(fanout_rows));
|
||||
double out_rows;
|
||||
|
||||
out_rows= get_fanout_with_deps(join, tables_in_group_list);
|
||||
|
||||
#if 0
|
||||
/* The following will be needed when making use of index stats: */
|
||||
/*
|
||||
Also generate max. number of records for each of the tables mentioned
|
||||
in the group-list. We'll use that a baseline number that we'll try to
|
||||
reduce by using
|
||||
- #table-records
|
||||
- index statistics.
|
||||
*/
|
||||
Table_map_iterator tm_it(tables_in_group_list);
|
||||
int tableno;
|
||||
while ((tableno = tm_it.next_bit()) != Table_map_iterator::BITMAP_END)
|
||||
{
|
||||
fanout_rows[tableno]= get_fanout_with_deps(join, table_map(1) << tableno);
|
||||
}
|
||||
|
||||
/*
|
||||
Try to bring down estimates using index statistics.
|
||||
*/
|
||||
//check_out_index_stats(join);
|
||||
#endif
|
||||
|
||||
return out_rows;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Optimize the underlying subselect's join
|
||||
|
||||
@param out_rows OUT How many records we expect to get in the
|
||||
materialized table
|
||||
@param cost OUT Cost to materialize the subquery
|
||||
|
||||
@return
|
||||
0 OK
|
||||
1 Fatal error
|
||||
*/
|
||||
#if 0
|
||||
int subselect_hash_sj_engine::optimize(double *out_rows, double *cost)
|
||||
{
|
||||
DBUG_ENTER("subselect_hash_sj_engine::optimize");
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Execute a subquery IN predicate via materialization.
|
||||
|
||||
|
|
|
@ -37,26 +37,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,26 @@ 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;
|
||||
/*
|
||||
Set to TRUE if at optimization or execution time we determine that this
|
||||
item's value is a constant. We need this member because it is not possible
|
||||
|
@ -79,7 +79,6 @@ protected:
|
|||
*/
|
||||
bool forced_const;
|
||||
|
||||
public:
|
||||
/* A reference from inside subquery predicate to somewhere outside of it */
|
||||
class Ref_to_outside : public Sql_alloc
|
||||
{
|
||||
|
@ -161,6 +160,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(double *out_rows, double *cost);
|
||||
virtual bool exec();
|
||||
/*
|
||||
If subquery optimization or execution determines that the subquery has
|
||||
|
@ -348,6 +348,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
TABLE_LIST * const NO_JOIN_NEST=(TABLE_LIST*)0x1;
|
||||
|
||||
/*
|
||||
Possible methods to execute an IN predicate. These are set by the optimizer
|
||||
based on user-set optimizer switches, semantic analysis and cost comparison.
|
||||
|
@ -393,9 +395,11 @@ protected:
|
|||
all JOIN in UNION
|
||||
*/
|
||||
Item *expr;
|
||||
Item_in_optimizer *optimizer;
|
||||
bool was_null;
|
||||
bool abort_on_null;
|
||||
public:
|
||||
Item_in_optimizer *optimizer;
|
||||
protected:
|
||||
/* Used to trigger on/off conditions that were pushed down to subselect */
|
||||
bool *pushed_cond_guards;
|
||||
Comp_creator *func;
|
||||
|
@ -419,19 +423,13 @@ 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
|
||||
See also THD::emb_on_expr_nest.
|
||||
*/
|
||||
TABLE_LIST *emb_on_expr_nest;
|
||||
/*
|
||||
Location of the subquery predicate. It is either
|
||||
- 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;
|
||||
/*
|
||||
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
|
||||
|
@ -443,10 +441,31 @@ public:
|
|||
Same as above, but they also allow to scan the materialized table.
|
||||
*/
|
||||
bool sjm_scan_allowed;
|
||||
double jtbm_read_time;
|
||||
double jtbm_record_count;
|
||||
|
||||
/* A bitmap of possible execution strategies for an IN predicate. */
|
||||
uchar in_strategy;
|
||||
|
||||
bool is_jtbm_merged;
|
||||
|
||||
/*
|
||||
TRUE<=>this is a flattenable semi-join, false overwise.
|
||||
*/
|
||||
bool is_flattenable_semijoin;
|
||||
|
||||
/*
|
||||
Used to determine how this subselect item is represented in the item tree,
|
||||
in case there is a need to locate it there and replace with something else.
|
||||
Two options are possible:
|
||||
1. This item is there 'as-is'.
|
||||
1. This item is wrapped within Item_in_optimizer.
|
||||
*/
|
||||
Item *original_item()
|
||||
{
|
||||
return is_flattenable_semijoin ? (Item*)this : (Item*)optimizer;
|
||||
}
|
||||
|
||||
bool *get_cond_guard(int i)
|
||||
{
|
||||
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
|
||||
|
@ -463,8 +482,9 @@ 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),
|
||||
optimizer(0), abort_on_null(0),
|
||||
abort_on_null(0), optimizer(0),
|
||||
pushed_cond_guards(NULL), func(NULL), in_strategy(SUBS_NOT_TRANSFORMED),
|
||||
is_jtbm_merged(FALSE),
|
||||
upper_item(0)
|
||||
{}
|
||||
void cleanup();
|
||||
|
@ -501,6 +521,7 @@ public:
|
|||
void set_first_execution() { if (first_execution) first_execution= FALSE; }
|
||||
bool expr_cache_is_needed(THD *thd);
|
||||
|
||||
int optimize(double *out_rows, double *cost);
|
||||
/*
|
||||
Return the identifier that we could use to identify the subquery for the
|
||||
user.
|
||||
|
@ -572,6 +593,7 @@ public:
|
|||
THD * get_thd() { return thd; }
|
||||
virtual int prepare()= 0;
|
||||
virtual void fix_length_and_dec(Item_cache** row)= 0;
|
||||
//virtual int optimize(double *out_rows, double *cost) { DBUG_ASSERT(0); return 0; }
|
||||
/*
|
||||
Execute the engine
|
||||
|
||||
|
@ -808,7 +830,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. */
|
||||
|
@ -820,63 +842,35 @@ 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();
|
||||
Name_resolution_context *semi_join_conds_context;
|
||||
|
||||
|
||||
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(List<Item> *tmp_columns);
|
||||
bool init(List<Item> *tmp_columns, uint subquery_id);
|
||||
void cleanup();
|
||||
int prepare();
|
||||
//int optimize(double *out_rows, double *cost);
|
||||
int exec();
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
uint cols()
|
||||
|
@ -898,6 +892,38 @@ public:
|
|||
select_result_interceptor *result,
|
||||
bool temp= FALSE);
|
||||
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)
|
||||
{
|
||||
|
@ -2926,7 +2927,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)
|
||||
|
@ -4344,7 +4346,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 +
|
||||
|
@ -11287,7 +11289,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 */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
||||
|
|
|
@ -7759,7 +7759,6 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||
table_list= table_list->next_leaf, tablenr++)
|
||||
{
|
||||
TABLE *table= table_list->table;
|
||||
table->pos_in_table_list= table_list;
|
||||
if (first_select_table &&
|
||||
table_list->top_table() == first_select_table)
|
||||
{
|
||||
|
@ -7767,9 +7766,19 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
|
|||
first_select_table= 0;
|
||||
tablenr= 0;
|
||||
}
|
||||
setup_table_map(table, table_list, tablenr);
|
||||
if (table_list->process_index_hints(table))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (table_list->jtbm_subselect)
|
||||
{
|
||||
table_list->jtbm_table_no= tablenr;
|
||||
}
|
||||
else
|
||||
{
|
||||
table->pos_in_table_list= table_list;
|
||||
setup_table_map(table, table_list, tablenr);
|
||||
|
||||
if (table_list->process_index_hints(table))
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
if (tablenr > MAX_TABLES)
|
||||
{
|
||||
|
@ -7796,6 +7805,17 @@ 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->optimizer;
|
||||
if (table_list->jtbm_subselect->optimizer->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->optimizer);
|
||||
}
|
||||
}
|
||||
|
||||
/* Precompute and store the row types of NATURAL/USING joins. */
|
||||
|
@ -8217,7 +8237,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";
|
||||
|
|
|
@ -363,7 +363,6 @@ Sensitive_cursor::open(JOIN *join_arg)
|
|||
join= join_arg;
|
||||
THD *thd= join->thd;
|
||||
/* First non-constant table */
|
||||
JOIN_TAB *join_tab= join->join_tab + join->const_tables;
|
||||
DBUG_ENTER("Sensitive_cursor::open");
|
||||
|
||||
join->change_result(result);
|
||||
|
@ -381,26 +380,29 @@ 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;
|
||||
}
|
||||
|
||||
DBUG_ASSERT(join_tab->table->reginfo.not_exists_optimize == 0);
|
||||
DBUG_ASSERT(join_tab->not_used_in_distinct == 0);
|
||||
#ifndef DBUG_OFF
|
||||
JOIN_TAB *first_tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
|
||||
DBUG_ASSERT(first_tab->table->reginfo.not_exists_optimize == 0);
|
||||
DBUG_ASSERT(first_tab->not_used_in_distinct == 0);
|
||||
/*
|
||||
null_row is set only if row not found and it's outer join: should never
|
||||
happen for the first table in join_tab list
|
||||
*/
|
||||
DBUG_ASSERT(join_tab->table->null_row == 0);
|
||||
DBUG_ASSERT(first_tab->table->null_row == 0);
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -681,9 +681,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;
|
||||
}
|
||||
|
@ -3219,12 +3243,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);
|
||||
}
|
||||
|
@ -3279,6 +3298,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
|
||||
|
||||
|
@ -3295,9 +3357,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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3697,12 +3757,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;
|
||||
|
|
|
@ -3114,8 +3114,16 @@ bool st_select_lex::optimize_unflattened_subqueries()
|
|||
for (SELECT_LEX_UNIT *un= first_inner_unit(); un; un= un->next_unit())
|
||||
{
|
||||
Item_subselect *subquery_predicate= un->item;
|
||||
|
||||
if (subquery_predicate)
|
||||
{
|
||||
if (subquery_predicate->substype() == Item_subselect::IN_SUBS)
|
||||
{
|
||||
Item_in_subselect *in_subs=(Item_in_subselect*)subquery_predicate;
|
||||
if (in_subs->is_jtbm_merged)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
|
||||
{
|
||||
JOIN *inner_join= sl->join;
|
||||
|
|
1574
sql/sql_select.cc
1574
sql/sql_select.cc
File diff suppressed because it is too large
Load diff
111
sql/sql_select.h
111
sql/sql_select.h
|
@ -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,11 +363,11 @@ 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;
|
||||
uint n_sj_tables;
|
||||
|
||||
void cleanup();
|
||||
inline bool is_using_loose_index_scan()
|
||||
|
@ -450,9 +483,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);
|
||||
|
@ -600,6 +630,13 @@ 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
|
||||
{
|
||||
|
@ -652,20 +689,40 @@ protected:
|
|||
bool choose_tableless_subquery_plan();
|
||||
|
||||
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 */
|
||||
/**
|
||||
|
@ -692,7 +749,8 @@ public:
|
|||
/* Tables removed by table elimination. Set to 0 before the elimination. */
|
||||
table_map eliminated_tables;
|
||||
/*
|
||||
Bitmap of all inner tables from outer joins
|
||||
Bitmap of all inner tables from outer joins (set at start of
|
||||
make_join_statistics)
|
||||
*/
|
||||
table_map outer_join;
|
||||
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
|
||||
|
@ -741,7 +799,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
|
||||
|
@ -893,6 +950,10 @@ public:
|
|||
bool optimized; ///< flag to avoid double optimization in EXPLAIN
|
||||
bool initialized; ///< flag to avoid double init_execution calls
|
||||
|
||||
/*
|
||||
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;
|
||||
/*
|
||||
Additional WHERE and HAVING predicates to be considered for IN=>EXISTS
|
||||
|
@ -900,7 +961,7 @@ public:
|
|||
*/
|
||||
Item *in_to_exists_where;
|
||||
Item *in_to_exists_having;
|
||||
|
||||
|
||||
/* Temporary tables used to weed-out semi-join duplicates */
|
||||
List<TABLE> sj_tmp_tables;
|
||||
/* SJM nests that are executed with SJ-Materialization strategy */
|
||||
|
@ -933,7 +994,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;
|
||||
|
@ -990,7 +1052,6 @@ public:
|
|||
rollup.state= ROLLUP::STATE_NONE;
|
||||
|
||||
no_const_tables= FALSE;
|
||||
first_select= sub_select;
|
||||
outer_ref_cond= 0;
|
||||
in_to_exists_where= NULL;
|
||||
in_to_exists_having= NULL;
|
||||
|
@ -1056,7 +1117,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
|
||||
|
@ -1079,8 +1140,13 @@ public:
|
|||
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
|
||||
}
|
||||
bool choose_subquery_plan(table_map join_tables);
|
||||
void get_partial_join_cost(uint n_tables,
|
||||
double *read_time_arg, double *record_count_arg);
|
||||
void get_partial_cost_and_fanout(uint end_tab_idx,
|
||||
table_map filter_map,
|
||||
double *read_time_arg,
|
||||
double *record_count_arg);
|
||||
void get_prefix_cost_and_fanout(uint n_tables,
|
||||
double *read_time_arg,
|
||||
double *record_count_arg);
|
||||
/* defined in opt_subselect.cc */
|
||||
bool transform_max_min_subquery();
|
||||
/* True if this JOIN is a subquery under an IN predicate. */
|
||||
|
@ -1088,7 +1154,6 @@ public:
|
|||
{
|
||||
return (unit->item && unit->item->is_in_predicate());
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
TRUE if the query contains an aggregate function but has no GROUP
|
||||
|
@ -1099,6 +1164,15 @@ 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);
|
||||
|
||||
JOIN_TAB *first_top_level_tab(JOIN *join, enum enum_with_const_tables with_const);
|
||||
JOIN_TAB *next_top_level_tab(JOIN *join, JOIN_TAB *tab);
|
||||
|
||||
typedef struct st_select_check {
|
||||
uint const_ref,reg_ref;
|
||||
|
@ -1351,6 +1425,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)
|
||||
{
|
||||
|
|
|
@ -6637,14 +6637,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;
|
||||
|
|
|
@ -137,6 +137,11 @@ select_union::create_result_table(THD *thd_arg, List<Item> *column_types,
|
|||
(ORDER*) 0, is_union_distinct, 1,
|
||||
options, HA_POS_ERROR, (char*) alias)))
|
||||
return TRUE;
|
||||
//psergey-merge-fix:
|
||||
table->keys_in_use_for_query.clear_all();
|
||||
for (uint i=0; i < table->s->fields; i++)
|
||||
table->field[i]->flags &= ~PART_KEY_FLAG;
|
||||
|
||||
table->file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
return FALSE;
|
||||
|
@ -712,7 +717,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
|
@ -5345,6 +5345,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.
|
||||
|
||||
|
|
22
sql/table.h
22
sql/table.h
|
@ -66,7 +66,8 @@ typedef struct st_order {
|
|||
bool counter_used; /* parameter was counter of columns */
|
||||
Field *field; /* If tmp-table group */
|
||||
char *buff; /* If tmp-table group */
|
||||
table_map used, depend_map;
|
||||
table_map used; /* NOTE: the below is only set to 0 but is still used by eq_ref_table */
|
||||
table_map depend_map;
|
||||
} ORDER;
|
||||
|
||||
/**
|
||||
|
@ -966,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");
|
||||
|
@ -1194,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)
|
||||
|
@ -1213,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;
|
||||
|
@ -1255,8 +1264,15 @@ 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;
|
||||
uint jtbm_table_no;
|
||||
|
||||
SJ_MATERIALIZATION_INFO *sj_mat_info;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue