Skip to content

Commit

Permalink
planner: stream agg should not be pushed to double read (pingcap#12443)
Browse files Browse the repository at this point in the history
For the following two reason, we should not push stream agg down to double read
- The aggregate will lost the handle information
- There's no sort operator. The second read is ordered with pk, not by index.
  • Loading branch information
winoros committed Oct 14, 2019
1 parent 96dc595 commit 252287a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
7 changes: 4 additions & 3 deletions planner/core/rule_inject_extra_projection.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ func injectProjBelowAgg(aggPlan PhysicalPlan, aggFuncs []*aggregation.AggFuncDes
}
projExprs = append(projExprs, arg)
newArg := &expression.Column{
RetType: arg.GetType(),
ColName: model.NewCIStr(fmt.Sprintf("col_%d", len(projSchemaCols))),
Index: cursor,
UniqueID: aggPlan.context().GetSessionVars().AllocPlanColumnID(),
RetType: arg.GetType(),
ColName: model.NewCIStr(fmt.Sprintf("col_%d", len(projSchemaCols))),
Index: cursor,
}
projSchemaCols = append(projSchemaCols, newArg)
f.Args[i] = newArg
Expand Down
29 changes: 19 additions & 10 deletions planner/core/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,18 +508,27 @@ func (p *basePhysicalAgg) newPartialAggregate() (partial, final PhysicalPlan) {
func (p *PhysicalStreamAgg) attach2Task(tasks ...task) task {
t := tasks[0].copy()
if cop, ok := t.(*copTask); ok {
partialAgg, finalAgg := p.newPartialAggregate()
if partialAgg != nil {
if cop.tablePlan != nil {
partialAgg.SetChildren(cop.tablePlan)
cop.tablePlan = partialAgg
} else {
partialAgg.SetChildren(cop.indexPlan)
cop.indexPlan = partialAgg
// We should not push agg down across double read, since the data of second read is ordered by handle instead of index.
// The `doubleReadNeedProj` is always set if the double read needs to keep order. So we just use it to decided
// whether the following plan is double read with order reserved.
if !cop.doubleReadNeedProj {
partialAgg, finalAgg := p.newPartialAggregate()
if partialAgg != nil {
if cop.tablePlan != nil {
cop.finishIndexPlan()
partialAgg.SetChildren(cop.tablePlan)
cop.tablePlan = partialAgg
} else {
partialAgg.SetChildren(cop.indexPlan)
cop.indexPlan = partialAgg
}
}
t = finishCopTask(p.ctx, cop)
attachPlan2Task(finalAgg, t)
} else {
t = finishCopTask(p.ctx, cop)
attachPlan2Task(p, t)
}
t = finishCopTask(p.ctx, cop)
attachPlan2Task(finalAgg, t)
} else {
attachPlan2Task(p, t)
}
Expand Down

0 comments on commit 252287a

Please sign in to comment.