Skip to content

Commit

Permalink
plan: change distinct to aggregation. (pingcap#2515)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanfei1991 authored and shenli committed Jan 20, 2017
1 parent 30f97af commit 2cad815
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
2 changes: 2 additions & 0 deletions executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ func (s *testSuite) TestAggregation(c *C) {
tk.MustExec("insert t values (4, 3)")
result := tk.MustQuery("select count(*) from t group by d")
result.Check(testkit.Rows("3", "2", "2"))
result = tk.MustQuery("select distinct 99 from t group by d having d > 0")
result.Check(testkit.Rows("99"))
result = tk.MustQuery("select count(*) from t having 1 = 0")
result.Check(testkit.Rows())
result = tk.MustQuery("select c,d from t group by d")
Expand Down
27 changes: 17 additions & 10 deletions plan/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,14 +325,21 @@ func (b *planBuilder) buildProjection(p LogicalPlan, fields []*ast.SelectField,
return proj, oldLen
}

func (b *planBuilder) buildDistinct(src LogicalPlan) LogicalPlan {
d := &Distinct{baseLogicalPlan: newBaseLogicalPlan(Dis, b.allocator)}
d.self = d
d.initIDAndContext(b.ctx)
addChild(d, src)
d.SetSchema(src.GetSchema())
d.SetCorrelated()
return d
func (b *planBuilder) buildDistinct(child LogicalPlan, length int) LogicalPlan {
agg := &Aggregation{
baseLogicalPlan: newBaseLogicalPlan(Agg, b.allocator),
AggFuncs: make([]expression.AggregationFunction, 0, child.GetSchema().Len()),
GroupByItems: expression.Column2Exprs(child.GetSchema().Clone().Columns[:length])}
agg.collectGroupByColumns()
for _, col := range child.GetSchema().Columns {
agg.AggFuncs = append(agg.AggFuncs, expression.NewAggFunction(ast.AggFuncFirstRow, []expression.Expression{col}, false))
}
agg.self = agg
agg.initIDAndContext(b.ctx)
addChild(agg, child)
agg.SetSchema(child.GetSchema().Clone())
agg.SetCorrelated()
return agg
}

func (b *planBuilder) buildUnion(union *ast.UnionStmt) LogicalPlan {
Expand Down Expand Up @@ -381,7 +388,7 @@ func (b *planBuilder) buildUnion(union *ast.UnionStmt) LogicalPlan {
var p LogicalPlan
p = u
if union.Distinct {
p = b.buildDistinct(u)
p = b.buildDistinct(u, u.GetSchema().Len())
}
if union.OrderBy != nil {
p = b.buildSort(p, union.OrderBy.Items, nil)
Expand Down Expand Up @@ -867,7 +874,7 @@ func (b *planBuilder) buildSelect(sel *ast.SelectStmt) LogicalPlan {
}
}
if sel.Distinct {
p = b.buildDistinct(p)
p = b.buildDistinct(p, oldLen)
if b.err != nil {
return nil
}
Expand Down
13 changes: 11 additions & 2 deletions plan/physical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ func (s *testPlanSuite) TestPushDownAggregation(c *C) {
aggFields: "[blob bigint(21)]",
gbyItems: "[]",
},
{
sql: "select distinct a,b from t",
best: "Table(t)->HashAgg",
aggFuns: "[firstrow(test.t.a) firstrow(test.t.b)]",
aggFields: "[blob int int]",
gbyItems: "[test.t.a test.t.b]",
},
{
sql: "select sum(b) from t group by c",
best: "Table(t)->HashAgg->Projection",
Expand Down Expand Up @@ -76,6 +83,8 @@ func (s *testPlanSuite) TestPushDownAggregation(c *C) {
_, lp, err = lp.PredicatePushDown(nil)
c.Assert(err, IsNil)
lp.PruneColumns(lp.GetSchema().Columns)
solver := &aggPushDownSolver{builder.allocator, builder.ctx}
solver.aggPushDown(lp)
lp.ResolveIndicesAndCorCols()
info, err := lp.convert2PhysicalPlan(&requiredProperty{})
c.Assert(err, IsNil)
Expand Down Expand Up @@ -483,15 +492,15 @@ func (s *testPlanSuite) TestCBO(c *C) {
},
{
sql: "select * from (select t.a from t union select t.d from t where t.c = 1 union select t.c from t) k order by a limit 1",
best: "UnionAll{Table(t)->Index(t.c_d_e)[[1,1]]->Projection->Table(t)}->Distinct->Sort + Limit(1) + Offset(0)",
best: "UnionAll{Table(t)->HashAgg->Index(t.c_d_e)[[1,1]]->HashAgg->Table(t)->HashAgg}->HashAgg->Sort + Limit(1) + Offset(0)",
},
{
sql: "select * from (select t.a from t union all select t.d from t where t.c = 1 union all select t.c from t) k order by a limit 1",
best: "UnionAll{Table(t)->Limit->Index(t.c_d_e)[[1,1]]->Projection->Index(t.c_d_e)[[<nil>,+inf]]->Limit}->Sort + Limit(1) + Offset(0)",
},
{
sql: "select * from (select t.a from t union select t.d from t union select t.c from t) k order by a limit 1",
best: "UnionAll{Table(t)->Table(t)->Table(t)}->Distinct->Sort + Limit(1) + Offset(0)",
best: "UnionAll{Table(t)->HashAgg->Table(t)->HashAgg->Table(t)->HashAgg}->HashAgg->Sort + Limit(1) + Offset(0)",
},
}
for _, ca := range cases {
Expand Down

0 comments on commit 2cad815

Please sign in to comment.