Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.6, 10.11, 11.4, 11.8
-
None
-
None
Description
When a WHERE clause contains a condition like column + column <= ANY (subquery), and the column is a TEXT type requiring implicit casting to a number, the query produces an incorrect result set. The row that should evaluate to TRUE is incorrectly filtered out.
Interestingly, if the same boolean expression is evaluated directly in a SELECT list (as shown in the second query), it yields the correct count of TRUE values. This suggests the issue lies specifically in how the WHERE clause is processed or optimized, not in the evaluation of the expression itself.
DROP TABLE IF EXISTS t0; |
CREATE TABLE t0 (c1 TINYTEXT); |
INSERT INTO t0 (c1) VALUES ('1'),('2'),('X'); |
SELECT c1 AS ca1 FROM t0 WHERE c1+c1 <= ANY (SELECT c1 AS ca2 FROM t0); |
SELECT SUM(count) FROM (SELECT (c1 + c1 <= ANY (SELECT c1 AS ca2 FROM t0)) IS TRUE AS count FROM t0 ) AS ta_norec; |
The first SELECT statement returns only one row:
MariaDB [database0]> SELECT c1 AS ca1 FROM t0 WHERE c1+c1 <= ANY (SELECT c1 AS ca2 FROM t0);
|
+------+
|
| ca1 |
|
+------+
|
| X |
|
+------+
|
1 row in set, 3 warnings (0.001 sec)
|
The second SELECT statement returns 2, which is actually the correct count of rows that should match.
MariaDB [database0]> SELECT SUM(count) FROM (SELECT (c1 + c1 <= ANY (SELECT c1 AS ca2 FROM t0)) IS TRUE AS count FROM t0 ) AS ta_norec;
|
+------------+
|
| SUM(count) |
|
+------------+
|
| 2 |
|
+------------+
|
1 row in set, 3 warnings (0.001 sec)
|
The subquery SELECT c1 AS ca2 FROM t0 returns the set of strings
{'1', '2', 'X'}. When used in the numeric comparison, these are cast to numbers:
{1, 2, 0}.The outer query iterates through table t0:
For row c1 = '1': The condition is ('1'+'1') <= ANY ({1, 2, 0}
), which evaluates to 2 <= ANY (
{1, 2, 0}). This is TRUE because 2 <= 2. This row should be returned.For row c1 = '2': The condition is ('2'+'2') <= ANY ({1, 2, 0}
), which evaluates to 4 <= ANY (
{1, 2, 0}). This is FALSE. This row should not be returned.For row c1 = 'X': The condition is ('X'+'X') <= ANY ({1, 2, 0}
). 'X' is cast to 0, so it evaluates to 0 <= ANY (
{1, 2, 0}). This is TRUE because 0 <= 0. This row should be returned.