`UNION ALL` relation + `IN (correlated subquery)` over an `ALL` subquery panics
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
The following SQL raises an `assignment to entry in nil map` error, which might be unexpected. I've also attached an agent-generated analysis, if it helps.
[reduced.sql](https://github.com/user-attachments/files/30562494/reduced.sql)
### 1. Minimal reproduce step (Required)
```sql
CREATE TABLE t0 (id BIGINT);
CREATE VIEW u AS SELECT * FROM t0 UNION ALL SELECT * FROM t0;
SELECT 1 FROM u AS t1 WHERE (t1.id < ALL (SELECT 1)) IN (SELECT t1.id);
```
### 2. What did you expect to see? (Required)
| Query | Expected | Actual |
|---|---|---|
| minimal `SELECT` above | 0 rows (`t0` is empty) | `ERROR 1105 (HY000): assignment to entry in nil map` |
| `EXPLAIN` of the same | a plan | same 1105 (fails in physical planning) |
| same query against `t0` directly, or a non-`UNION ALL` view | 0 rows | 0 rows ✓ |
| as-found finding query (`logs/tidb_run12/error_round38_0.sql`) | 0 rows (BASE returns 0 rows) | same 1105 |
### 3. What did you see instead (Required)
```
[WARN] command dispatched failed [conn=2097158]
[sql="SELECT 1 FROM u AS t1 WHERE (t1.id < ALL (SELECT 1)) IN (SELECT t1.id)"]
[err="assignment to entry in nil map
github.com/pingcap/errors.Trace
/home/juan/go/pkg/mod/github.com/pingcap/errors@v0.11.5-0.20260508054701-306e305bcf41/juju_adaptor.go:15
github.com/pingcap/tidb/pkg/util.GetRecoverError
pkg/util/util.go:296
github.com/pingcap/tidb/pkg/planner.optimizeNoCache.func1
pkg/planner/optimize.go:226
runtime.gopanic
runtime/panic.go:860
runtime.mapassign_faststr
internal/runtime/maps/runtime_faststr.go:265
github.com/pingcap/tidb/pkg/planner/funcdep.(*FDSet).RegisterUniqueID
pkg/planner/funcdep/fd_graph.go:1227
github.com/pingcap/tidb/pkg/planner/util.ExtractEquivalenceCols
pkg/planner/util/funcdep_misc.go:117
github.com/pingcap/tidb/pkg/planner/core/operator/logicalop.(*LogicalJoin).ExtractFDForInnerJoin
pkg/planner/core/operator/logicalop/logical_join.go:879
github.com/pingcap/tidb/pkg/planner/core/operator/logicalop.(*LogicalJoin).ExtractFD
pkg/planner/core/operator/logicalop/logical_join.go:708
github.com/pingcap/tidb/pkg/planner/core/operator/logicalop.(*LogicalJoin).ExtractFDForSemiJoin
pkg/planner/core/operator/logicalop/logical_join.go:845
github.com/pingcap/tidb/pkg/planner/core/operator/logicalop.(*LogicalJoin).ExtractFD
pkg/planner/core/operator/logicalop/logical_join.go:712
github.com/pingcap/tidb/pkg/planner/core/operator/physicalop.GetMergeJoin
pkg/planner/core/operator/physicalop/physical_merge_join.go:54
github.com/pingcap/tidb/pkg/planner/core.exhaustPhysicalPlans4LogicalJoin
pkg/planner/core/exhaust_physical_plans.go:2192
github.com/pingcap/tidb/pkg/planner/core.exhaustPhysicalPlans
pkg/planner/core/exhaust_physical_plans.go:71
github.com/pingcap/tidb/pkg/planner/core.findBestTask
pkg/planner/core/find_best_task.go:663
github.com/pingcap/tidb/pkg/planner/core/operator/physicalop.FindBestTask
pkg/planner/core/operator/physicalop/base_physical_plan.go:496
github.com/pingcap/tidb/pkg/planner/core.iteratePhysicalPlan4BaseLogical
pkg/planner/core/find_best_task.go:343
github.com/pingcap/tidb/pkg/planner/core.enumeratePhysicalPlans4TaskHelper
pkg/planner/core/find_best_task.go:177
github.com/pingcap/tidb/pkg/planner/core.enumeratePhysicalPlans4Task
pkg/planner/core/find_best_task.go:126
github.com/pingcap/tidb/pkg/planner/core.findBestTask
pkg/planner/core/find_best_task.go:717
github.com/pingcap/tidb/pkg/planner/core/operator/physicalop.FindBestTask
pkg/planner/core/operator/physicalop/base_physical_plan.go:496
github.com/pingcap/tidb/pkg/planner/core.physicalOptimize
pkg/planner/core/optimizer.go:1135
github.com/pingcap/tidb/pkg/planner/core.VolcanoOptimize
pkg/planner/core/optimizer.go:387
github.com/pingcap/tidb/pkg/planner/core.doOptimize
pkg/planner/core/optimizer.go:340
github.com/pingcap/tidb/pkg/planner/core.DoOptimize
pkg/planner/core/optimizer.go:437
github.com/pingcap/tidb/pkg/planner.buildAndOptimizeLogicalPlanRound
pkg/planner/optimize.go:568
github.com/pingcap/tidb/pkg/planner.optimize
pkg/planner/optimize.go:773
github.com/pingcap/tidb/pkg/planner.optimizeNoCache
pkg/planner/optimize.go:367
github.com/pingcap/tidb/pkg/planner.optimizeCache
pkg/planner/optimize.go:220
github.com/pingcap/tidb/pkg/planner.Optimize
pkg/planner/optimize.go:207
github.com/pingcap/tidb/pkg/executor.(*Compiler).Compile
pkg/executor/compiler.go:107
github.com/pingcap/tidb/pkg/session.(*session).executeStmtImpl
pkg/session/session.go:2563"]
```
### 4. What is your TiDB version? (Required)
`SELECT tidb_version();`
```
Release Version: v9.0.0-beta.2.pre-2051-g3bea8196a5
Edition: Community
Git Commit Hash: 3bea8196a565ca01800b2d0807868f01139d8a30
Git Branch: master
UTC Build Time: 2026-07-30 16:56:32
GoVersion: go1.26.4
Race Enabled: false
Check Table Before Drop: false
Store: unistore
Kernel Type: Classic
```
`SELECT VERSION();` → `8.0.11-TiDB-v9.0.0-beta.2.pre-2051-g3bea8196a5`
Contributor guide
Research direction
Start by running the reduced SQL reproducer and its EXPLAIN against TiDB. Trace the panic from pkg/planner/funcdep/fd_graph.go through ExtractEquivalenceCols and the LogicalJoin and merge-join planner paths named in the stack trace. Done means both queries produce plans or 0 rows without the nil-map panic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 54/100