pingcap / pingcap/tidb

IndexMerge keep-order on partition table with virtual generated column panics with interface conversion: interface {} is nil, not int

Open
#68,084 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

### Summary

A query on a partitioned table with a `VIRTUAL` generated column can panic in the IndexMerge keep-order path.

The likely root cause is that the table-side worker rebuilds a handle that does not match the handle stored in the keep-order `indexOrder` map, so the lookup returns `nil` and later gets type-asserted to `int`.

### 1. Minimal reproduce step

```sql
SET @@tidb_enable_index_merge=1;
SET @@tidb_partition_prune_mode='dynamic';

DROP TABLE IF EXISTS t_min_idxmerge_issue;
CREATE TABLE t_min_idxmerge_issue (
id BIGINT PRIMARY KEY,
a INT DEFAULT NULL,
dt DATETIME DEFAULT NULL,
gc_v_ifnull INT GENERATED ALWAYS AS (ifnull(a, -1)) VIRTUAL,
KEY idx_dt(dt),
KEY idx_gc_v_ifnull(gc_v_ifnull)
) PARTITION BY HASH(id) PARTITIONS 4;

INSERT INTO t_min_idxmerge_issue(id, a, dt) VALUES
(1, NULL, NULL),
(2, NULL, '2020-01-01 01:00:00');

EXPLAIN FORMAT='brief'
SELECT /*+ USE_INDEX_MERGE(t_min_idxmerge_issue, idx_dt, idx_gc_v_ifnull) */
id
FROM t_min_idxmerge_issue
WHERE dt IS NULL
OR date(dt) IS NOT NULL
AND gc_v_ifnull = -1
ORDER BY id;

SELECT /*+ USE_INDEX_MERGE(t_min_idxmerge_issue, idx_dt, idx_gc_v_ifnull) */
id
FROM t_min_idxmerge_issue
WHERE dt IS NULL
OR date(dt) IS NOT NULL
AND gc_v_ifnull = -1
ORDER BY id;
```

The `EXPLAIN` result on my side is:

```text
Projection
└─Selection
└─Projection
└─IndexMerge partition:all, type: union
├─IndexRangeScan(Build) index:idx_dt(dt), range:[NULL,NULL], keep order:true
├─IndexRangeScan(Build) index:idx_gc_v_ifnull(gc_v_ifnull), range:[-1,-1], keep order:true
└─TableRowIDScan(Probe) keep order:false
```

### 2. What did you expect to see?

The query should return:

```text
1
2
```

### 3. What did you see instead?

```text
ERROR 1105 (HY000): IndexMergeTableScanWorker: interface conversion: interface {} is nil, not int
```

### 4. What is your TiDB version?

```text
Release Version: v9.0.0
Edition: Community
Git Commit Hash: 4ae7a12ae7884061a9b095584fd22bc3eab23112
Git Branch: heads/refs/tags/v9.0.0
UTC Build Time: 2026-04-25 02:22:25
GoVersion: go1.25.9
Race Enabled: false
Check Table Before Drop: false
Store: tikv
Kernel Type: Classic
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.