Inconsistent query results (Pushdown vs. No-Pushdown) when evaluating NOT REGEXP with implicit string-to-int conversion (-('x_'))
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting your issue. Thanks!
I discovered a logic bug (inconsistent result set) in TiDB. An original query returns an Empty set, but when rewritten using a derived table to prevent predicate pushdown, it returns a row containing an empty string ''.
Based on the EXPLAIN output, the discrepancy occurs because the complex predicate containing NOT REGEXP and an invalid string-to-integer conversion (-('x_')) behaves differently when pushed down to TiKV (cop[tikv]) versus when it is evaluated in TiDB (root).
However, in MySQL and MariaDB, the results of both queries are still an empty string ''.
### 1. Minimal reproduce step (Required)
```sql
CREATE TABLE t0(c0 TEXT(397) );
REPLACE INTO t0(c0) VALUES ('EpRAR');
CREATE VIEW v0(c0) AS SELECT (CASE CAST(-785057440 AS DATETIME) WHEN ((t0.c0)NOT LIKE(t0.c0)) THEN (((NOT (-540588881)))NOT LIKE(558570807)) WHEN t0.c0 THEN t0.c0 ELSE '' END ) FROM t0;
-- result: empty set
SELECT v0.c0 FROM v0 WHERE
0.16 NOT REGEXP
((CASE v0.c0 LIKE v0.c0
WHEN v0.c0 >> v0.c0
THEN 1
ELSE (-('x_')) END ));
-- -- result: ''
SELECT ref0 FROM (SELECT v0.c0 AS ref0,
0.16 NOT REGEXP
((CASE v0.c0 LIKE v0.c0
WHEN v0.c0 >> v0.c0
THEN 1
ELSE (-('x_')) END )) AS ref1 FROM v0) AS s WHERE ref1;
```
### 2. What did you expect to see? (Required)
```shell
mysql> SELECT v0.c0 FROM v0 WHERE
-> 0.16 NOT REGEXP
-> ((CASE v0.c0 LIKE v0.c0
-> WHEN v0.c0 >> v0.c0
-> THEN 1
-> ELSE (-('x_')) END ));
+------+
| c0 |
+------+
| |
+------+
1 row in set, 4 warnings (0.00 sec)
mysql> SELECT ref0 FROM (SELECT v0.c0 AS ref0,
-> 0.16 NOT REGEXP
-> ((CASE v0.c0 LIKE v0.c0
-> WHEN v0.c0 >> v0.c0
-> THEN 1
-> ELSE (-('x_')) END )) AS ref1 FROM v0) AS s WHERE ref1;
+------+
| ref0 |
+------+
| |
+------+
1 row in set, 4 warnings (0.00 sec)
```
### 3. What did you see instead (Required)
```shell
mysql> -- result: empty set
mysql> SELECT v0.c0 FROM v0 WHERE
-> 0.16 NOT REGEXP
-> ((CASE v0.c0 LIKE v0.c0
-> WHEN v0.c0 >> v0.c0
-> THEN 1
-> ELSE (-('x_')) END ));
Empty set, 8 warnings (0.01 sec)
mysql> -- -- result: ''
mysql> SELECT ref0 FROM (SELECT v0.c0 AS ref0,
-> 0.16 NOT REGEXP
-> ((CASE v0.c0 LIKE v0.c0
-> WHEN v0.c0 >> v0.c0
-> THEN 1
-> ELSE (-('x_')) END )) AS ref1 FROM v0) AS s WHERE ref1;
+------+
| ref0 |
+------+
| |
+------+
1 row in set, 9 warnings (0.01 sec)
```
### 4. What is your TiDB version? (Required)
```shell
mysql> select tidb_version();
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tidb_version() |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Release Version: v8.5.5
Edition: Community
Git Commit Hash: 1fa258b833ff113883beeba40bc130be7ce66610
Git Branch: HEAD
UTC Build Time: 2026-01-14 22:20:57
GoVersion: go1.25.5
Race Enabled: false
Check Table Before Drop: false
Store: unistore |
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
```
Contributor guide
Assessment
This issue has not been assessed yet.