Skip to content

Commit

Permalink
expression: let first_row get the first value no matter if it's null (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
hanfei1991 authored Nov 22, 2016
1 parent c9d114f commit 7e041d2
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 7 deletions.
1 change: 1 addition & 0 deletions ast/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -531,4 +531,5 @@ type AggEvaluateContext struct {
Count int64
Value types.Datum
Buffer *bytes.Buffer // Buffer is used for group_concat.
GotFirstRow bool // It will check if the agg has met the first row key.
}
6 changes: 4 additions & 2 deletions executor/aggregate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ func (s *testSuite) TestAggregation(c *C) {
result.Check(testkit.Rows("3", "2", "2"))
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")
result.Check(testkit.Rows("<nil> 1", "1 2", "1 3"))
result = tk.MustQuery("select - c, c as d from t group by c having null not between c and avg(distinct d) - d")
result.Check(testkit.Rows())
result = tk.MustQuery("select - c as c from t group by c having t.c > 5")
Expand All @@ -90,7 +92,7 @@ func (s *testSuite) TestAggregation(c *C) {
result = tk.MustQuery("select c as a from t group by d having a < 0")
result.Check(testkit.Rows())
result = tk.MustQuery("select c as a from t group by d having sum(a) = 2")
result.Check(testkit.Rows("1"))
result.Check(testkit.Rows("<nil>"))
result = tk.MustQuery("select count(distinct c) from t group by d")
result.Check(testkit.Rows("1", "2", "2"))
result = tk.MustQuery("select sum(c) from t group by d")
Expand Down Expand Up @@ -152,7 +154,7 @@ func (s *testSuite) TestAggregation(c *C) {
result = tk.MustQuery("select count(*) from t a join t b where a.c < 0")
result.Check(testkit.Rows("0"))
result = tk.MustQuery("select sum(b.c), count(b.d), a.c from t a left join t b on a.c = b.d group by b.d order by b.d")
result.Check(testkit.Rows("<nil> 0 4", "8 12 1", "5 2 3"))
result.Check(testkit.Rows("<nil> 0 <nil>", "8 12 1", "5 2 3"))
// This two cases prove that having always resolve name from field list firstly.
result = tk.MustQuery("select 1-d as d from t having d < 0 order by d desc")
result.Check(testkit.Rows("-1", "-1", "-2", "-2"))
Expand Down
6 changes: 4 additions & 2 deletions expression/aggregation.go
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ func (ff *firstRowFunction) GetType() *types.FieldType {
// Update implements AggregationFunction interface.
func (ff *firstRowFunction) Update(row []types.Datum, groupKey []byte, ectx context.Context) error {
ctx := ff.getContext(groupKey)
if !ctx.Value.IsNull() {
if ctx.GotFirstRow {
return nil
}
if len(ff.Args) != 1 {
Expand All @@ -839,13 +839,14 @@ func (ff *firstRowFunction) Update(row []types.Datum, groupKey []byte, ectx cont
return errors.Trace(err)
}
ctx.Value = value
ctx.GotFirstRow = true
return nil
}

// StreamUpdate implements AggregationFunction interface.
func (ff *firstRowFunction) StreamUpdate(row []types.Datum, ectx context.Context) error {
ctx := ff.getStreamedContext()
if !ctx.Value.IsNull() {
if ctx.GotFirstRow {
return nil
}
if len(ff.Args) != 1 {
Expand All @@ -856,6 +857,7 @@ func (ff *firstRowFunction) StreamUpdate(row []types.Datum, ectx context.Context
return errors.Trace(err)
}
ctx.Value = value
ctx.GotFirstRow = true
return nil
}

Expand Down
7 changes: 5 additions & 2 deletions store/localstore/local_aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,12 @@ func (rs *localRegion) aggregate(ctx *selectContext, h int64, row map[int64][]by
type aggItem struct {
// Number of rows, this could be used in cout/avg
count uint64
// This could be used to store sum/max/min
// This could be used to store sum/max/min/first
value types.Datum
// TODO: support group_concat
buffer *bytes.Buffer // Buffer is used for group_concat.
// It will check if the agg has met the first row key.
gotFirstRow bool
}

// This is similar to ast.AggregateFuncExpr but use tipb.Expr.
Expand Down Expand Up @@ -200,13 +202,14 @@ func (n *aggregateFuncExpr) updateCount(ctx *selectContext, args []types.Datum)

func (n *aggregateFuncExpr) updateFirst(ctx *selectContext, args []types.Datum) error {
aggItem := n.getAggItem()
if !aggItem.value.IsNull() {
if aggItem.gotFirstRow {
return nil
}
if len(args) != 1 {
return errors.New("Wrong number of args for AggFuncFirstRow")
}
aggItem.value = args[0]
aggItem.gotFirstRow = true
return nil
}

Expand Down
5 changes: 4 additions & 1 deletion store/tikv/mock-tikv/aggregate.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ type aggItem struct {
value types.Datum
// TODO: support group_concat
buffer *bytes.Buffer // Buffer is used for group_concat.
// It will check if the agg has met the first row key.
gotFirstRow bool
}

// This is similar to ast.AggregateFuncExpr but use tipb.Expr.
Expand Down Expand Up @@ -200,13 +202,14 @@ func (n *aggregateFuncExpr) updateCount(ctx *selectContext, args []types.Datum)

func (n *aggregateFuncExpr) updateFirst(ctx *selectContext, args []types.Datum) error {
aggItem := n.getAggItem()
if !aggItem.value.IsNull() {
if aggItem.gotFirstRow {
return nil
}
if len(args) != 1 {
return errors.New("Wrong number of args for AggFuncFirstRow")
}
aggItem.value = args[0]
aggItem.gotFirstRow = true
return nil
}

Expand Down

0 comments on commit 7e041d2

Please sign in to comment.