Commit 33d8d316 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #939009.

The result of materialization of the right part of an IN subquery predicate
is placed into a temporary table. Each row of the materialized table is
distinct. A unique key over all fields of the temporary table is defined and
created. It allows to perform key look-ups into the table.
The table created for a materialized subquery can be accessed by key as
any other table. The function best_access-path search for the best access
to join a table to a given partial join. With some where conditions this
function considers a possibility of a ref_or_null access. If such access
employs the unique key on the temporary table then when estimating
the cost this access the function tries to use the array rec_per_key. Yet,
such array is not built for this unique key. This causes a crash of the server.

Rows returned by the subquery that contain nulls don't have to be placed
into temporary table, as they cannot be match any row produced by the
left part of the subquery predicate. So all fields of the temporary table
can be defined as non-nullable. In this case any ref_or_null access
to the temporary table does not make any sense and it does not make sense
to estimate such an access.

The fix makes sure that the temporary table for a materialized IN subquery
is defined with columns that are all non-nullable. The also ensures that 
any row with nulls returned by the subquery is not placed into the
temporary table.  
parent e5414ab5
......@@ -1458,14 +1458,14 @@ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t ref PRIMARY,c c 4 func 2 Using where; Using index
2 DEPENDENT SUBQUERY t eq_ref PRIMARY,c PRIMARY 4 func 1 Using where
EXPLAIN
SELECT * FROM t1 , t2
WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY t3 ref PRIMARY,c c 4 func 2 Using where; Using index
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,c PRIMARY 4 func 1 Using where
SELECT * FROM t1 , t2
WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
b a
......
......@@ -1845,7 +1845,7 @@ NULL
EXPLAIN EXTENDED
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
......
......@@ -2407,7 +2407,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8 Using where
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 8
1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 Using index
2 MATERIALIZED t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
......
......@@ -2973,7 +2973,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cac
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
......@@ -3563,7 +3563,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
......@@ -3575,7 +3575,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
DROP TABLE t1;
create table t1( f1 int,f2 int);
......@@ -4471,14 +4471,14 @@ SET @save_join_cache_level=@@join_cache_level;
SET join_cache_level=0;
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> const distinct_key distinct_key 5 const 1 100.00
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
Note 1003 select 1 AS `1` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`min(a)` = 1)
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> const distinct_key distinct_key 5 const 1 100.00
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
......@@ -5585,7 +5585,7 @@ WHERE col_varchar_nokey IN
(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index
SELECT col_int_nokey FROM ot
WHERE col_varchar_nokey IN
......@@ -5598,7 +5598,7 @@ WHERE (col_varchar_nokey, 'x') IN
(SELECT col_varchar_key, col_varchar_key2 FROM it2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index
SELECT col_int_nokey FROM ot
WHERE (col_varchar_nokey, 'x') IN
......
......@@ -1249,7 +1249,7 @@ EXPLAIN
SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
......@@ -1258,7 +1258,7 @@ c1 c1 c1
EXPLAIN
SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where
......
......@@ -1473,7 +1473,7 @@ SET @@optimizer_switch='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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED 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
......@@ -1861,6 +1861,39 @@ WHERE 'condition'='impossible'
MIN(a)
NULL
DROP TABLE t1;
#
# BUG#939009: Crash with aggregate function in IN subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='materialization=on,semijoin=on';
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
CREATE TABLE t2 ( c INT );
INSERT INTO t2 VALUES (4), (7), (6);
EXPLAIN EXTENDED
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (`test`.`t1`.`b` = 7) and (isnull(`<subquery2>`.`MAX(c)`) or (`<subquery2>`.`MAX(c)` = 7)))
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
EXPLAIN
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 Using where
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
a b
SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
# This must be at the end:
set optimizer_switch=@subselect_sj_mat_tmp;
set join_cache_level=@save_join_cache_level;
......@@ -1983,7 +2016,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
pk
......
......@@ -348,7 +348,7 @@ FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
AND Language IN ('English','Spanish');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage range Language Language 30 NULL 72 Using index condition; Using where; Rowid-ordered scan
2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 2 Using index condition; Using where
2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 1 Using index condition; Using where
2 DEPENDENT SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using index
select count(*)
from CountryLanguage
......
......@@ -2979,7 +2979,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optim
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
......@@ -3569,7 +3569,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
......@@ -3581,7 +3581,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
DROP TABLE t1;
create table t1( f1 int,f2 int);
......@@ -4477,14 +4477,14 @@ SET @save_join_cache_level=@@join_cache_level;
SET join_cache_level=0;
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> const distinct_key distinct_key 5 const 1 100.00
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
Note 1003 select 1 AS `1` from <materialize> (select min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`min(a)` = 1)
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT min(a) FROM t1 WHERE a > 3 GROUP BY a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> const distinct_key distinct_key 5 const 1 100.00
1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
......@@ -5591,7 +5591,7 @@ WHERE col_varchar_nokey IN
(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it1 ref idx_cvk_cik idx_cvk_cik 9 const,const 1 Using where; Using index
SELECT col_int_nokey FROM ot
WHERE col_varchar_nokey IN
......@@ -5604,7 +5604,7 @@ WHERE (col_varchar_nokey, 'x') IN
(SELECT col_varchar_key, col_varchar_key2 FROM it2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
2 MATERIALIZED it2 ref idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 const,const 1 Using where; Using index
SELECT col_int_nokey FROM ot
WHERE (col_varchar_nokey, 'x') IN
......
......@@ -802,7 +802,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f
EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func,func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 11 func,func 1 100.00
2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan
Warnings:
Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
......@@ -1053,8 +1053,8 @@ AND t1.val IN (SELECT t3.val FROM t3
WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 14 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 14 func 1
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 13 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func 1
3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
SELECT *
......@@ -1633,9 +1633,9 @@ select * from t1 A, t1 B
where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY A ALL NULL NULL NULL NULL 3
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED C ALL NULL NULL NULL NULL 3
3 MATERIALIZED D ALL NULL NULL NULL NULL 3
drop table t1, t2;
......@@ -2323,7 +2323,7 @@ explain
SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t3 ALL NULL NULL NULL NULL 13 Using where
2 MATERIALIZED t2 ref b b 4 test.t3.a 1 Using index
SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
......@@ -2443,7 +2443,7 @@ EXPLAIN
SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
......
......@@ -183,7 +183,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it ALL NULL NULL NULL NULL 32
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -251,7 +251,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it ALL NULL NULL NULL NULL 52
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -292,7 +292,7 @@ from t0 where a in
(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 Using where
2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index
2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index
2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index
......@@ -721,7 +721,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t3 index a a 5 NULL 30000 Using index
select count(a) from t2 where a in ( SELECT a FROM t3);
count(a)
......@@ -878,7 +878,7 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
WHERE t3.b IN (SELECT b FROM t4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2
......
......@@ -133,7 +133,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t2 index b b 5 NULL 20 Using index
select * from t1;
a b
......@@ -195,7 +195,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it ALL NULL NULL NULL NULL 32
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -263,7 +263,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it ALL NULL NULL NULL NULL 52
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -304,7 +304,7 @@ from t0 where a in
(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 Using where
2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index
2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index
2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index
......@@ -735,7 +735,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t3 index a a 5 NULL 30000 Using index
select count(a) from t2 where a in ( SELECT a FROM t3);
count(a)
......@@ -892,7 +892,7 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
WHERE t3.b IN (SELECT b FROM t4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t3.a 1 Using where; Using join buffer (flat, BNLH join)
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2
......@@ -990,7 +990,7 @@ EXPLAIN
SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1
SELECT * FROM t1 WHERE b IN (SELECT a FROM t2 GROUP BY a);
a b
......@@ -999,7 +999,7 @@ EXPLAIN
SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY <subquery2> hash_ALL distinct_key #hash#distinct_key 5 test.t1.b 1 Using join buffer (flat, BNLH join)
1 PRIMARY <subquery2> hash_ALL distinct_key #hash#distinct_key 4 test.t1.b 1 Using join buffer (flat, BNLH join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 1 Using temporary
SELECT * FROM t1 WHERE b IN (SELECT max(a) FROM t2 GROUP BY a);
a b
......
......@@ -185,7 +185,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it ALL NULL NULL NULL NULL 32
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -253,7 +253,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED it ALL NULL NULL NULL NULL 52
select
a, mid(filler1, 1,10), length(filler1)=length(filler2)
......@@ -294,7 +294,7 @@ from t0 where a in
(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func 1 Using where
2 MATERIALIZED t1 index a a 5 NULL 10 Using where; Using index
2 MATERIALIZED t2 ref a a 5 test.t1.a 1 Using index
2 MATERIALIZED t3 ref a a 5 test.t1.a 1 Using index
......@@ -723,7 +723,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 <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t3 index a a 5 NULL 30000 Using index
select count(a) from t2 where a in ( SELECT a FROM t3);
count(a)
......@@ -880,7 +880,7 @@ SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
WHERE t3.b IN (SELECT b FROM t4);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2
......
......@@ -815,7 +815,7 @@ INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii','iiii','ffff','ffff','ffff','f
EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func,func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 11 func,func 1 100.00
2 MATERIALIZED t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan
Warnings:
Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`pk` > 0))
......@@ -1066,8 +1066,8 @@ AND t1.val IN (SELECT t3.val FROM t3
WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 14 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 14 func 1
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 13 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 13 func 1
3 MATERIALIZED t3 ALL NULL NULL NULL NULL 5 Using where
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 6 Using where
SELECT *
......@@ -1646,9 +1646,9 @@ select * from t1 A, t1 B
where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY A ALL NULL NULL NULL NULL 3
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED C ALL NULL NULL NULL NULL 3
3 MATERIALIZED D ALL NULL NULL NULL NULL 3
drop table t1, t2;
......@@ -1993,7 +1993,7 @@ explain extended
SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (incremental, BNL join)
2 MATERIALIZED t4 index f2 f2 5 NULL 2 100.00 Using index
......@@ -2337,7 +2337,7 @@ explain
SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
2 MATERIALIZED t3 ALL NULL NULL NULL NULL 13 Using where
2 MATERIALIZED t2 ref b b 4 test.t3.a 1 Using index
SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
......@@ -2457,7 +2457,7 @@ EXPLAIN
SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 RIGHT JOIN t2 ON b = a WHERE t2.b IN (SELECT c FROM t3);
......@@ -2773,7 +2773,7 @@ SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
WHERE (a, b) IN (SELECT a, b FROM t1 t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index
2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
......@@ -2788,7 +2788,7 @@ SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
WHERE (a, b) IN (SELECT a, b FROM t1 t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where
2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
......@@ -2804,7 +2804,7 @@ SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
WHERE (a, b) IN (SELECT a, b FROM t1 t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index
2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
SELECT * FROM t1 LEFT JOIN t2 ON (c = b)
......@@ -2819,7 +2819,7 @@ SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
WHERE (a, b) IN (SELECT a, b FROM t1 t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL idx_a NULL NULL NULL 3
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1
1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
2 MATERIALIZED t ALL idx_a NULL NULL NULL 3
SELECT * FROM t1 LEFT JOIN t3 ON (c = b)
......
This diff is collapsed.
......@@ -40,14 +40,14 @@ alter table t3 add primary key(a);
# (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 <subquery2> ALL distinct_key NULL NULL NULL 5
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
2 MATERIALIZED 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 <subquery2> ALL distinct_key NULL NULL NULL 50
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
......@@ -57,7 +57,7 @@ SET optimizer_switch='outer_join_with_cache=off';
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 <subquery2> ALL distinct_key NULL NULL NULL 50
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using temporary
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using where
......@@ -69,7 +69,7 @@ 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
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t4.a 1
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
2 MATERIALIZED 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;
......@@ -77,8 +77,8 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 5
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using join buffer (flat, BNL join)
1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
3 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 Using temporary
3 MATERIALIZED t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
......@@ -114,7 +114,7 @@ insert into t1 select A.a + 10*B.a + 100*C.a from t0 A, t0 B, t0 C;
# The following must use non-merged SJ-Materialization:
explain select * from t1 X join t0 Y on X.a < Y.a where X.a in (select max(a) from t0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 Using where
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1
1 PRIMARY X ref a a 5 <subquery2>.max(a) 1 Using index
1 PRIMARY Y ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10
......
......@@ -2256,7 +2256,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE
a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 15 Using where
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 15
1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 1 Using index
2 MATERIALIZED t1 index NULL a 10 NULL 15 Using index
EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING
......
......@@ -2842,7 +2842,7 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cac
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 10 func,func 1 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
......@@ -3435,7 +3435,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
ALTER TABLE t1 ADD INDEX(a);
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
......@@ -3447,7 +3447,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL a NULL NULL NULL 9 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 23 test.t1.a,test.t1.b 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 21 test.t1.a,test.t1.b 1
2 MATERIALIZED t1 ALL NULL NULL NULL NULL 9 Using temporary
DROP TABLE t1;
create table t1( f1 int,f2 int);
......
......@@ -1559,6 +1559,35 @@ WHERE a IN (
DROP TABLE t1;
--echo #
--echo # BUG#939009: Crash with aggregate function in IN subquery
--echo #
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='materialization=on,semijoin=on';
CREATE TABLE t1 (a int, b int);
INSERT INTO t1 VALUES (7,1), (4,2), (7,7);
CREATE TABLE t2 ( c INT );
INSERT INTO t2 VALUES (4), (7), (6);
EXPLAIN EXTENDED
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
EXPLAIN
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2 WHERE c < 4) AND b=7 AND (a IS NULL OR a=b);
SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
--echo # This must be at the end:
set optimizer_switch=@subselect_sj_mat_tmp;
set join_cache_level=@save_join_cache_level;
......
......@@ -117,6 +117,11 @@ static void do_outer_field_to_null_str(Copy_field *copy)
int
set_field_to_null(Field *field)
{
if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
{
field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS;
return -1;
}
if (field->real_maybe_null())
{
field->set_null();
......@@ -160,6 +165,11 @@ set_field_to_null(Field *field)
int
set_field_to_null_with_conversions(Field *field, bool no_conversions)
{
if (field->table->null_catch_flags & CHECK_ROW_FOR_NULLS_TO_REJECT)
{
field->table->null_catch_flags|= REJECT_ROW_DUE_TO_NULL_FIELDS;
return -1;
}
if (field->real_maybe_null())
{
field->set_null();
......
......@@ -4180,6 +4180,11 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
memcpy(name, buf, len+1);
result_sink->get_tmp_table_param()->materialized_subquery= true;
if (item->substype() == Item_subselect::IN_SUBS &&
((Item_in_subselect*)item)->is_jtbm_merged)
{
result_sink->get_tmp_table_param()->force_not_null_cols= true;
}
if (result_sink->create_result_table(thd, tmp_columns, TRUE,
tmp_create_options,
name, TRUE, TRUE))
......
......@@ -3167,6 +3167,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
sjm->sjm_table_cols.push_back(*p_item);
sjm->sjm_table_param.field_count= subq_select->item_list.elements;
sjm->sjm_table_param.force_not_null_cols= TRUE;
if (!(sjm->table= create_tmp_table(thd, &sjm->sjm_table_param,
sjm->sjm_table_cols, (ORDER*) 0,
......
......@@ -3195,6 +3195,11 @@ int select_materialize_with_stats::send_data(List<Item> &items)
if ((res= select_union::send_data(items)))
return res;
if (table->null_catch_flags & REJECT_ROW_DUE_TO_NULL_FIELDS)
{
table->null_catch_flags&= ~REJECT_ROW_DUE_TO_NULL_FIELDS;
return 0;
}
/* Skip duplicate rows. */
if (write_err == HA_ERR_FOUND_DUPP_KEY ||
write_err == HA_ERR_FOUND_DUPP_UNIQUE)
......@@ -3236,6 +3241,7 @@ void TMP_TABLE_PARAM::init()
precomputed_group_by= 0;
bit_fields_as_long= 0;
materialized_subquery= 0;
force_not_null_cols= 0;
skip_create_table= 0;
DBUG_VOID_RETURN;
}
......
......@@ -3081,6 +3081,8 @@ class TMP_TABLE_PARAM :public Sql_alloc
bool schema_table;
/* TRUE if the temp table is created for subquery materialization. */
bool materialized_subquery;
/* TRUE if all columns of the table are guaranteed to be non-nullable */
bool force_not_null_cols;
/*
True if GROUP BY and its aggregate functions are already computed
by a table access method (e.g. by loose index scan). In this case
......@@ -3104,7 +3106,8 @@ class TMP_TABLE_PARAM :public Sql_alloc
TMP_TABLE_PARAM()
:copy_field(0), group_parts(0),
group_length(0), group_null_parts(0), convert_blob_length(0),
schema_table(0), materialized_subquery(0), precomputed_group_by(0),
schema_table(0), materialized_subquery(0), force_not_null_cols(0),
precomputed_group_by(0),
force_copy_fields(0), bit_fields_as_long(0), skip_create_table(0)
{}
~TMP_TABLE_PARAM()
......
......@@ -3769,6 +3769,8 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
{
/* field = expression OR field IS NULL */
old->level= and_level;
if (old->field->maybe_null())
{
old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
/*
Remember the NOT NULL value unless the value does not depend
......@@ -3779,6 +3781,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
/* The referred expression can be NULL: */
old->null_rejecting= 0;
}
}
else
{
/*
......@@ -13577,6 +13580,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
table->merge_keys.init();
table->intersect_keys.init();
table->keys_in_use_for_query.init();
table->no_rows_with_nulls= param->force_not_null_cols;
table->s= share;
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
......@@ -13656,6 +13660,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
thd->mem_root= mem_root_save;
arg= sum_item->set_arg(i, thd, new Item_field(new_field));
thd->mem_root= &table->mem_root;
if (param->force_not_null_cols)
{
new_field->flags|= NOT_NULL_FLAG;
new_field->null_ptr= NULL;
}
if (!(new_field->flags & NOT_NULL_FLAG))
{
null_count++;
......@@ -13731,6 +13740,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
agg_item->result_field= new_field;
}
tmp_from_field++;
if (param->force_not_null_cols)
{
new_field->flags|= NOT_NULL_FLAG;
new_field->null_ptr= NULL;
}
reclength+=new_field->pack_length();
if (!(new_field->flags & NOT_NULL_FLAG))
null_count++;
......
......@@ -57,9 +57,17 @@ int select_union::send_data(List<Item> &values)
unit->offset_limit_cnt--;
return 0;
}
if (table->no_rows_with_nulls)
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
fill_record(thd, table->field, values, TRUE, FALSE);
if (thd->is_error())
return 1;
if (table->no_rows_with_nulls)
{
table->null_catch_flags&= ~CHECK_ROW_FOR_NULLS_TO_REJECT;
if (table->null_catch_flags)
return 0;
}
if ((write_err= table->file->ha_write_tmp_row(table->record[0])))
{
......
......@@ -665,6 +665,9 @@ enum index_hint_type
INDEX_HINT_FORCE
};
#define CHECK_ROW_FOR_NULLS_TO_REJECT (1 << 0)
#define REJECT_ROW_DUE_TO_NULL_FIELDS (1 << 1)
struct st_table {
st_table() {} /* Remove gcc warning */
......@@ -807,6 +810,26 @@ struct st_table {
NULL, including columns declared as "not null" (see maybe_null).
*/
bool null_row;
/*
No rows that contain null values can be placed into this table.
Currently this flag can be set to true only for a temporary table
that used to store the result of materialization of a subquery.
*/
bool no_rows_with_nulls;
/*
This field can contain two bit flags:
CHECK_ROW_FOR_NULLS_TO_REJECT
REJECT_ROW_DUE_TO_NULL_FIELDS
The first flag is set for the dynamic contexts where it is prohibited
to write any null into the table.
The second flag is set only if the first flag is set on.
The informs the outer scope that there was an attept to write null
into a field of the table in the context where it is prohibited.
This flag should be set off as soon as the first flag is set on.
Currently these flags are used only the tables tno_rows_with_nulls set
to true.
*/
uint8 null_catch_flags;
/*
TODO: Each of the following flags take up 8 bits. They can just as easily
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment