github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/executor/aggregate_test.go (about) 1 // Copyright 2015 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package executor 15 16 import ( 17 . "github.com/insionng/yougam/libraries/pingcap/check" 18 "github.com/insionng/yougam/libraries/pingcap/tidb/ast" 19 "github.com/insionng/yougam/libraries/pingcap/tidb/evaluator" 20 "github.com/insionng/yougam/libraries/pingcap/tidb/util/mock" 21 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testleak" 22 "github.com/insionng/yougam/libraries/pingcap/tidb/util/testutil" 23 "github.com/insionng/yougam/libraries/pingcap/tidb/util/types" 24 ) 25 26 var _ = Suite(&testAggFuncSuite{}) 27 28 type testAggFuncSuite struct { 29 } 30 31 func (s *testAggFuncSuite) SetUpSuite(c *C) { 32 } 33 34 func (s *testAggFuncSuite) TearDownSuite(c *C) { 35 } 36 37 type mockExec struct { 38 fields []*ast.ResultField 39 rows []*Row 40 curRowIdx int 41 } 42 43 func (m *mockExec) Fields() []*ast.ResultField { 44 return m.fields 45 } 46 47 func (m *mockExec) Next() (*Row, error) { 48 if m.curRowIdx >= len(m.rows) { 49 return nil, nil 50 } 51 r := m.rows[m.curRowIdx] 52 m.curRowIdx++ 53 for i, d := range r.Data { 54 m.fields[i].Expr.SetValue(d.GetValue()) 55 } 56 return r, nil 57 } 58 59 func (m *mockExec) Close() error { 60 return nil 61 } 62 63 func (s *testAggFuncSuite) TestCount(c *C) { 64 defer testleak.AfterTest(c)() 65 // Compose aggregate exec for "select c1, count(c2) from t"; 66 // c1 c2 67 // 1 1 68 // 2 1 69 // 3 nil 70 c1 := ast.NewValueExpr(0) 71 rf1 := &ast.ResultField{Expr: c1} 72 col1 := &ast.ColumnNameExpr{Refer: rf1} 73 fc1 := &ast.AggregateFuncExpr{ 74 F: ast.AggFuncFirstRow, 75 Args: []ast.ExprNode{col1}, 76 } 77 c2 := ast.NewValueExpr(0) 78 rf2 := &ast.ResultField{Expr: c2} 79 col2 := &ast.ColumnNameExpr{Refer: rf2} 80 fc2 := &ast.AggregateFuncExpr{ 81 F: ast.AggFuncCount, 82 Args: []ast.ExprNode{col2}, 83 } 84 row1 := types.MakeDatums(1, 1) 85 row2 := types.MakeDatums(2, 1) 86 row3 := types.MakeDatums(3, nil) 87 data := []([]types.Datum){row1, row2, row3} 88 89 rows := make([]*Row, 0, 3) 90 for _, d := range data { 91 rows = append(rows, &Row{Data: d}) 92 } 93 src := &mockExec{ 94 rows: rows, 95 fields: []*ast.ResultField{rf1, rf2}, 96 } 97 agg := &AggregateExec{ 98 AggFuncs: []*ast.AggregateFuncExpr{fc1, fc2}, 99 Src: src, 100 } 101 ast.SetFlag(fc1) 102 ast.SetFlag(fc2) 103 var ( 104 row *Row 105 cnt int 106 ) 107 for { 108 r, err := agg.Next() 109 c.Assert(err, IsNil) 110 if r == nil { 111 break 112 } 113 row = r 114 cnt++ 115 } 116 c.Assert(cnt, Equals, 1) 117 c.Assert(row, NotNil) 118 ctx := mock.NewContext() 119 val, err := evaluator.Eval(ctx, fc1) 120 c.Assert(err, IsNil) 121 c.Assert(val, testutil.DatumEquals, types.NewDatum(int64(1))) 122 val, err = evaluator.Eval(ctx, fc2) 123 c.Assert(err, IsNil) 124 c.Assert(val, testutil.DatumEquals, types.NewDatum(int64(2))) 125 126 agg.Close() 127 val, err = evaluator.Eval(ctx, fc1) 128 c.Assert(err, IsNil) 129 c.Assert(val.Kind(), Equals, types.KindNull) 130 val, err = evaluator.Eval(ctx, fc2) 131 c.Assert(err, IsNil) 132 c.Assert(val, testutil.DatumEquals, types.NewDatum(int64(0))) 133 }