Skip to content

Commit

Permalink
executor/aggfuncs: add test for max and min
Browse files Browse the repository at this point in the history
  • Loading branch information
Xuanwo committed Oct 23, 2018
1 parent 76f84f4 commit f1a68da
Showing 1 changed file with 163 additions and 0 deletions.
163 changes: 163 additions & 0 deletions executor/aggfuncs/func_max_min_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,59 @@ import (
"github.com/pingcap/tidb/util/chunk"
)

func (s *testSuite) TestMergePartialResult4MaxDecimal(c *C) {
srcChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeNewDecimal)}, 5)
for i := int64(0); i < 5; i++ {
srcChk.AppendMyDecimal(0, types.NewDecFromInt(i))
}
iter := chunk.NewIterator4Chunk(srcChk)

desc := &aggregation.AggFuncDesc{
Name: ast.AggFuncMax,
Mode: aggregation.CompleteMode,
Args: []expression.Expression{&expression.Column{RetType: types.NewFieldType(mysql.TypeLonglong), Index: 0}},
RetTp: types.NewFieldType(mysql.TypeNewDecimal),
}
finalDesc := desc.Split([]int{0})

// build max func for partial phase.
partialMaxFunc := aggfuncs.Build(s.ctx, desc, 0)
partialPr1 := partialMaxFunc.AllocPartialResult()
partialPr2 := partialMaxFunc.AllocPartialResult()

// build final func for final phase.
finalMaxFunc := aggfuncs.Build(s.ctx, finalDesc, 0)
finalPr := finalMaxFunc.AllocPartialResult()
resultChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeNewDecimal)}, 1)

// update partial result.
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
partialMaxFunc.UpdatePartialResult(s.ctx, []chunk.Row{row}, partialPr1)
}
partialMaxFunc.AppendFinalResult2Chunk(s.ctx, partialPr1, resultChk)
c.Assert(resultChk.GetRow(0).GetMyDecimal(0).Compare(types.NewDecFromInt(4)) == 0, IsTrue)

row := iter.Begin()
row = iter.Next()
for row = iter.Next(); row != iter.End(); row = iter.Next() {
partialMaxFunc.UpdatePartialResult(s.ctx, []chunk.Row{row}, partialPr2)
}
resultChk.Reset()
partialMaxFunc.AppendFinalResult2Chunk(s.ctx, partialPr2, resultChk)
c.Assert(resultChk.GetRow(0).GetMyDecimal(0).Compare(types.NewDecFromInt(4)) == 0, IsTrue)

// merge two partial results.
err := finalMaxFunc.MergePartialResult(s.ctx, partialPr1, finalPr)
c.Assert(err, IsNil)
err = finalMaxFunc.MergePartialResult(s.ctx, partialPr2, finalPr)
c.Assert(err, IsNil)

resultChk.Reset()
err = finalMaxFunc.AppendFinalResult2Chunk(s.ctx, finalPr, resultChk)
c.Assert(err, IsNil)
c.Assert(resultChk.GetRow(0).GetMyDecimal(0).Compare(types.NewDecFromInt(4)) == 0, IsTrue)
}

func (s *testSuite) TestMergePartialResult4MaxFloat(c *C) {
srcChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeDouble)}, 5)
for i := int64(0); i < 5; i++ {
Expand Down Expand Up @@ -76,3 +129,113 @@ func (s *testSuite) TestMergePartialResult4MaxFloat(c *C) {
c.Assert(err, IsNil)
c.Assert(resultChk.GetRow(0).GetFloat64(0) == float64(4), IsTrue)
}

func (s *testSuite) TestMergePartialResult4MinDecimal(c *C) {
srcChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeNewDecimal)}, 5)
for i := int64(0); i < 5; i++ {
srcChk.AppendMyDecimal(0, types.NewDecFromInt(i))
}
iter := chunk.NewIterator4Chunk(srcChk)

desc := &aggregation.AggFuncDesc{
Name: ast.AggFuncMin,
Mode: aggregation.CompleteMode,
Args: []expression.Expression{&expression.Column{RetType: types.NewFieldType(mysql.TypeLonglong), Index: 0}},
RetTp: types.NewFieldType(mysql.TypeNewDecimal),
}
finalDesc := desc.Split([]int{0})

// build min func for partial phase.
partialMinFunc := aggfuncs.Build(s.ctx, desc, 0)
partialPr1 := partialMinFunc.AllocPartialResult()
partialPr2 := partialMinFunc.AllocPartialResult()

