func (s *testDecimalSuite) TestDecimalCodec(c *C) { defer testleak.AfterTest(c)() inputs := []struct { Input float64 }{ {float64(123400)}, {float64(1234)}, {float64(12.34)}, {float64(0.1234)}, {float64(0.01234)}, {float64(-0.1234)}, {float64(-0.01234)}, {float64(12.3400)}, {float64(-12.34)}, {float64(0.00000)}, {float64(0)}, {float64(-0.0)}, {float64(-0.000)}, } for _, input := range inputs { v := mysql.NewDecFromFloatForTest(input.Input) b := EncodeDecimal([]byte{}, types.NewDatum(v)) _, d, err := DecodeDecimal(b) c.Assert(err, IsNil) c.Assert(v.Compare(d.GetMysqlDecimal()), Equals, 0) } }
func (s *testDecimalSuite) TestFrac(c *C) { defer testleak.AfterTest(c)() inputs := []struct { Input *mysql.MyDecimal }{ {mysql.NewDecFromInt(3)}, {mysql.NewDecFromFloatForTest(0.03)}, } for _, v := range inputs { testFrac(c, v.Input) } }
// TODO: add more tests. func (s *testEvalSuite) TestEval(c *C) { colID := int64(1) row := make(map[int64]types.Datum) row[colID] = types.NewIntDatum(100) xevaluator := &Evaluator{Row: row} cases := []struct { expr *tipb.Expr result types.Datum }{ // Datums. { datumExpr(types.NewFloat32Datum(1.1)), types.NewFloat32Datum(1.1), }, { datumExpr(types.NewFloat64Datum(1.1)), types.NewFloat64Datum(1.1), }, { datumExpr(types.NewIntDatum(1)), types.NewIntDatum(1), }, { datumExpr(types.NewUintDatum(1)), types.NewUintDatum(1), }, { datumExpr(types.NewBytesDatum([]byte("abc"))), types.NewBytesDatum([]byte("abc")), }, { datumExpr(types.NewStringDatum("abc")), types.NewStringDatum("abc"), }, { datumExpr(types.Datum{}), types.Datum{}, }, { datumExpr(types.NewDurationDatum(mysql.Duration{Duration: time.Hour})), types.NewDurationDatum(mysql.Duration{Duration: time.Hour}), }, { datumExpr(types.NewDecimalDatum(mysql.NewDecFromFloatForTest(1.1))), types.NewDecimalDatum(mysql.NewDecFromFloatForTest(1.1)), }, { columnExpr(1), types.NewIntDatum(100), }, // Comparison operations. { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(1), tipb.ExprType_LT), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(1), types.NewIntDatum(100), tipb.ExprType_LT), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(100), types.Datum{}, tipb.ExprType_LT), types.Datum{}, }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(1), tipb.ExprType_LE), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(1), types.NewIntDatum(1), tipb.ExprType_LE), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(100), types.Datum{}, tipb.ExprType_LE), types.Datum{}, }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(1), tipb.ExprType_EQ), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(100), tipb.ExprType_EQ), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(100), types.Datum{}, tipb.ExprType_EQ), types.Datum{}, }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(100), tipb.ExprType_NE), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(1), tipb.ExprType_NE), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(100), types.Datum{}, tipb.ExprType_NE), types.Datum{}, }, { binaryExpr(types.NewIntDatum(1), types.NewIntDatum(100), tipb.ExprType_GE), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(100), tipb.ExprType_GE), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(100), types.Datum{}, tipb.ExprType_GE), types.Datum{}, }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(100), tipb.ExprType_GT), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(100), types.NewIntDatum(1), tipb.ExprType_GT), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(100), types.Datum{}, tipb.ExprType_GT), types.Datum{}, }, { binaryExpr(types.NewIntDatum(1), types.Datum{}, tipb.ExprType_NullEQ), types.NewIntDatum(0), }, { binaryExpr(types.Datum{}, types.Datum{}, tipb.ExprType_NullEQ), types.NewIntDatum(1), }, // Logic operation. { binaryExpr(types.NewIntDatum(0), types.NewIntDatum(1), tipb.ExprType_And), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(1), types.NewIntDatum(1), tipb.ExprType_And), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(0), types.Datum{}, tipb.ExprType_And), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(1), types.Datum{}, tipb.ExprType_And), types.Datum{}, }, { binaryExpr(types.NewIntDatum(0), types.NewIntDatum(0), tipb.ExprType_Or), types.NewIntDatum(0), }, { binaryExpr(types.NewIntDatum(0), types.NewIntDatum(1), tipb.ExprType_Or), types.NewIntDatum(1), }, { binaryExpr(types.NewIntDatum(0), types.Datum{}, tipb.ExprType_Or), types.Datum{}, }, { binaryExpr(types.NewIntDatum(1), types.Datum{}, tipb.ExprType_Or), types.NewIntDatum(1), }, { binaryExpr( binaryExpr(types.NewIntDatum(1), types.NewIntDatum(1), tipb.ExprType_EQ), binaryExpr(types.NewIntDatum(1), types.NewIntDatum(1), tipb.ExprType_EQ), tipb.ExprType_And), types.NewIntDatum(1), }, { notExpr(datumExpr(types.NewIntDatum(1))), types.NewIntDatum(0), }, { notExpr(datumExpr(types.NewIntDatum(0))), types.NewIntDatum(1), }, { notExpr(datumExpr(types.Datum{})), types.Datum{}, }, } for _, ca := range cases { result, err := xevaluator.Eval(ca.expr) c.Assert(err, IsNil) c.Assert(result.Kind(), Equals, ca.result.Kind()) cmp, err := result.CompareDatum(ca.result) c.Assert(err, IsNil) c.Assert(cmp, Equals, 0) } }
func (s *testCodecSuite) TestCut(c *C) { defer testleak.AfterTest(c)() table := []struct { Input []types.Datum Expect []types.Datum }{ { types.MakeDatums(int64(1)), types.MakeDatums(int64(1)), }, { types.MakeDatums(float32(1), float64(3.15), []byte("123"), "123"), types.MakeDatums(float64(1), float64(3.15), []byte("123"), []byte("123")), }, { types.MakeDatums(uint64(1), float64(3.15), []byte("123"), int64(-1)), types.MakeDatums(uint64(1), float64(3.15), []byte("123"), int64(-1)), }, { types.MakeDatums(true, false), types.MakeDatums(int64(1), int64(0)), }, { types.MakeDatums(nil), types.MakeDatums(nil), }, { types.MakeDatums(mysql.Hex{Value: 100}, mysql.Bit{Value: 100, Width: 8}), types.MakeDatums(int64(100), uint64(100)), }, { types.MakeDatums(mysql.Enum{Name: "a", Value: 1}, mysql.Set{Name: "a", Value: 1}), types.MakeDatums(uint64(1), uint64(1)), }, { types.MakeDatums(float32(1), float64(3.15), []byte("123456789012345")), types.MakeDatums(float64(1), float64(3.15), []byte("123456789012345")), }, { types.MakeDatums(mysql.NewDecFromInt(0), mysql.NewDecFromFloatForTest(-1.3)), types.MakeDatums(mysql.NewDecFromInt(0), mysql.NewDecFromFloatForTest(-1.3)), }, } for i, t := range table { comment := Commentf("%d %v", i, t) b, err := EncodeKey(nil, t.Input...) c.Assert(err, IsNil, comment) var d []byte for j, e := range t.Expect { d, b, err = CutOne(b) c.Assert(err, IsNil) c.Assert(d, NotNil) ed, err1 := EncodeKey(nil, e) c.Assert(err1, IsNil) c.Assert(d, DeepEquals, ed, Commentf("%d:%d %#v", i, j, e)) } c.Assert(b, HasLen, 0) } for i, t := range table { comment := Commentf("%d %v", i, t) b, err := EncodeValue(nil, t.Input...) c.Assert(err, IsNil, comment) var d []byte for j, e := range t.Expect { d, b, err = CutOne(b) c.Assert(err, IsNil) c.Assert(d, NotNil) ed, err1 := EncodeValue(nil, e) c.Assert(err1, IsNil) c.Assert(d, DeepEquals, ed, Commentf("%d:%d %#v", i, j, e)) } c.Assert(b, HasLen, 0) } }
func (s *testCodecSuite) TestDecimal(c *C) { defer testleak.AfterTest(c)() tbl := []string{ "1234.00", "1234", "12.34", "12.340", "0.1234", "0.0", "0", "-0.0", "-0.0000", "-1234.00", "-1234", "-12.34", "-12.340", "-0.1234", } for _, t := range tbl { dec := new(mysql.MyDecimal) err := dec.FromString([]byte(t)) c.Assert(err, IsNil) b, err := EncodeKey(nil, types.NewDatum(dec)) c.Assert(err, IsNil) v, err := Decode(b) c.Assert(err, IsNil) c.Assert(v, HasLen, 1) vv := v[0].GetMysqlDecimal() c.Assert(vv.Compare(dec), Equals, 0) } tblCmp := []struct { Arg1 interface{} Arg2 interface{} Ret int }{ // Test for float type decimal. {"1234", "123400", -1}, {"12340", "123400", -1}, {"1234", "1234.5", -1}, {"1234", "1234.0000", 0}, {"1234", "12.34", 1}, {"12.34", "12.35", -1}, {"0.12", "0.1234", -1}, {"0.1234", "12.3400", -1}, {"0.1234", "0.1235", -1}, {"0.123400", "12.34", -1}, {"12.34000", "12.34", 0}, {"0.01234", "0.01235", -1}, {"0.1234", "0", 1}, {"0.0000", "0", 0}, {"0.0001", "0", 1}, {"0.0001", "0.0000", 1}, {"0", "-0.0000", 0}, {"-0.0001", "0", -1}, {"-0.1234", "0", -1}, {"-0.1234", "-0.12", -1}, {"-0.12", "-0.1234", 1}, {"-0.12", "-0.1200", 0}, {"-0.1234", "0.1234", -1}, {"-1.234", "-12.34", 1}, {"-0.1234", "-12.34", 1}, {"-12.34", "1234", -1}, {"-12.34", "-12.35", 1}, {"-0.01234", "-0.01235", 1}, {"-1234", "-123400", 1}, {"-12340", "-123400", 1}, // Test for int type decimal. {int64(-1), int64(1), -1}, {int64(math.MaxInt64), int64(math.MinInt64), 1}, {int64(math.MaxInt64), int64(math.MaxInt32), 1}, {int64(math.MinInt32), int64(math.MaxInt16), -1}, {int64(math.MinInt64), int64(math.MaxInt8), -1}, {int64(0), int64(math.MaxInt8), -1}, {int64(math.MinInt8), int64(0), -1}, {int64(math.MinInt16), int64(math.MaxInt16), -1}, {int64(1), int64(-1), 1}, {int64(1), int64(0), 1}, {int64(-1), int64(0), -1}, {int64(0), int64(0), 0}, {int64(math.MaxInt16), int64(math.MaxInt16), 0}, // Test for uint type decimal. {uint64(0), uint64(0), 0}, {uint64(1), uint64(0), 1}, {uint64(0), uint64(1), -1}, {uint64(math.MaxInt8), uint64(math.MaxInt16), -1}, {uint64(math.MaxUint32), uint64(math.MaxInt32), 1}, {uint64(math.MaxUint8), uint64(math.MaxInt8), 1}, {uint64(math.MaxUint16), uint64(math.MaxInt32), -1}, {uint64(math.MaxUint64), uint64(math.MaxInt64), 1}, {uint64(math.MaxInt64), uint64(math.MaxUint32), 1}, {uint64(math.MaxUint64), uint64(0), 1}, {uint64(0), uint64(math.MaxUint64), -1}, } for _, t := range tblCmp { d1 := types.NewDatum(t.Arg1) dec1, err := d1.ToDecimal() c.Assert(err, IsNil) d1.SetMysqlDecimal(dec1) d2 := types.NewDatum(t.Arg2) dec2, err := d2.ToDecimal() c.Assert(err, IsNil) d2.SetMysqlDecimal(dec2) d1.SetLength(30) d1.SetFrac(6) d2.SetLength(30) d2.SetFrac(6) b1, err := EncodeKey(nil, d1) c.Assert(err, IsNil) b2, err := EncodeKey(nil, d2) c.Assert(err, IsNil) ret := bytes.Compare(b1, b2) c.Assert(ret, Equals, t.Ret, Commentf("%v %x %x", t, b1, b2)) } floats := []float64{-123.45, -123.40, -23.45, -1.43, -0.93, -0.4333, -0.068, -0.0099, 0, 0.001, 0.0012, 0.12, 1.2, 1.23, 123.3, 2424.242424} var decs [][]byte for i := range floats { dec := mysql.NewDecFromFloatForTest(floats[i]) var d types.Datum d.SetLength(20) d.SetFrac(6) d.SetMysqlDecimal(dec) decs = append(decs, EncodeDecimal(nil, d)) } for i := 0; i < len(decs)-1; i++ { cmp := bytes.Compare(decs[i], decs[i+1]) c.Assert(cmp, LessEqual, 0) } }
// TODO: add more tests. func (s *testEvalSuite) TestEval(c *C) { colID := int64(1) row := make(map[int64]types.Datum) row[colID] = types.NewIntDatum(100) xevaluator := &Evaluator{Row: row} cases := []struct { expr *tipb.Expr result types.Datum }{ // Datums. { datumExpr(types.NewFloat32Datum(1.1)), types.NewFloat32Datum(1.1), }, { datumExpr(types.NewFloat64Datum(1.1)), types.NewFloat64Datum(1.1), }, { datumExpr(types.NewIntDatum(1)), types.NewIntDatum(1), }, { datumExpr(types.NewUintDatum(1)), types.NewUintDatum(1), }, { datumExpr(types.NewBytesDatum([]byte("abc"))), types.NewBytesDatum([]byte("abc")), }, { datumExpr(types.NewStringDatum("abc")), types.NewStringDatum("abc"), }, { datumExpr(types.Datum{}), types.Datum{}, }, { datumExpr(types.NewDurationDatum(mysql.Duration{Duration: time.Hour})), types.NewDurationDatum(mysql.Duration{Duration: time.Hour}), }, { datumExpr(types.NewDecimalDatum(mysql.NewDecFromFloatForTest(1.1))), types.NewDecimalDatum(mysql.NewDecFromFloatForTest(1.1)), }, { columnExpr(1), types.NewIntDatum(100), }, // Comparison operations. { buildExpr(tipb.ExprType_LT, types.NewIntDatum(100), types.NewIntDatum(1)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_LT, types.NewIntDatum(1), types.NewIntDatum(100)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_LT, types.NewIntDatum(100), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_LE, types.NewIntDatum(100), types.NewIntDatum(1)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_LE, types.NewIntDatum(1), types.NewIntDatum(1)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_LE, types.NewIntDatum(100), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_EQ, types.NewIntDatum(100), types.NewIntDatum(1)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_EQ, types.NewIntDatum(100), types.NewIntDatum(100)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_EQ, types.NewIntDatum(100), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_NE, types.NewIntDatum(100), types.NewIntDatum(100)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_NE, types.NewIntDatum(100), types.NewIntDatum(1)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_NE, types.NewIntDatum(100), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_GE, types.NewIntDatum(1), types.NewIntDatum(100)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_GE, types.NewIntDatum(100), types.NewIntDatum(100)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_GE, types.NewIntDatum(100), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_GT, types.NewIntDatum(100), types.NewIntDatum(100)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_GT, types.NewIntDatum(100), types.NewIntDatum(1)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_GT, types.NewIntDatum(100), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_NullEQ, types.NewIntDatum(1), types.Datum{}), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_NullEQ, types.Datum{}, types.Datum{}), types.NewIntDatum(1), }, // Logic operation. { buildExpr(tipb.ExprType_And, types.NewIntDatum(0), types.NewIntDatum(1)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_And, types.NewIntDatum(1), types.NewIntDatum(1)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_And, types.NewIntDatum(0), types.Datum{}), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_And, types.NewIntDatum(1), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_Or, types.NewIntDatum(0), types.NewIntDatum(0)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_Or, types.NewIntDatum(0), types.NewIntDatum(1)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_Or, types.NewIntDatum(0), types.Datum{}), types.Datum{}, }, { buildExpr(tipb.ExprType_Or, types.NewIntDatum(1), types.Datum{}), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_And, buildExpr(tipb.ExprType_EQ, types.NewIntDatum(1), types.NewIntDatum(1)), buildExpr(tipb.ExprType_EQ, types.NewIntDatum(1), types.NewIntDatum(1))), types.NewIntDatum(1), }, { notExpr(datumExpr(types.NewIntDatum(1))), types.NewIntDatum(0), }, { notExpr(datumExpr(types.NewIntDatum(0))), types.NewIntDatum(1), }, { notExpr(datumExpr(types.Datum{})), types.Datum{}, }, // Arithmetic operation. { buildExpr(tipb.ExprType_Plus, types.NewIntDatum(-1), types.NewIntDatum(1)), types.NewIntDatum(0), }, { buildExpr(tipb.ExprType_Plus, types.NewIntDatum(-1), types.NewFloat64Datum(1.5)), types.NewFloat64Datum(0.5), }, { buildExpr(tipb.ExprType_Minus, types.NewIntDatum(-1), types.NewIntDatum(1)), types.NewIntDatum(-2), }, { buildExpr(tipb.ExprType_Minus, types.NewIntDatum(-1), types.NewFloat64Datum(1.5)), types.NewFloat64Datum(-2.5), }, { buildExpr(tipb.ExprType_Mul, types.NewFloat64Datum(-1), types.NewFloat64Datum(1)), types.NewFloat64Datum(-1), }, { buildExpr(tipb.ExprType_Mul, types.NewFloat64Datum(-1.5), types.NewFloat64Datum(2)), types.NewFloat64Datum(-3), }, { buildExpr(tipb.ExprType_Div, types.NewFloat64Datum(-3), types.NewFloat64Datum(2)), types.NewFloat64Datum(-1.5), }, { buildExpr(tipb.ExprType_Div, types.NewFloat64Datum(-3), types.NewFloat64Datum(0)), types.NewDatum(nil), }, { buildExpr(tipb.ExprType_IntDiv, types.NewIntDatum(3), types.NewIntDatum(2)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_IntDiv, types.NewFloat64Datum(3.0), types.NewFloat64Datum(1.9)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_Mod, types.NewIntDatum(3), types.NewIntDatum(2)), types.NewIntDatum(1), }, { buildExpr(tipb.ExprType_Mod, types.NewFloat64Datum(3.0), types.NewFloat64Datum(1.9)), types.NewFloat64Datum(1.1), }, } for _, ca := range cases { result, err := xevaluator.Eval(ca.expr) c.Assert(err, IsNil) c.Assert(result.Kind(), Equals, ca.result.Kind()) cmp, err := result.CompareDatum(ca.result) c.Assert(err, IsNil) c.Assert(cmp, Equals, 0) } }
func (s *testAggFuncSuite) TestXAPIAvg(c *C) { defer testleak.AfterTest(c)() // Compose aggregate exec for "select avg(c2) from t groupby c1"; // // Data in region1: // c1 c2 // 1 11 // 2 21 // 1 1 // 3 2 // // Partial aggregate result for region1: // groupkey cnt sum // 1 2 12 // 2 1 21 // 3 1 2 // // Data in region2: // 1 nil // 1 3 // 3 31 // // Partial aggregate result for region2: // groupkey cnt sum // 1 1 3 // 3 1 31 // // Expected final aggregate result: // avg(c2) // 5 // 21 // 16.500000 c1 := ast.NewValueExpr([]byte{0}) rf1 := &ast.ResultField{Expr: c1} c2 := ast.NewValueExpr(0) rf2 := &ast.ResultField{Expr: c2} c3 := ast.NewValueExpr(0) rf3 := &ast.ResultField{Expr: c3} col2 := &ast.ColumnNameExpr{Refer: rf2} fc := &ast.AggregateFuncExpr{ F: ast.AggFuncAvg, Args: []ast.ExprNode{col2}, } // Return row: // GroupKey, Sum // Partial result from region1 row1 := types.MakeDatums([]byte{1}, 2, 12) row2 := types.MakeDatums([]byte{2}, 1, 21) row3 := types.MakeDatums([]byte{3}, 1, 2) // Partial result from region2 row4 := types.MakeDatums([]byte{1}, 1, 3) row5 := types.MakeDatums([]byte{3}, 1, 31) data := []([]types.Datum){row1, row2, row3, row4, row5} rows := make([]*Row, 0, 5) for _, d := range data { rows = append(rows, &Row{Data: d}) } src := &mockExec{ rows: rows, fields: []*ast.ResultField{rf1, rf2, rf3}, // groupby, cnt, sum } agg := &XAggregateExec{ AggFuncs: []*ast.AggregateFuncExpr{fc}, Src: src, } ast.SetFlag(fc) // First row: 5 row, err := agg.Next() c.Assert(err, IsNil) c.Assert(row, NotNil) ctx := mock.NewContext() val, err := evaluator.Eval(ctx, fc) c.Assert(err, IsNil) c.Assert(val, testutil.DatumEquals, types.NewDecimalDatum(mysql.NewDecFromInt(5))) // Second row: 21 row, err = agg.Next() c.Assert(err, IsNil) c.Assert(row, NotNil) val, err = evaluator.Eval(ctx, fc) c.Assert(err, IsNil) c.Assert(val, testutil.DatumEquals, types.NewDecimalDatum(mysql.NewDecFromInt(21))) // Third row: 16.5000 row, err = agg.Next() c.Assert(err, IsNil) c.Assert(row, NotNil) val, err = evaluator.Eval(ctx, fc) c.Assert(err, IsNil) d := mysql.NewDecFromFloatForTest(16.5) c.Logf("d1 %s, d2 %s, cmp %d", d.String(), val.GetMysqlDecimal().String(), val.GetMysqlDecimal().Compare(d)) c.Assert(val, testutil.DatumEquals, types.NewDecimalDatum(d)) // Forth row: nil row, err = agg.Next() c.Assert(err, IsNil) c.Assert(row, IsNil) // Close executor err = agg.Close() c.Assert(err, IsNil) }