mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 10:14:19 +01:00
b917fb63a6
Analysis: The queries in question use the [unique | index]_subquery execution methods. These methods reuse the ref keys constructed by create_ref_for_key(). The way create_ref_for_key() works is that it doesn't store in ref.key_copy[] store_key elements that represent constants. In particular it doesn't store the store_key for NULL constants. The execution of [unique | index]_subquery calls subselect_uniquesubquery_engine::copy_ref_key, which in addition to copy the left IN argument into a index lookup key, is supposed to detect if the left IN argument contains NULLs. Since the store_key for the NULL constant is not copied into the key array, the null is not detected, and execution erroneously proceeds as if it should look for a complete match. Solution: The solution (unlike MySQL) is to reuse already computed information about NULL presence. Item_in_optimizer::val_int already finds out if the left IN operand contains NULLs. The fix propagates this to the execution methods subselect_[unique | index]subquery_engine::exec so it knows if there were NULL values independent of the presence of keys. In addition the patch siplifies copy_ref_key() and the logic that hanldes the case of NULLs in the left IN operand.
282 lines
10 KiB
Text
282 lines
10 KiB
Text
#
|
|
# Bug #46791: Assertion failed:(table->key_read==0),function unknown
|
|
# function,file sql_base.cc
|
|
#
|
|
CREATE TABLE t1 (a INT, b INT, KEY(a));
|
|
INSERT INTO t1 VALUES (1,1),(2,2);
|
|
CREATE TABLE t2 LIKE t1;
|
|
INSERT INTO t2 VALUES (1,1),(2,2);
|
|
CREATE TABLE t3 LIKE t1;
|
|
# should have 1 impossible where and 2 dependent subqueries
|
|
EXPLAIN
|
|
SELECT 1 FROM t1
|
|
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
|
|
ORDER BY count(*);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 index NULL a 5 NULL 2 Using index; Using temporary
|
|
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
|
|
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
|
|
# should not crash the next statement
|
|
SELECT 1 FROM t1
|
|
WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
|
|
ORDER BY count(*);
|
|
1
|
|
1
|
|
# should not crash: the crash is caused by the previous statement
|
|
SELECT 1;
|
|
1
|
|
1
|
|
DROP TABLE t1,t2,t3;
|
|
#
|
|
# Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
|
|
# query
|
|
#
|
|
CREATE TABLE t1 (
|
|
a INT,
|
|
b INT,
|
|
PRIMARY KEY (a),
|
|
KEY b (b)
|
|
);
|
|
INSERT INTO t1 VALUES (1, 1), (2, 1);
|
|
CREATE TABLE t2 LIKE t1;
|
|
INSERT INTO t2 SELECT * FROM t1;
|
|
CREATE TABLE t3 LIKE t1;
|
|
INSERT INTO t3 SELECT * FROM t1;
|
|
# Should not crash.
|
|
# Should have 1 impossible where and 2 dependent subqs.
|
|
EXPLAIN
|
|
SELECT
|
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
|
FROM t3 WHERE 1 = 0 GROUP BY 1;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
|
|
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using index
|
|
2 DEPENDENT SUBQUERY t2 index b b 5 NULL 2 Using where; Using index; Using join buffer
|
|
# should return 0 rows
|
|
SELECT
|
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
|
FROM t3 WHERE 1 = 0 GROUP BY 1;
|
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
|
DROP TABLE t1,t2,t3;
|
|
End of 5.0 tests.
|
|
CREATE TABLE t1 (col_int_nokey int(11) NOT NULL, col_varchar_nokey varchar(1) NOT NULL) engine=myisam;
|
|
INSERT INTO t1 VALUES (2,'s'),(0,'v'),(2,'s');
|
|
CREATE TABLE t2 (
|
|
pk int(11) NOT NULL AUTO_INCREMENT,
|
|
`col_int_key` int(11) NOT NULL,
|
|
col_varchar_key varchar(1) NOT NULL,
|
|
PRIMARY KEY (pk),
|
|
KEY `col_int_key` (`col_int_key`),
|
|
KEY `col_varchar_key` (`col_varchar_key`)
|
|
) ENGINE=MyISAM;
|
|
INSERT INTO t2 VALUES (4,10,'g'), (5,20,'v');
|
|
SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1;
|
|
col_int_nokey sub
|
|
2 10
|
|
0 NULL
|
|
2 10
|
|
SELECT t1.col_int_nokey,(SELECT MIN( t2_a.col_int_key ) +1 FROM t2 t2_a, t2 t2_b, t1 t1_a WHERE t1_a.col_varchar_nokey = t2_b.col_varchar_key and t1.col_int_nokey ) as sub FROM t1;
|
|
col_int_nokey sub
|
|
2 11
|
|
0 NULL
|
|
2 11
|
|
DROP TABLE t1,t2;
|
|
#
|
|
# Bug#54568: create view cause Assertion failed: 0,
|
|
# file .\item_subselect.cc, line 836
|
|
#
|
|
EXPLAIN SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
|
Warnings:
|
|
Note 1249 Select 2 was reduced during optimization
|
|
DESCRIBE SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
|
Warnings:
|
|
Note 1249 Select 2 was reduced during optimization
|
|
# None of the below should crash
|
|
CREATE VIEW v1 AS SELECT 1 LIKE ( 1 IN ( SELECT 1 ) );
|
|
CREATE VIEW v2 AS SELECT 1 LIKE '%' ESCAPE ( 1 IN ( SELECT 1 ) );
|
|
DROP VIEW v1, v2;
|
|
#
|
|
# Bug#51070: Query with a NOT IN subquery predicate returns a wrong
|
|
# result set
|
|
#
|
|
CREATE TABLE t1 ( a INT, b INT );
|
|
INSERT INTO t1 VALUES ( 1, NULL ), ( 2, NULL );
|
|
CREATE TABLE t2 ( c INT, d INT );
|
|
INSERT INTO t2 VALUES ( NULL, 3 ), ( NULL, 4 );
|
|
CREATE TABLE t3 ( e INT, f INT );
|
|
INSERT INTO t3 VALUES ( NULL, NULL ), ( NULL, NULL );
|
|
CREATE TABLE t4 ( a INT );
|
|
INSERT INTO t4 VALUES (1), (2), (3);
|
|
CREATE TABLE t5 ( a INT );
|
|
INSERT INTO t5 VALUES (NULL), (2);
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
x PRIMARY x x x x x x x x
|
|
x DEPENDENT SUBQUERY x x x x x x x x
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
|
a b
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
|
|
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS NULL;
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
SELECT * FROM t1 WHERE ( a, b ) IN ( SELECT c, d FROM t2 ) IS NULL;
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT c, d FROM t2 ) IS UNKNOWN;
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
SELECT * FROM t1 WHERE (( a, b ) NOT IN ( SELECT c, d FROM t2 )) IS UNKNOWN;
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
SELECT * FROM t1 WHERE 1 = 1 AND ( a, b ) NOT IN ( SELECT c, d FROM t2 );
|
|
a b
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
x PRIMARY x x x x x x x x
|
|
x DEPENDENT SUBQUERY x x x x x x x x
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN ( SELECT e, f FROM t3 );
|
|
a b
|
|
EXPLAIN
|
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
x PRIMARY x x x x x x x x
|
|
x DEPENDENT SUBQUERY x x x x x x x x
|
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT a, b FROM t1 );
|
|
c d
|
|
EXPLAIN
|
|
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
x PRIMARY x x x x x x x x
|
|
x DEPENDENT SUBQUERY x x x x x x x x
|
|
SELECT * FROM t3 WHERE ( e, f ) NOT IN ( SELECT c, d FROM t2 );
|
|
e f
|
|
EXPLAIN
|
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
x PRIMARY x x x x x x x x
|
|
x DEPENDENT SUBQUERY x x x x x x x x
|
|
SELECT * FROM t2 WHERE ( c, d ) NOT IN ( SELECT e, f FROM t3 );
|
|
c d
|
|
SELECT * FROM t1 WHERE ( a, b ) NOT IN
|
|
( SELECT c, d FROM t2 WHERE c = 1 AND c <> 1 );
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
SELECT * FROM t1 WHERE b NOT IN ( SELECT c FROM t2 WHERE c = 1 );
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
SELECT * FROM t1 WHERE NULL NOT IN ( SELECT c FROM t2 WHERE c = 1 AND c <> 1 );
|
|
a b
|
|
1 NULL
|
|
2 NULL
|
|
DROP TABLE t1, t2, t3, t4, t5;
|
|
#
|
|
# Bug#58207: invalid memory reads when using default column value and
|
|
# tmptable needed
|
|
#
|
|
CREATE TABLE t(a VARCHAR(245) DEFAULT
|
|
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
|
|
INSERT INTO t VALUES (''),(''),(''),(''),(''),(''),(''),(''),(''),(''),('');
|
|
SELECT * FROM (SELECT default(a) FROM t GROUP BY a) d;
|
|
default(a)
|
|
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
|
DROP TABLE t;
|
|
#
|
|
# LP BUG#1009187, MDEV-373, MYSQL bug#58628
|
|
# Wrong result for a query with [NOT] IN subquery predicate if
|
|
# the left part of the predicate is explicit NULL
|
|
#
|
|
CREATE TABLE t1 (pk INT NOT NULL, i INT NOT NULL);
|
|
INSERT INTO t1 VALUES (0,10), (1,20), (2,30), (3,40);
|
|
CREATE TABLE t2a (pk INT NOT NULL, i INT NOT NULL, PRIMARY KEY(i,pk));
|
|
INSERT INTO t2a VALUES (0,0), (1,1), (2,2), (3,3);
|
|
CREATE TABLE t2b (pk INT, i INT);
|
|
INSERT INTO t2b VALUES (0,0), (1,1), (2,2), (3,3);
|
|
CREATE TABLE t2c (pk INT NOT NULL, i INT NOT NULL);
|
|
INSERT INTO t2c VALUES (0,0), (1,1), (2,2), (3,3);
|
|
create index it2c on t2c (i,pk);
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
|
|
2 DEPENDENT SUBQUERY t2a unique_subquery PRIMARY PRIMARY 8 const,test.t1.pk 1 Using index; Using where; Full scan on NULL key
|
|
SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk);
|
|
pk i
|
|
SELECT * FROM t1 WHERE 1+NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk);
|
|
pk i
|
|
SELECT * FROM t1 WHERE NULL IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) IS UNKNOWN;
|
|
pk i
|
|
0 10
|
|
1 20
|
|
2 30
|
|
3 40
|
|
SELECT t1.pk, NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk) FROM t1;
|
|
pk NULL NOT IN (SELECT t2a.i FROM t2a WHERE t2a.pk = t1.pk)
|
|
0 NULL
|
|
1 NULL
|
|
2 NULL
|
|
3 NULL
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
|
|
2 DEPENDENT SUBQUERY t2b ALL NULL NULL NULL NULL 4 Using where
|
|
SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk);
|
|
pk i
|
|
SELECT * FROM t1 WHERE NULL IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) IS UNKNOWN;
|
|
pk i
|
|
0 10
|
|
1 20
|
|
2 30
|
|
3 40
|
|
SELECT t1.pk, NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk) FROM t1;
|
|
pk NULL NOT IN (SELECT t2b.i FROM t2b WHERE t2b.pk = t1.pk)
|
|
0 NULL
|
|
1 NULL
|
|
2 NULL
|
|
3 NULL
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
|
|
2 DEPENDENT SUBQUERY t2c index_subquery it2c it2c 8 const,test.t1.pk 2 Using index; Using where; Full scan on NULL key
|
|
SELECT * FROM t1 WHERE NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk);
|
|
pk i
|
|
SELECT * FROM t1 WHERE NULL IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) IS UNKNOWN;
|
|
pk i
|
|
0 10
|
|
1 20
|
|
2 30
|
|
3 40
|
|
SELECT t1.pk, NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk) FROM t1;
|
|
pk NULL NOT IN (SELECT t2c.i FROM t2c WHERE t2c.pk = t1.pk)
|
|
0 NULL
|
|
1 NULL
|
|
2 NULL
|
|
3 NULL
|
|
EXPLAIN
|
|
SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
|
|
2 DEPENDENT SUBQUERY t2a eq_ref PRIMARY PRIMARY 8 const,test.t1.pk 2 Using where; Using index; Full scan on NULL key
|
|
SELECT * FROM t1 WHERE (NULL, 1) NOT IN (SELECT t2a.i, t2a.pk FROM t2a WHERE t2a.pk = t1.pk);
|
|
pk i
|
|
drop table t1, t2a, t2b, t2c;
|
|
#
|
|
# End of 5.1 tests.
|
|
#
|