mariadb/mysql-test/main/unique.result
Dave Gosselin f4833ceb41 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.
2025-07-15 16:29:02 -04:00

161 lines
4.3 KiB
Text

ALTER DATABASE test CHARACTER SET latin1 COLLATE latin1_swedish_ci;
CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, a varchar(30000), UNIQUE (a)) ENGINE=innodb;
INSERT INTO t1 (a) VALUES (20),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
SELECT * FROM t1 WHERE a BETWEEN '1' AND '100';
pk a
DROP TABLE t1;
CREATE TABLE t2 (n BLOB, UNIQUE(n));
INSERT INTO t2 VALUES (1);
DELETE FROM t2 WHERE n = 1;
DROP TABLE t2;
ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci;
CREATE TABLE t1 (c1 TEXT, UNIQUE (c1(1)));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` text DEFAULT NULL,
UNIQUE KEY `c1` (`c1`(1))
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
INSERT INTO t1 (c1) VALUES ('a');
SELECT 'abc' IN (SELECT c1 FROM t1);
'abc' IN (SELECT c1 FROM t1)
0
EXPLAIN format=json SELECT 'abc' IN (SELECT c1 FROM t1);
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "No tables used"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"table": {
"message": "Impossible WHERE noticed after reading const tables"
}
}
}
]
}
}
SELECT c1 FROM t1 WHERE ('abc' IN (SELECT c1 FROM t1)) IS FALSE;
c1
a
DROP TABLE t1;
CREATE TABLE t1 (c1 TEXT, c2 TEXT, UNIQUE (c1(1)));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` text DEFAULT NULL,
`c2` text DEFAULT NULL,
UNIQUE KEY `c1` (`c1`(1))
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
INSERT INTO t1 (c1, c2) VALUES ('a','b');
SELECT ('abc', 'xyz') IN (SELECT c1, c2 FROM t1);
('abc', 'xyz') IN (SELECT c1, c2 FROM t1)
0
EXPLAIN format=json SELECT ('abc', 'xyz') IN (SELECT c1, c2 FROM t1);
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "No tables used"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"table": {
"message": "Impossible WHERE noticed after reading const tables"
}
}
}
]
}
}
SELECT * FROM t1 WHERE (('abc', 'xyz') IN (SELECT c1, c2 FROM t1)) IS FALSE;
c1 c2
a b
DROP TABLE t1;
CREATE TABLE t1 (c1 TEXT, c2 TEXT, UNIQUE (c1(3)));
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` text DEFAULT NULL,
`c2` text DEFAULT NULL,
UNIQUE KEY `c1` (`c1`(3))
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
INSERT INTO t1 (c1, c2) VALUES ('abc','xyz');
SELECT ('abc', 'xyz') IN (SELECT c1, c2 FROM t1) IS FALSE;
('abc', 'xyz') IN (SELECT c1, c2 FROM t1) IS FALSE
0
EXPLAIN format=json SELECT ('abc', 'xyz') IN (SELECT c1, c2 FROM t1) IS FALSE;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "No tables used"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"const_condition": "(convert('abc' using utf8mb4) = 'abc' or 'abc' is null) and (convert('xyz' using utf8mb4) = 'xyz' or 'xyz' is null)",
"having_condition": "'abc' is null and 'xyz' is null",
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "system",
"rows": 1,
"filtered": 100
}
}
]
}
}
]
}
}
SELECT * FROM t1 WHERE (('abc', 'xyz') IN (SELECT c1, c2 FROM t1)) IS FALSE;
c1 c2
SELECT ('abc', 'xyz') IN (SELECT c1, c2 FROM t1) IS TRUE;
('abc', 'xyz') IN (SELECT c1, c2 FROM t1) IS TRUE
1
EXPLAIN format=json SELECT ('abc', 'xyz') IN (SELECT c1, c2 FROM t1) IS TRUE;
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"message": "No tables used"
},
"subqueries": [
{
"query_block": {
"select_id": 2,
"const_condition": "(convert('abc' using utf8mb4) = 'abc' or 'abc' is null) and (convert('xyz' using utf8mb4) = 'xyz' or 'xyz' is null)",
"having_condition": "'abc' is null and 'xyz' is null",
"nested_loop": [
{
"table": {
"table_name": "t1",
"access_type": "system",
"rows": 1,
"filtered": 100
}
}
]
}
}
]
}
}
SELECT * FROM t1 WHERE (('abc', 'xyz') IN (SELECT c1, c2 FROM t1)) IS TRUE;
c1 c2
abc xyz
DROP TABLE t1;