TiDB returns non-zero count for a query with contradictory filtering conditions
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
When querying with a join and a `WHERE` clause that contains a complex `CASE` expression involving generated columns, TiDB may return rows that should be logically impossible. Specifically, a row is counted even though the `CASE WHEN` condition requires both `NOT (t1.c0 <= t0.c0)` and the join condition `t1.c0 <= t0.c0` to be true simultaneously—a contradiction.
### 1. Minimal reproduce step (Required)
```sql
CREATE TABLE t0(c0 TEXT, c1 BLOB, c2 TEXT AS (CAST(c1 OR c1 REGEXP c0 AS BINARY)));
CREATE TABLE t1 LIKE t0;
INSERT INTO t0(c0, c1) VALUES ('', '1');
INSERT INTO t1(c0) VALUES (' ');
SELECT COUNT(CASE WHEN NOT (t1.c0 <= t0.c0) THEN 1 END) FROM t1 JOIN t0 ON t1.c0 <= t0.c0 WHERE (CASE 1 WHEN (CASE 0 WHEN 0 THEN t1.c0 WHEN 0 THEN t1.c1 END) THEN t1.c0 ELSE t0.c2 END) NOT LIKE 0; -- return: 1; expected: 0
+--------------------------------------------------+
| COUNT(CASE WHEN NOT (t1.c0 <= t0.c0) THEN 1 END) |
+--------------------------------------------------+
| 1 |
+--------------------------------------------------+
```
### 2. What did you expect to see? (Required)
```sql
SELECT COUNT(CASE WHEN NOT (t1.c0 <= t0.c0) THEN 1 END) FROM t1 JOIN t0 ON t1.c0 <= t0.c0 WHERE (CASE 1 WHEN (CASE 0 WHEN 0 THEN t1.c0 WHEN 0 THEN t1.c1 END) THEN t1.c0 ELSE t0.c2 END) NOT LIKE 0; -- return: 1; expected: 0. Since NOT (t1.c0 <= t0.c0) AND t1.c0 <= t0.c0 is false.
+--------------------------------------------------+
| COUNT(CASE WHEN NOT (t1.c0 <= t0.c0) THEN 1 END) |
+--------------------------------------------------+
| 0 |
+--------------------------------------------------+
```
### 3. What did you see instead (Required)
```sql
SELECT COUNT(CASE WHEN NOT (t1.c0 <= t0.c0) THEN 1 END) FROM t1 JOIN t0 ON t1.c0 <= t0.c0 WHERE (CASE 1 WHEN (CASE 0 WHEN 0 THEN t1.c0 WHEN 0 THEN t1.c1 END) THEN t1.c0 ELSE t0.c2 END) NOT LIKE 0; -- return: 1; expected: 0. Since NOT (t1.c0 <= t0.c0) AND t1.c0 <= t0.c0 is false.
+--------------------------------------------------+
| COUNT(CASE WHEN NOT (t1.c0 <= t0.c0) THEN 1 END) |
+--------------------------------------------------+
| 1 |
+--------------------------------------------------+
```
### 4. What is your TiDB version? (Required)
| 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: tikv |
Contributor guide
Assessment
This issue has not been assessed yet.