mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
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.
This commit is contained in:
@@ -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
|
||||
|
Reference in New Issue
Block a user