You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MDEV-36389 Incorrect query results for an indexed text column
Fixes a scenario where an IN subquery returned the wrong result
because the pushed WHERE clause was not retained for downstream
result filtering. For example:
CREATE TABLE t1 (c1 TEXT, UNIQUE (c1(1)));
INSERT INTO t1 (c1) VALUES ('a');
SELECT 'abc' IN (SELECT c1 FROM t1);
Internally, he 'abc' IN subquery condition becomes the constant
condition:
'abc' = t1.c1 or t1.c1 is null
Prior to this patch, this condition was incorrectly removed when
converting the subquery engine to an index lookup-based engine.
Now eligible conditions are preserved during such engine rewrites.
Copy file name to clipboardExpand all lines: mysql-test/main/subselect.result
+9-9Lines changed: 9 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -991,9 +991,9 @@ a t1.a in (select t2.a from t2)
991
991
explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
992
992
id select_type table type possible_keys key key_len ref rows filtered Extra
993
993
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
994
-
2 SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
994
+
2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index; Using where
995
995
Warnings:
996
-
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
996
+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL where <cache>(`test`.`t1`.`a`) = `test`.`t2`.`a` or `test`.`t2`.`a` is null having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
997
997
CREATE TABLE t3 (a int(11) default '0');
998
998
INSERT INTO t3 VALUES (1),(2),(3);
999
999
SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
@@ -1700,21 +1700,21 @@ a3 1
1700
1700
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
1701
1701
id select_type table type possible_keys key key_len ref rows filtered Extra
1702
1702
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1703
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1703
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1704
1704
Warnings:
1705
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
1705
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
1706
1706
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
1707
1707
id select_type table type possible_keys key key_len ref rows filtered Extra
1708
1708
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1709
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1709
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1710
1710
Warnings:
1711
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
1711
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
1712
1712
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
1713
1713
id select_type table type possible_keys key key_len ref rows filtered Extra
1714
1714
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1715
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1715
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1716
1716
Warnings:
1717
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
1717
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
1718
1718
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
1719
1719
id select_type table type possible_keys key key_len ref rows filtered Extra
1720
1720
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
@@ -3272,7 +3272,7 @@ INSERT INTO t2 VALUES (1),(2),(3);
3272
3272
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
3273
3273
id select_type table type possible_keys key key_len ref rows Extra
3274
3274
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
3275
-
2 SUBQUERY t1 index_subquery a a 5 func 3 Using index; Full scan on NULL key
3275
+
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 3 Using index; Using where; Full scan on NULL key
Copy file name to clipboardExpand all lines: mysql-test/main/subselect_no_exists_to_in.result
+9-9Lines changed: 9 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -995,9 +995,9 @@ a t1.a in (select t2.a from t2)
995
995
explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
996
996
id select_type table type possible_keys key key_len ref rows filtered Extra
997
997
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
998
-
2 SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
998
+
2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index; Using where
999
999
Warnings:
1000
-
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
1000
+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL where <cache>(`test`.`t1`.`a`) = `test`.`t2`.`a` or `test`.`t2`.`a` is null having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
1001
1001
CREATE TABLE t3 (a int(11) default '0');
1002
1002
INSERT INTO t3 VALUES (1),(2),(3);
1003
1003
SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
@@ -1704,21 +1704,21 @@ a3 1
1704
1704
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
1705
1705
id select_type table type possible_keys key key_len ref rows filtered Extra
1706
1706
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1707
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1707
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1708
1708
Warnings:
1709
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
1709
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
1710
1710
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
1711
1711
id select_type table type possible_keys key key_len ref rows filtered Extra
1712
1712
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1713
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1713
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1714
1714
Warnings:
1715
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
1715
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
1716
1716
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
1717
1717
id select_type table type possible_keys key key_len ref rows filtered Extra
1718
1718
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1719
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1719
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1720
1720
Warnings:
1721
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
1721
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
1722
1722
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
1723
1723
id select_type table type possible_keys key key_len ref rows filtered Extra
1724
1724
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
@@ -3275,7 +3275,7 @@ INSERT INTO t2 VALUES (1),(2),(3);
3275
3275
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
3276
3276
id select_type table type possible_keys key key_len ref rows Extra
3277
3277
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
3278
-
2 SUBQUERY t1 index_subquery a a 5 func 3 Using index; Full scan on NULL key
3278
+
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 3 Using index; Using where; Full scan on NULL key
Copy file name to clipboardExpand all lines: mysql-test/main/subselect_no_mat.result
+9-9Lines changed: 9 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -998,9 +998,9 @@ a t1.a in (select t2.a from t2)
998
998
explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
999
999
id select_type table type possible_keys key key_len ref rows filtered Extra
1000
1000
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
1001
-
2 SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
1001
+
2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index; Using where
1002
1002
Warnings:
1003
-
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
1003
+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL where <cache>(`test`.`t1`.`a`) = `test`.`t2`.`a` or `test`.`t2`.`a` is null having `test`.`t2`.`a` is null)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
1004
1004
CREATE TABLE t3 (a int(11) default '0');
1005
1005
INSERT INTO t3 VALUES (1),(2),(3);
1006
1006
SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
@@ -1707,21 +1707,21 @@ a3 1
1707
1707
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
1708
1708
id select_type table type possible_keys key key_len ref rows filtered Extra
1709
1709
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1710
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1710
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1711
1711
Warnings:
1712
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
1712
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
1713
1713
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
1714
1714
id select_type table type possible_keys key key_len ref rows filtered Extra
1715
1715
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1716
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1716
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1717
1717
Warnings:
1718
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
1718
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
1719
1719
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
1720
1720
id select_type table type possible_keys key key_len ref rows filtered Extra
1721
1721
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
1722
-
2 SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
1722
+
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
1723
1723
Warnings:
1724
-
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
1724
+
Note 1003 /* select#1 */ select `test`.`t1`.`s1` AS `s1`,!<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where trigcond(<cache>(`test`.`t1`.`s1`) = `test`.`t2`.`s1` or `test`.`t2`.`s1` is null) having trigcond(`test`.`t2`.`s1` is null))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
1725
1725
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
1726
1726
id select_type table type possible_keys key key_len ref rows filtered Extra
1727
1727
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
@@ -3277,7 +3277,7 @@ INSERT INTO t2 VALUES (1),(2),(3);
3277
3277
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
3278
3278
id select_type table type possible_keys key key_len ref rows Extra
3279
3279
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
3280
-
2 SUBQUERY t1 index_subquery a a 5 func 3 Using index; Full scan on NULL key
3280
+
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 3 Using index; Using where; Full scan on NULL key
0 commit comments