planner: fix stat for CTETable (#26367)

This commit is contained in:
wjHuang
2021-07-20 14:35:34 +08:00
committed by GitHub
parent 84887df9aa
commit dd42a3d0eb
4 changed files with 10 additions and 5 deletions

View File

@ -3773,7 +3773,7 @@ func (b *PlanBuilder) tryBuildCTE(ctx context.Context, tn *ast.TableName, asName
}
cte.recursiveRef = true
p := LogicalCTETable{name: cte.def.Name.String(), idForStorage: cte.storageID, seedPlan: cte.seedLP}.Init(b.ctx, b.getSelectOffset())
p := LogicalCTETable{name: cte.def.Name.String(), idForStorage: cte.storageID, seedStat: cte.seedStat}.Init(b.ctx, b.getSelectOffset())
p.SetSchema(getResultCTESchema(cte.seedLP.Schema(), b.ctx.GetSessionVars()))
p.SetOutputNames(cte.seedLP.OutputNames())
return p, nil
@ -3801,7 +3801,7 @@ func (b *PlanBuilder) tryBuildCTE(ctx context.Context, tn *ast.TableName, asName
lp := LogicalCTE{cteAsName: tn.Name, cte: &CTEClass{IsDistinct: cte.isDistinct, seedPartLogicalPlan: cte.seedLP,
recursivePartLogicalPlan: cte.recurLP, IDForStorage: cte.storageID,
optFlag: cte.optFlag, HasLimit: hasLimit, LimitBeg: limitBeg,
LimitEnd: limitEnd}}.Init(b.ctx, b.getSelectOffset())
LimitEnd: limitEnd}, seedStat: cte.seedStat}.Init(b.ctx, b.getSelectOffset())
lp.SetSchema(getResultCTESchema(cte.seedLP.Schema(), b.ctx.GetSessionVars()))
p = lp
p.SetOutputNames(cte.seedLP.OutputNames())
@ -6228,7 +6228,7 @@ func (b *PlanBuilder) buildWith(ctx context.Context, w *ast.WithClause) error {
nameMap[cte.Name.L] = struct{}{}
}
for _, cte := range w.CTEs {
b.outerCTEs = append(b.outerCTEs, &cteInfo{def: cte, nonRecursive: !w.IsRecursive, isBuilding: true, storageID: b.allocIDForCTEStorage})
b.outerCTEs = append(b.outerCTEs, &cteInfo{def: cte, nonRecursive: !w.IsRecursive, isBuilding: true, storageID: b.allocIDForCTEStorage, seedStat: &property.StatsInfo{}})
b.allocIDForCTEStorage++
saveFlag := b.optFlag
// Init the flag to flagPrunColumns, otherwise it's missing.

View File

@ -1216,13 +1216,14 @@ type LogicalCTE struct {
cte *CTEClass
cteAsName model.CIStr
seedStat *property.StatsInfo
}
// LogicalCTETable is for CTE table
type LogicalCTETable struct {
logicalSchemaProducer
seedPlan LogicalPlan
seedStat *property.StatsInfo
name string
idForStorage int
}

View File

@ -433,6 +433,8 @@ type cteInfo struct {
enterSubquery bool
recursiveRef bool
limitLP LogicalPlan
// seedStat is shared between logicalCTE and logicalCTETable.
seedStat *property.StatsInfo
}
// PlanBuilder builds Plan from an ast.Node.

View File

@ -1110,6 +1110,8 @@ func (p *LogicalCTE) DeriveStats(childStats []*property.StatsInfo, selfSchema *e
return nil, err
}
resStat := p.cte.seedPartPhysicalPlan.Stats()
// Changing the pointer so that seedStat in LogicalCTETable can get the new stat.
*p.seedStat = *resStat
p.stats = &property.StatsInfo{
RowCount: resStat.RowCount,
ColNDVs: make(map[int64]float64, selfSchema.Len()),
@ -1140,6 +1142,6 @@ func (p *LogicalCTETable) DeriveStats(childStats []*property.StatsInfo, selfSche
if p.stats != nil {
return p.stats, nil
}
p.stats = p.seedPlan.statsInfo()
p.stats = p.seedStat
return p.stats, nil
}