TRUE OR ... expressions are not always short-circuit
- 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!
### 1. Minimal reproduce step (Required)
```mysql
create table t (a int auto_increment primary key, b int);
insert into t (b) values (1),(2),(3),(4),(5),(6),(7),(8);
insert into t (b) select t2.b from t, t t2, t t3, t t4;
insert into t (b) select t2.b from t, t t2 limit 2000000;
update t set b = rand()*100000;
update t set b = a where a in (1510001,1520002,1530003,1540004,1550005);
prepare trueStmt from 'select * from t where a = ? and (? is null or b in (select b from t where b = ?))';
set @a=1510001,@b=null;
select connection_id(); -- Assuming it is set to 2097154 below...
-- This executes almost as fast as a PK lookup (~2-3x overhead using UniStore engine) ~120microseconds
execute trueStmt using @a,@b,@b;
explain for connection 2097154;
set @a=1520002,@b=1520002,@null=null;
-- This takes 160 milliseconds!!!
execute trueStmt using @a,@null,@b;
explain for connection 2097154;
-- This takes around a second using UniStore (OK, need to do full table scan)
execute trueStmt using @a,@b,@b;
explain for connection 2097154;
-- This is OK, showing TableDual and is almost as fast as a PK lookup (~2x overhead using UniStore engine)
explain analyze select * from t where a = 1530003 and (null IS NULL or b in (select b from t where b = null));
-- This is OK, needs to do a full table scan
explain analyze select * from t where a = 1540004 and (1540004 IS NULL or b in (select b from t where b = 1540004));
-- This still runs a full table scan!!!
explain analyze select * from t where a = 1550005 and (true or b in (select b from t where b = 1550005));
```
### 2. What did you expect to see? (Required)
`where a = 1550005 and (true or b in (select b from t where b = 1550005))` would be short-circuit to just `where a = 1550005` As well as `where a = ? (1520002) and (? (null) IN NULL) or b in (selet b from t where b = ? (1520002))` to be short-circuit to just `where a = ? (1520002)`
### 3. What did you see instead (Required)
It executes the subquery, taking much longer time than needed.
### 4. What is your TiDB version? (Required)
```
tidb_version(): Release Version: v9.0.0-beta.2.pre-511-g35094ab95c
Edition: Community
Git Commit Hash: 35094ab95c393e6d55b00a215d24e859880ec1f5
Git Branch: master
UTC Build Time: 2025-09-17 09:56:01
GoVersion: go1.24.2
Race Enabled: false
Check Table Before Drop: false
Store: unistore
Kernel Type: Classic
```
Contributor guide
Assessment
This issue has not been assessed yet.