diff --git a/pkg/planner/core/logical_plans.go b/pkg/planner/core/logical_plans.go index c507dd69f1df3..5681d2c70c825 100644 --- a/pkg/planner/core/logical_plans.go +++ b/pkg/planner/core/logical_plans.go @@ -564,6 +564,15 @@ func (p *LogicalExpand) ExtractFD() *fd.FDSet { // ExtractCorrelatedCols implements LogicalPlan interface. func (p *LogicalExpand) ExtractCorrelatedCols() []*expression.CorrelatedColumn { + // if p.LevelExprs is nil, it means the GenLevelProjections has not been called yet, + // which is done in logical optimizing phase. While for building correlated subquery + // plan, the ExtractCorrelatedCols will be called once after building, so we should + // distinguish the case here. + if p.LevelExprs == nil { + // since level projections generation don't produce any correlated columns, just + // return nil. + return nil + } corCols := make([]*expression.CorrelatedColumn, 0, len(p.LevelExprs[0])) for _, lExpr := range p.LevelExprs { for _, expr := range lExpr {