plan: remove parents totally (#5454)
This commit is contained in:
@ -213,7 +213,7 @@ func (a *aggregationOptimizer) tryToPushDownAgg(aggFuncs []aggregation.Aggregati
|
||||
}
|
||||
}
|
||||
agg := a.makeNewAgg(aggFuncs, gbyCols)
|
||||
setParentAndChildren(agg, child)
|
||||
agg.SetChildren(child)
|
||||
// If agg has no group-by item, it will return a default value, which may cause some bugs.
|
||||
// So here we add a group-by item forcely.
|
||||
if len(agg.GroupByItems) == 0 {
|
||||
@ -304,11 +304,11 @@ func (a *aggregationOptimizer) pushAggCrossUnion(agg *LogicalAggregation, unionS
|
||||
for _, key := range unionChild.Schema().Keys {
|
||||
if tmpSchema.ColumnsIndices(key) != nil {
|
||||
proj := a.convertAggToProj(newAgg, a.ctx)
|
||||
setParentAndChildren(proj, unionChild)
|
||||
proj.SetChildren(unionChild)
|
||||
return proj
|
||||
}
|
||||
}
|
||||
setParentAndChildren(newAgg, unionChild)
|
||||
newAgg.SetChildren(unionChild)
|
||||
return newAgg
|
||||
}
|
||||
|
||||
@ -346,7 +346,7 @@ func (a *aggregationOptimizer) aggPushDown(p LogicalPlan) LogicalPlan {
|
||||
} else {
|
||||
lChild = a.tryToPushDownAgg(leftAggFuncs, leftGbyCols, join, 0)
|
||||
}
|
||||
setParentAndChildren(join, lChild, rChild)
|
||||
join.SetChildren(lChild, rChild)
|
||||
join.SetSchema(expression.MergeSchema(lChild.Schema(), rChild.Schema()))
|
||||
join.buildKeyInfo()
|
||||
proj := a.tryToEliminateAggregation(agg)
|
||||
@ -369,7 +369,7 @@ func (a *aggregationOptimizer) aggPushDown(p LogicalPlan) LogicalPlan {
|
||||
aggFunc.SetArgs(newArgs)
|
||||
}
|
||||
projChild := proj.children[0]
|
||||
setParentAndChildren(agg, projChild)
|
||||
agg.SetChildren(projChild)
|
||||
} else if union, ok1 := child.(*LogicalUnionAll); ok1 {
|
||||
var gbyCols []*expression.Column
|
||||
gbyCols = expression.ExtractColumnsFromExpressions(gbyCols, agg.GroupByItems, nil)
|
||||
@ -379,7 +379,7 @@ func (a *aggregationOptimizer) aggPushDown(p LogicalPlan) LogicalPlan {
|
||||
newChild := a.pushAggCrossUnion(pushedAgg, union.schema, child.(LogicalPlan))
|
||||
newChildren = append(newChildren, newChild)
|
||||
}
|
||||
setParentAndChildren(union, newChildren...)
|
||||
union.SetChildren(newChildren...)
|
||||
union.SetSchema(pushedAgg.schema)
|
||||
}
|
||||
}
|
||||
@ -389,7 +389,7 @@ func (a *aggregationOptimizer) aggPushDown(p LogicalPlan) LogicalPlan {
|
||||
newChild := a.aggPushDown(child.(LogicalPlan))
|
||||
newChildren = append(newChildren, newChild)
|
||||
}
|
||||
setParentAndChildren(p, newChildren...)
|
||||
p.SetChildren(newChildren...)
|
||||
return p
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@ func (a *aggregationOptimizer) tryToEliminateAggregation(agg *LogicalAggregation
|
||||
if coveredByUniqueKey {
|
||||
// GroupByCols has unique key, so this aggregation can be removed.
|
||||
proj := a.convertAggToProj(agg, a.ctx)
|
||||
setParentAndChildren(proj, agg.children[0])
|
||||
proj.SetChildren(agg.children[0])
|
||||
return proj
|
||||
}
|
||||
return nil
|
||||
|
||||
@ -91,8 +91,6 @@ func (s *decorrelateSolver) optimize(p LogicalPlan, _ context.Context) (LogicalP
|
||||
if len(apply.corCols) == 0 {
|
||||
// If the inner plan is non-correlated, the apply will be simplified to join.
|
||||
join := &apply.LogicalJoin
|
||||
innerPlan.SetParents(join)
|
||||
outerPlan.SetParents(join)
|
||||
join.self = join
|
||||
p = join
|
||||
} else if sel, ok := innerPlan.(*LogicalSelection); ok {
|
||||
@ -104,12 +102,12 @@ func (s *decorrelateSolver) optimize(p LogicalPlan, _ context.Context) (LogicalP
|
||||
}
|
||||
apply.attachOnConds(newConds)
|
||||
innerPlan = sel.children[0].(LogicalPlan)
|
||||
setParentAndChildren(apply, outerPlan, innerPlan)
|
||||
apply.SetChildren(outerPlan, innerPlan)
|
||||
return s.optimize(p, nil)
|
||||
} else if m, ok := innerPlan.(*LogicalMaxOneRow); ok {
|
||||
if m.children[0].Schema().MaxOneRow {
|
||||
innerPlan = m.children[0].(LogicalPlan)
|
||||
setParentAndChildren(apply, outerPlan, innerPlan)
|
||||
apply.SetChildren(outerPlan, innerPlan)
|
||||
return s.optimize(p, nil)
|
||||
}
|
||||
} else if proj, ok := innerPlan.(*LogicalProjection); ok {
|
||||
@ -118,17 +116,16 @@ func (s *decorrelateSolver) optimize(p LogicalPlan, _ context.Context) (LogicalP
|
||||
}
|
||||
apply.columnSubstitute(proj.Schema(), proj.Exprs)
|
||||
innerPlan = proj.children[0].(LogicalPlan)
|
||||
setParentAndChildren(apply, outerPlan, innerPlan)
|
||||
apply.SetChildren(outerPlan, innerPlan)
|
||||
if apply.JoinType != SemiJoin && apply.JoinType != LeftOuterSemiJoin && apply.JoinType != AntiSemiJoin && apply.JoinType != AntiLeftOuterSemiJoin {
|
||||
proj.SetSchema(apply.Schema())
|
||||
proj.Exprs = append(expression.Column2Exprs(outerPlan.Schema().Clone().Columns), proj.Exprs...)
|
||||
apply.SetSchema(expression.MergeSchema(outerPlan.Schema(), innerPlan.Schema()))
|
||||
proj.SetParents(apply.Parents()...)
|
||||
np, err := s.optimize(p, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
setParentAndChildren(proj, np)
|
||||
proj.SetChildren(np)
|
||||
return proj, nil
|
||||
}
|
||||
return s.optimize(p, nil)
|
||||
@ -136,7 +133,7 @@ func (s *decorrelateSolver) optimize(p LogicalPlan, _ context.Context) (LogicalP
|
||||
if apply.canPullUpAgg() && agg.canPullUp() {
|
||||
innerPlan = agg.children[0].(LogicalPlan)
|
||||
apply.JoinType = LeftOuterJoin
|
||||
setParentAndChildren(apply, outerPlan, innerPlan)
|
||||
apply.SetChildren(outerPlan, innerPlan)
|
||||
agg.SetSchema(apply.Schema())
|
||||
agg.GroupByItems = expression.Column2Exprs(outerPlan.Schema().Keys[0])
|
||||
newAggFuncs := make([]aggregation.Aggregation, 0, apply.Schema().Len())
|
||||
@ -147,12 +144,11 @@ func (s *decorrelateSolver) optimize(p LogicalPlan, _ context.Context) (LogicalP
|
||||
newAggFuncs = append(newAggFuncs, agg.AggFuncs...)
|
||||
agg.AggFuncs = newAggFuncs
|
||||
apply.SetSchema(expression.MergeSchema(outerPlan.Schema(), innerPlan.Schema()))
|
||||
agg.SetParents(apply.Parents()...)
|
||||
np, err := s.optimize(p, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
setParentAndChildren(agg, np)
|
||||
agg.SetChildren(np)
|
||||
agg.collectGroupByColumns()
|
||||
return agg, nil
|
||||
}
|
||||
@ -166,6 +162,6 @@ func (s *decorrelateSolver) optimize(p LogicalPlan, _ context.Context) (LogicalP
|
||||
}
|
||||
newChildren = append(newChildren, np)
|
||||
}
|
||||
setParentAndChildren(p, newChildren...)
|
||||
p.SetChildren(newChildren...)
|
||||
return p, nil
|
||||
}
|
||||
|
||||
@ -69,19 +69,15 @@ func resolveExprAndReplace(origin expression.Expression, replace map[string]*exp
|
||||
}
|
||||
|
||||
func doPhysicalProjectionElimination(p PhysicalPlan) PhysicalPlan {
|
||||
children := make([]Plan, 0, len(p.Children()))
|
||||
for _, child := range p.Children() {
|
||||
newChild := doPhysicalProjectionElimination(child.(PhysicalPlan))
|
||||
children = append(children, newChild)
|
||||
for i, child := range p.Children() {
|
||||
p.Children()[i] = doPhysicalProjectionElimination(child.(PhysicalPlan))
|
||||
}
|
||||
setParentAndChildren(p, children...)
|
||||
|
||||
proj, isProj := p.(*PhysicalProjection)
|
||||
if !isProj || !canProjectionBeEliminatedStrict(proj) {
|
||||
return p
|
||||
}
|
||||
child := p.Children()[0]
|
||||
removePlan(p)
|
||||
return child.(PhysicalPlan)
|
||||
}
|
||||
|
||||
@ -114,18 +110,15 @@ func (pe *projectionEliminater) optimize(lp LogicalPlan, _ context.Context) (Log
|
||||
// eliminate eliminates the redundant projection in a logical plan.
|
||||
func (pe *projectionEliminater) eliminate(p LogicalPlan, replace map[string]*expression.Column, canEliminate bool) LogicalPlan {
|
||||
proj, isProj := p.(*LogicalProjection)
|
||||
children := make([]Plan, 0, len(p.Children()))
|
||||
|
||||
childFlag := canEliminate
|
||||
if _, isUnion := p.(*LogicalUnionAll); isUnion {
|
||||
childFlag = false
|
||||
} else if _, isAgg := p.(*LogicalAggregation); isAgg || isProj {
|
||||
childFlag = true
|
||||
}
|
||||
for _, child := range p.Children() {
|
||||
children = append(children, pe.eliminate(child.(LogicalPlan), replace, childFlag))
|
||||
for i, child := range p.Children() {
|
||||
p.Children()[i] = pe.eliminate(child.(LogicalPlan), replace, childFlag)
|
||||
}
|
||||
setParentAndChildren(p, children...)
|
||||
|
||||
switch p.(type) {
|
||||
case *LogicalSort, *LogicalTopN, *LogicalLimit, *LogicalSelection, *LogicalMaxOneRow, *LogicalLock:
|
||||
@ -161,7 +154,6 @@ func (pe *projectionEliminater) eliminate(p LogicalPlan, replace map[string]*exp
|
||||
for i, col := range proj.Schema().Columns {
|
||||
replace[string(col.HashCode())] = exprs[i].(*expression.Column)
|
||||
}
|
||||
removePlan(p)
|
||||
return p.Children()[0].(LogicalPlan)
|
||||
}
|
||||
|
||||
|
||||
@ -362,7 +362,7 @@ func (er *expressionRewriter) handleOtherComparableSubq(lexpr, rexpr expression.
|
||||
agg := LogicalAggregation{
|
||||
AggFuncs: []aggregation.Aggregation{aggFunc},
|
||||
}.init(er.ctx)
|
||||
setParentAndChildren(agg, np)
|
||||
agg.SetChildren(np)
|
||||
aggCol0 := &expression.Column{
|
||||
ColName: model.NewCIStr("agg_Col_0"),
|
||||
FromID: agg.id,
|
||||
@ -432,7 +432,7 @@ func (er *expressionRewriter) buildQuantifierPlan(agg *LogicalAggregation, cond,
|
||||
IsAggOrSubq: true,
|
||||
RetType: cond.GetType(),
|
||||
})
|
||||
setParentAndChildren(proj, er.p)
|
||||
proj.SetChildren(er.p)
|
||||
er.p = proj
|
||||
}
|
||||
|
||||
@ -445,7 +445,7 @@ func (er *expressionRewriter) handleNEAny(lexpr, rexpr expression.Expression, np
|
||||
agg := LogicalAggregation{
|
||||
AggFuncs: []aggregation.Aggregation{firstRowFunc, countFunc},
|
||||
}.init(er.ctx)
|
||||
setParentAndChildren(agg, np)
|
||||
agg.SetChildren(np)
|
||||
firstRowResultCol := &expression.Column{
|
||||
ColName: model.NewCIStr("col_firstRow"),
|
||||
FromID: agg.id,
|
||||
@ -473,7 +473,7 @@ func (er *expressionRewriter) handleEQAll(lexpr, rexpr expression.Expression, np
|
||||
agg := LogicalAggregation{
|
||||
AggFuncs: []aggregation.Aggregation{firstRowFunc, countFunc},
|
||||
}.init(er.ctx)
|
||||
setParentAndChildren(agg, np)
|
||||
agg.SetChildren(np)
|
||||
firstRowResultCol := &expression.Column{
|
||||
ColName: model.NewCIStr("col_firstRow"),
|
||||
FromID: agg.id,
|
||||
|
||||
@ -190,7 +190,7 @@ func (e *joinReOrderSolver) newJoin(lChild, rChild LogicalPlan) *LogicalJoin {
|
||||
reordered: true,
|
||||
}.init(e.ctx)
|
||||
join.SetSchema(expression.MergeSchema(lChild.Schema(), rChild.Schema()))
|
||||
setParentAndChildren(join, lChild, rChild)
|
||||
join.SetChildren(lChild, rChild)
|
||||
return join
|
||||
}
|
||||
|
||||
|
||||
@ -108,7 +108,7 @@ func (b *planBuilder) buildAggregation(p LogicalPlan, aggFuncList []*ast.Aggrega
|
||||
agg.AggFuncs = append(agg.AggFuncs, newFunc)
|
||||
schema.Append(col.Clone().(*expression.Column))
|
||||
}
|
||||
setParentAndChildren(agg, p)
|
||||
agg.SetChildren(p)
|
||||
agg.GroupByItems = gbyItems
|
||||
agg.SetSchema(schema)
|
||||
agg.collectGroupByColumns()
|
||||
@ -242,7 +242,7 @@ func (b *planBuilder) buildJoin(join *ast.Join) LogicalPlan {
|
||||
|
||||
newSchema := expression.MergeSchema(leftPlan.Schema(), rightPlan.Schema())
|
||||
joinPlan := LogicalJoin{}.init(b.ctx)
|
||||
setParentAndChildren(joinPlan, leftPlan, rightPlan)
|
||||
joinPlan.SetChildren(leftPlan, rightPlan)
|
||||
joinPlan.SetSchema(newSchema)
|
||||
|
||||
// Merge sub join's redundantSchema into this join plan. When handle query like
|
||||
@ -444,7 +444,7 @@ func (b *planBuilder) buildSelection(p LogicalPlan, where ast.ExprNode, AggMappe
|
||||
}
|
||||
selection.Conditions = expressions
|
||||
selection.SetSchema(p.Schema().Clone())
|
||||
setParentAndChildren(selection, p)
|
||||
selection.SetChildren(p)
|
||||
return selection
|
||||
}
|
||||
|
||||
@ -554,7 +554,7 @@ func (b *planBuilder) buildProjection(p LogicalPlan, fields []*ast.SelectField,
|
||||
}
|
||||
}
|
||||
proj.SetSchema(schema)
|
||||
setParentAndChildren(proj, p)
|
||||
proj.SetChildren(p)
|
||||
return proj, oldLen
|
||||
}
|
||||
|
||||
@ -569,7 +569,7 @@ func (b *planBuilder) buildDistinct(child LogicalPlan, length int) LogicalPlan {
|
||||
for _, col := range child.Schema().Columns {
|
||||
agg.AggFuncs = append(agg.AggFuncs, aggregation.NewAggFunction(ast.AggFuncFirstRow, []expression.Expression{col}, false))
|
||||
}
|
||||
setParentAndChildren(agg, child)
|
||||
agg.SetChildren(child)
|
||||
agg.SetSchema(child.Schema().Clone())
|
||||
return agg
|
||||
}
|
||||
@ -607,11 +607,11 @@ func (b *planBuilder) buildProjection4Union(u *LogicalUnionAll) {
|
||||
for _, col := range proj.schema.Columns {
|
||||
col.FromID = proj.ID()
|
||||
}
|
||||
setParentAndChildren(proj, u.children[childID])
|
||||
proj.SetChildren(u.children[childID])
|
||||
u.children[childID] = proj
|
||||
}
|
||||
}
|
||||
setParentAndChildren(u, u.children...)
|
||||
u.SetChildren(u.children...)
|
||||
}
|
||||
|
||||
func (b *planBuilder) buildUnion(union *ast.UnionStmt) LogicalPlan {
|
||||
@ -637,11 +637,10 @@ func (b *planBuilder) buildUnion(union *ast.UnionStmt) LogicalPlan {
|
||||
col.FromID = proj.ID()
|
||||
}
|
||||
proj.SetSchema(schema)
|
||||
setParentAndChildren(proj, sel)
|
||||
proj.SetChildren(sel)
|
||||
sel = proj
|
||||
u.children[i] = proj
|
||||
}
|
||||
sel.SetParents(u)
|
||||
}
|
||||
|
||||
// infer union type
|
||||
@ -710,7 +709,7 @@ func (b *planBuilder) buildSort(p LogicalPlan, byItems []*ast.ByItem, aggMapper
|
||||
exprs = append(exprs, &ByItems{Expr: it, Desc: item.Desc})
|
||||
}
|
||||
sort.ByItems = exprs
|
||||
setParentAndChildren(sort, p)
|
||||
sort.SetChildren(p)
|
||||
sort.SetSchema(p.Schema().Clone())
|
||||
return sort
|
||||
}
|
||||
@ -761,7 +760,7 @@ func (b *planBuilder) buildLimit(src LogicalPlan, limit *ast.Limit) LogicalPlan
|
||||
Offset: offset,
|
||||
Count: count,
|
||||
}.init(b.ctx)
|
||||
setParentAndChildren(li, src)
|
||||
li.SetChildren(src)
|
||||
li.SetSchema(src.Schema().Clone())
|
||||
return li
|
||||
}
|
||||
@ -1551,7 +1550,7 @@ func (b *planBuilder) buildSelect(sel *ast.SelectStmt) LogicalPlan {
|
||||
sel.Fields.Fields = originalFields
|
||||
if oldLen != p.Schema().Len() {
|
||||
proj := LogicalProjection{Exprs: expression.Column2Exprs(p.Schema().Columns[:oldLen])}.init(b.ctx)
|
||||
setParentAndChildren(proj, p)
|
||||
proj.SetChildren(p)
|
||||
schema := expression.NewSchema(p.Schema().Clone().Columns[:oldLen]...)
|
||||
for _, col := range schema.Columns {
|
||||
col.FromID = proj.ID()
|
||||
@ -1652,12 +1651,12 @@ func (b *planBuilder) buildDataSource(tn *ast.TableName) LogicalPlan {
|
||||
if b.ctx.Txn() != nil && !b.ctx.Txn().IsReadOnly() {
|
||||
us := LogicalUnionScan{}.init(b.ctx)
|
||||
us.SetSchema(ds.Schema().Clone())
|
||||
setParentAndChildren(us, result)
|
||||
us.SetChildren(result)
|
||||
result = us
|
||||
}
|
||||
proj := b.projectVirtualColumns(ds, columns)
|
||||
if proj != nil {
|
||||
setParentAndChildren(proj, result)
|
||||
proj.SetChildren(result)
|
||||
result = proj
|
||||
}
|
||||
return result
|
||||
@ -1715,7 +1714,7 @@ func (b *planBuilder) buildApplyWithJoinType(outerPlan, innerPlan LogicalPlan, t
|
||||
b.optFlag = b.optFlag | flagBuildKeyInfo
|
||||
b.optFlag = b.optFlag | flagDecorrelate
|
||||
ap := LogicalApply{LogicalJoin: LogicalJoin{JoinType: tp}}.init(b.ctx)
|
||||
setParentAndChildren(ap, outerPlan, innerPlan)
|
||||
ap.SetChildren(outerPlan, innerPlan)
|
||||
ap.SetSchema(expression.MergeSchema(outerPlan.Schema(), innerPlan.Schema()))
|
||||
for i := outerPlan.Schema().Len(); i < ap.Schema().Len(); i++ {
|
||||
ap.schema.Columns[i].IsAggOrSubq = true
|
||||
@ -1732,8 +1731,6 @@ func (b *planBuilder) buildSemiApply(outerPlan, innerPlan LogicalPlan, condition
|
||||
ap := &LogicalApply{LogicalJoin: *join}
|
||||
ap.tp = TypeApply
|
||||
ap.self = ap
|
||||
ap.children[0].SetParents(ap)
|
||||
ap.children[1].SetParents(ap)
|
||||
return ap
|
||||
}
|
||||
|
||||
@ -1745,20 +1742,18 @@ out:
|
||||
// e.g. exists(select count(*) from t order by a) is equal to exists t.
|
||||
case *LogicalProjection, *LogicalSort:
|
||||
p = p.Children()[0].(LogicalPlan)
|
||||
p.SetParents()
|
||||
case *LogicalAggregation:
|
||||
if len(plan.GroupByItems) == 0 {
|
||||
p = b.buildTableDual()
|
||||
break out
|
||||
}
|
||||
p = p.Children()[0].(LogicalPlan)
|
||||
p.SetParents()
|
||||
default:
|
||||
break out
|
||||
}
|
||||
}
|
||||
exists := LogicalExists{}.init(b.ctx)
|
||||
setParentAndChildren(exists, p)
|
||||
exists.SetChildren(p)
|
||||
newCol := &expression.Column{
|
||||
FromID: exists.id,
|
||||
RetType: types.NewFieldType(mysql.TypeTiny),
|
||||
@ -1769,7 +1764,7 @@ out:
|
||||
|
||||
func (b *planBuilder) buildMaxOneRow(p LogicalPlan) LogicalPlan {
|
||||
maxOneRow := LogicalMaxOneRow{}.init(b.ctx)
|
||||
setParentAndChildren(maxOneRow, p)
|
||||
maxOneRow.SetChildren(p)
|
||||
maxOneRow.SetSchema(p.Schema().Clone())
|
||||
return maxOneRow
|
||||
}
|
||||
@ -1779,7 +1774,7 @@ func (b *planBuilder) buildSemiJoin(outerPlan, innerPlan LogicalPlan, onConditio
|
||||
for i, expr := range onCondition {
|
||||
onCondition[i] = expr.Decorrelate(outerPlan.Schema())
|
||||
}
|
||||
setParentAndChildren(joinPlan, outerPlan, innerPlan)
|
||||
joinPlan.SetChildren(outerPlan, innerPlan)
|
||||
joinPlan.attachOnConds(onCondition)
|
||||
if asScalar {
|
||||
newSchema := outerPlan.Schema().Clone()
|
||||
|
||||
15
plan/plan.go
15
plan/plan.go
@ -28,8 +28,6 @@ import (
|
||||
// It is created from ast.Node first, then optimized by the optimizer,
|
||||
// finally used by the executor to create a Cursor which executes the statement.
|
||||
type Plan interface {
|
||||
// Get all the parents.
|
||||
Parents() []Plan
|
||||
// Get all the children.
|
||||
Children() []Plan
|
||||
// Set the schema.
|
||||
@ -40,8 +38,6 @@ type Plan interface {
|
||||
ID() int
|
||||
// Get the ID in explain statement
|
||||
ExplainID() string
|
||||
// SetParents sets the parents for the plan.
|
||||
SetParents(...Plan)
|
||||
// SetChildren sets the children for the plan.
|
||||
SetChildren(...Plan)
|
||||
// replaceExprColumns replace all the column reference in the plan's expression node.
|
||||
@ -308,7 +304,6 @@ func (p *baseLogicalPlan) PruneColumns(parentUsedCols []*expression.Column) {
|
||||
// basePlan implements base Plan interface.
|
||||
// Should be used as embedded struct in Plan implementations.
|
||||
type basePlan struct {
|
||||
parents []Plan
|
||||
children []Plan
|
||||
|
||||
schema *expression.Schema
|
||||
@ -340,21 +335,11 @@ func (p *basePlan) Schema() *expression.Schema {
|
||||
return p.schema
|
||||
}
|
||||
|
||||
// Parents implements Plan Parents interface.
|
||||
func (p *basePlan) Parents() []Plan {
|
||||
return p.parents
|
||||
}
|
||||
|
||||
// Children implements Plan Children interface.
|
||||
func (p *basePlan) Children() []Plan {
|
||||
return p.children
|
||||
}
|
||||
|
||||
// SetParents implements Plan SetParents interface.
|
||||
func (p *basePlan) SetParents(pars ...Plan) {
|
||||
p.parents = pars
|
||||
}
|
||||
|
||||
// SetChildren implements Plan SetChildren interface.
|
||||
func (p *basePlan) SetChildren(children ...Plan) {
|
||||
p.children = children
|
||||
|
||||
@ -237,8 +237,7 @@ func (b *planBuilder) buildDo(v *ast.DoStmt) Plan {
|
||||
}
|
||||
dual.SetSchema(expression.NewSchema())
|
||||
p := LogicalProjection{Exprs: exprs}.init(b.ctx)
|
||||
setParentAndChildren(p, dual)
|
||||
p.self = p
|
||||
p.SetChildren(dual)
|
||||
p.SetSchema(expression.NewSchema())
|
||||
return p
|
||||
}
|
||||
@ -381,7 +380,7 @@ func findIndexByName(indices []*model.IndexInfo, name model.CIStr) *model.IndexI
|
||||
|
||||
func (b *planBuilder) buildSelectLock(src Plan, lock ast.SelectLockType) *LogicalLock {
|
||||
selectLock := LogicalLock{Lock: lock}.init(b.ctx)
|
||||
setParentAndChildren(selectLock, src)
|
||||
selectLock.SetChildren(src)
|
||||
selectLock.SetSchema(src.Schema())
|
||||
return selectLock
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ func (p *LogicalJoin) getProj(idx int) *LogicalProjection {
|
||||
proj.Exprs = append(proj.Exprs, col.Clone())
|
||||
}
|
||||
proj.SetSchema(child.Schema().Clone())
|
||||
setParentAndChildren(proj, child)
|
||||
proj.SetChildren(child)
|
||||
p.children[idx] = proj
|
||||
return proj
|
||||
}
|
||||
|
||||
@ -30,7 +30,6 @@ func (s *baseLogicalPlan) pushDownTopN(topN *LogicalTopN) LogicalPlan {
|
||||
p := s.self
|
||||
for i, child := range p.Children() {
|
||||
p.Children()[i] = child.(LogicalPlan).pushDownTopN(nil)
|
||||
p.Children()[i].SetParents(p)
|
||||
}
|
||||
if topN != nil {
|
||||
return topN.setChild(p, false)
|
||||
@ -49,12 +48,12 @@ func (s *LogicalTopN) setChild(p LogicalPlan, eliminable bool) LogicalPlan {
|
||||
Offset: s.Offset,
|
||||
partial: s.partial,
|
||||
}.init(s.ctx)
|
||||
setParentAndChildren(limit, p)
|
||||
limit.SetChildren(p)
|
||||
limit.SetSchema(p.Schema().Clone())
|
||||
return limit
|
||||
}
|
||||
// Then s must be topN.
|
||||
setParentAndChildren(s, p)
|
||||
s.SetChildren(p)
|
||||
s.SetSchema(p.Schema().Clone())
|
||||
return s
|
||||
}
|
||||
@ -94,7 +93,6 @@ func (p *LogicalUnionAll) pushDownTopN(topN *LogicalTopN) LogicalPlan {
|
||||
}
|
||||
}
|
||||
p.children[i] = child.(LogicalPlan).pushDownTopN(newTopN)
|
||||
p.children[i].SetParents(p)
|
||||
}
|
||||
if topN != nil {
|
||||
return topN.setChild(p, true)
|
||||
@ -108,8 +106,7 @@ func (p *LogicalProjection) pushDownTopN(topN *LogicalTopN) LogicalPlan {
|
||||
by.Expr = expression.ColumnSubstitute(by.Expr, p.schema, p.Exprs)
|
||||
}
|
||||
}
|
||||
child := p.children[0].(LogicalPlan).pushDownTopN(topN)
|
||||
setParentAndChildren(p, child)
|
||||
p.children[0] = p.children[0].(LogicalPlan).pushDownTopN(topN)
|
||||
return p
|
||||
}
|
||||
|
||||
@ -142,20 +139,18 @@ func (p *LogicalJoin) pushDownTopNToChild(topN *LogicalTopN, idx int) LogicalPla
|
||||
}
|
||||
|
||||
func (p *LogicalJoin) pushDownTopN(topN *LogicalTopN) LogicalPlan {
|
||||
var leftChild, rightChild LogicalPlan
|
||||
switch p.JoinType {
|
||||
case LeftOuterJoin, LeftOuterSemiJoin, AntiLeftOuterSemiJoin:
|
||||
leftChild = p.pushDownTopNToChild(topN, 0)
|
||||
rightChild = p.children[1].(LogicalPlan).pushDownTopN(nil)
|
||||
p.children[0] = p.pushDownTopNToChild(topN, 0)
|
||||
p.children[1] = p.children[1].(LogicalPlan).pushDownTopN(nil)
|
||||
case RightOuterJoin:
|
||||
leftChild = p.children[0].(LogicalPlan).pushDownTopN(nil)
|
||||
rightChild = p.pushDownTopNToChild(topN, 1)
|
||||
p.children[0] = p.children[0].(LogicalPlan).pushDownTopN(nil)
|
||||
p.children[1] = p.pushDownTopNToChild(topN, 1)
|
||||
default:
|
||||
return p.baseLogicalPlan.pushDownTopN(topN)
|
||||
}
|
||||
// The LogicalJoin may be also a LogicalApply. So we must use self to set parents.
|
||||
self := p.self.(LogicalPlan)
|
||||
setParentAndChildren(self, leftChild, rightChild)
|
||||
if topN != nil {
|
||||
return topN.setChild(self, true)
|
||||
}
|
||||
|
||||
34
plan/util.go
34
plan/util.go
@ -45,37 +45,3 @@ func (a *AggregateFuncExtractor) Leave(n ast.Node) (ast.Node, bool) {
|
||||
}
|
||||
return n, true
|
||||
}
|
||||
|
||||
// replaceChild replaces p's child with some plan else.
|
||||
func replaceChild(p, child, replace Plan) {
|
||||
for i, ch := range p.Children() {
|
||||
if ch.ID() == child.ID() {
|
||||
p.Children()[i] = replace
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setParentAndChildren sets parent and children relationship.
|
||||
func setParentAndChildren(parent Plan, children ...Plan) {
|
||||
if children == nil || parent == nil {
|
||||
return
|
||||
}
|
||||
for _, child := range children {
|
||||
child.SetParents(parent)
|
||||
}
|
||||
parent.SetChildren(children...)
|
||||
}
|
||||
|
||||
// removePlan removes a plan from its parent and child.
|
||||
func removePlan(p Plan) {
|
||||
parents := p.Parents()
|
||||
children := p.Children()
|
||||
if len(parents) == 0 {
|
||||
child := children[0]
|
||||
child.SetParents()
|
||||
return
|
||||
}
|
||||
parent, child := parents[0], children[0]
|
||||
replaceChild(parent, p, child)
|
||||
child.SetParents(parent)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user