// build final func for final phase.
finalMinFunc := aggfuncs.Build(s.ctx, finalDesc, 0)
finalPr := finalMinFunc.AllocPartialResult()
resultChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeNewDecimal)}, 1)

// update partial result.
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
partialMinFunc.UpdatePartialResult(s.ctx, []chunk.Row{row}, partialPr1)
}
partialMinFunc.AppendFinalResult2Chunk(s.ctx, partialPr1, resultChk)
c.Assert(resultChk.GetRow(0).GetMyDecimal(0).Compare(types.NewDecFromInt(0)) == 0, IsTrue)

row := iter.Begin()
row = iter.Next()
for row = iter.Next(); row != iter.End(); row = iter.Next() {
partialMinFunc.UpdatePartialResult(s.ctx, []chunk.Row{row}, partialPr2)
}
resultChk.Reset()
partialMinFunc.AppendFinalResult2Chunk(s.ctx, partialPr2, resultChk)
// Min in [2,3,4] -> 2
c.Assert(resultChk.GetRow(0).GetMyDecimal(0).Compare(types.NewDecFromInt(2)) == 0, IsTrue)

// merge two partial results.
err := finalMinFunc.MergePartialResult(s.ctx, partialPr1, finalPr)
c.Assert(err, IsNil)
err = finalMinFunc.MergePartialResult(s.ctx, partialPr2, finalPr)
c.Assert(err, IsNil)

resultChk.Reset()
err = finalMinFunc.AppendFinalResult2Chunk(s.ctx, finalPr, resultChk)
c.Assert(err, IsNil)
// Min in [0,1,2,3,4] -> 0
c.Assert(resultChk.GetRow(0).GetMyDecimal(0).Compare(types.NewDecFromInt(0)) == 0, IsTrue)
}

func (s *testSuite) TestMergePartialResult4MinFloat(c *C) {
srcChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeDouble)}, 5)
for i := int64(0); i < 5; i++ {
srcChk.AppendFloat64(0, float64(i))
}
iter := chunk.NewIterator4Chunk(srcChk)

desc := &aggregation.AggFuncDesc{
Name: ast.AggFuncMin,
Mode: aggregation.CompleteMode,
Args: []expression.Expression{&expression.Column{RetType: types.NewFieldType(mysql.TypeDouble), Index: 0}},
RetTp: types.NewFieldType(mysql.TypeDouble),
}
finalDesc := desc.Split([]int{0})

// build min func for partial phase.
partialMinFunc := aggfuncs.Build(s.ctx, desc, 0)
partialPr1 := partialMinFunc.AllocPartialResult()
partialPr2 := partialMinFunc.AllocPartialResult()

// build final func for final phase.
finalMinFunc := aggfuncs.Build(s.ctx, finalDesc, 0)
finalPr := finalMinFunc.AllocPartialResult()
resultChk := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeDouble)}, 1)

// update partial result.
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
partialMinFunc.UpdatePartialResult(s.ctx, []chunk.Row{row}, partialPr1)
}
partialMinFunc.AppendFinalResult2Chunk(s.ctx, partialPr1, resultChk)
c.Assert(resultChk.GetRow(0).GetFloat64(0) == float64(0), IsTrue)

row := iter.Begin()
row = iter.Next()
for row = iter.Next(); row != iter.End(); row = iter.Next() {
partialMinFunc.UpdatePartialResult(s.ctx, []chunk.Row{row}, partialPr2)
}
resultChk.Reset()
partialMinFunc.AppendFinalResult2Chunk(s.ctx, partialPr2, resultChk)
// Min in [2.0,3.0,4.0] -> 0
c.Assert(resultChk.GetRow(0).GetFloat64(0) == float64(2), IsTrue)

// merge two partial results.
err := finalMinFunc.MergePartialResult(s.ctx, partialPr1, finalPr)
c.Assert(err, IsNil)
err = finalMinFunc.MergePartialResult(s.ctx, partialPr2, finalPr)
c.Assert(err, IsNil)

resultChk.Reset()
err = finalMinFunc.AppendFinalResult2Chunk(s.ctx, finalPr, resultChk)
c.Assert(err, IsNil)
// Min in [0.0,1.0,2.0,3.0,4.0] -> 0
c.Assert(resultChk.GetRow(0).GetFloat64(0) == float64(0), IsTrue)
}

0 comments on commit f1a68da

Please sign in to comment.