Skip to content

Commit 35e308f

Browse files
SunRunAwaysre-bot
authored andcommitted
expression: go generate vectorized addtime functions (pingcap#12224)
1 parent 2dc6264 commit 35e308f

14 files changed

+1393
-111
lines changed

.codecov.yml

+1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ ignore:
4242
- "ddl/testutil/.*"
4343
- "executor/seqtest/.*"
4444
- "metrics/.*"
45+
- "expression/generator/.*"
4546

expression/bench_test.go

+45-18
Original file line numberDiff line numberDiff line change
@@ -449,11 +449,12 @@ func eType2FieldType(eType types.EvalType) *types.FieldType {
449449
}
450450

451451
func genVecExprBenchCase(ctx sessionctx.Context, funcName string, testCase vecExprBenchCase) (expr Expression, fts []*types.FieldType, input *chunk.Chunk, output *chunk.Chunk) {
452-
fts = testCase.childrenFieldTypes
453-
if fts == nil {
454-
fts = make([]*types.FieldType, len(testCase.childrenTypes))
455-
for i, eType := range testCase.childrenTypes {
456-
fts[i] = eType2FieldType(eType)
452+
fts = make([]*types.FieldType, len(testCase.childrenTypes))
453+
for i := range fts {
454+
if i < len(testCase.childrenFieldTypes) && testCase.childrenFieldTypes[i] != nil {
455+
fts[i] = testCase.childrenFieldTypes[i]
456+
} else {
457+
fts[i] = eType2FieldType(testCase.childrenTypes[i])
457458
}
458459
}
459460
cols := make([]Expression, len(testCase.childrenTypes))
@@ -580,11 +581,12 @@ func benchmarkVectorizedEvalOneVec(b *testing.B, vecExprCases vecExprBenchCases)
580581

581582
func genVecBuiltinFuncBenchCase(ctx sessionctx.Context, funcName string, testCase vecExprBenchCase) (baseFunc builtinFunc, fts []*types.FieldType, input *chunk.Chunk, result *chunk.Column) {
582583
childrenNumber := len(testCase.childrenTypes)
583-
fts = testCase.childrenFieldTypes
584-
if fts == nil {
585-
fts = make([]*types.FieldType, childrenNumber)
586-
for i, eType := range testCase.childrenTypes {
587-
fts[i] = eType2FieldType(eType)
584+
fts = make([]*types.FieldType, childrenNumber)
585+
for i := range fts {
586+
if i < len(testCase.childrenFieldTypes) && testCase.childrenFieldTypes[i] != nil {
587+
fts[i] = testCase.childrenFieldTypes[i]
588+
} else {
589+
fts[i] = eType2FieldType(testCase.childrenTypes[i])
588590
}
589591
}
590592
cols := make([]Expression, childrenNumber)
@@ -622,9 +624,18 @@ func genVecBuiltinFuncBenchCase(ctx sessionctx.Context, funcName string, testCas
622624
panic(err)
623625
}
624626
result = chunk.NewColumn(eType2FieldType(testCase.retEvalType), 1024)
627+
// Mess up the output to make sure vecEvalXXX to call ResizeXXX/ReserveXXX itself.
628+
result.AppendNull()
625629
return baseFunc, fts, input, result
626630
}
627631

632+
// a hack way to calculate length of a chunk.Column.
633+
func getColumnLen(col *chunk.Column, eType types.EvalType) int {
634+
chk := chunk.New([]*types.FieldType{eType2FieldType(eType)}, 1024, 1024)
635+
chk.SetCol(0, col)
636+
return chk.NumRows()
637+
}
638+
628639
// testVectorizedBuiltinFunc is used to verify that the vectorized
629640
// expression is evaluated correctly
630641
func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
@@ -645,8 +656,10 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
645656
if !testAll && testFunc[baseFuncName] != true {
646657
continue
647658
}
659+
// do not forget to implement the vectorized method.
660+
c.Assert(baseFunc.vectorized(), IsTrue, Commentf("func: %v", baseFuncName))
648661
commentf := func(row int) CommentInterface {
649-
return Commentf("case %+v, row: %v, rowData: %v", testCase, row, input.GetRow(row).GetDatumRow(fts))
662+
return Commentf("func: %v, case %+v, row: %v, rowData: %v", baseFuncName, testCase, row, input.GetRow(row).GetDatumRow(fts))
650663
}
651664
it := chunk.NewIterator4Chunk(input)
652665
i := 0
@@ -655,12 +668,14 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
655668
case types.ETInt:
656669
err := baseFunc.vecEvalInt(input, output)
657670
c.Assert(err, IsNil)
671+
// do not forget to call ResizeXXX/ReserveXXX
672+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
658673
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
659674
i64s := output.Int64s()
660675
for row := it.Begin(); row != it.End(); row = it.Next() {
661676
val, isNull, err := baseFunc.evalInt(row)
662677
c.Assert(err, IsNil)
663-
c.Assert(isNull, Equals, output.IsNull(i))
678+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
664679
if !isNull {
665680
c.Assert(val, Equals, i64s[i], commentf(i))
666681
}
@@ -669,12 +684,14 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
669684
case types.ETReal:
670685
err := baseFunc.vecEvalReal(input, output)
671686
c.Assert(err, IsNil)
687+
// do not forget to call ResizeXXX/ReserveXXX
688+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
672689
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
673690
f64s := output.Float64s()
674691
for row := it.Begin(); row != it.End(); row = it.Next() {
675692
val, isNull, err := baseFunc.evalReal(row)
676693
c.Assert(err, IsNil)
677-
c.Assert(isNull, Equals, output.IsNull(i))
694+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
678695
if !isNull {
679696
c.Assert(val, Equals, f64s[i], commentf(i))
680697
}
@@ -683,12 +700,14 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
683700
case types.ETDecimal:
684701
err := baseFunc.vecEvalDecimal(input, output)
685702
c.Assert(err, IsNil)
703+
// do not forget to call ResizeXXX/ReserveXXX
704+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
686705
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
687706
d64s := output.Decimals()
688707
for row := it.Begin(); row != it.End(); row = it.Next() {
689708
val, isNull, err := baseFunc.evalDecimal(row)
690709
c.Assert(err, IsNil)
691-
c.Assert(isNull, Equals, output.IsNull(i))
710+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
692711
if !isNull {
693712
c.Assert(*val, Equals, d64s[i], commentf(i))
694713
}
@@ -697,12 +716,14 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
697716
case types.ETDatetime, types.ETTimestamp:
698717
err := baseFunc.vecEvalTime(input, output)
699718
c.Assert(err, IsNil)
719+
// do not forget to call ResizeXXX/ReserveXXX
720+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
700721
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
701722
t64s := output.Times()
702723
for row := it.Begin(); row != it.End(); row = it.Next() {
703724
val, isNull, err := baseFunc.evalTime(row)
704725
c.Assert(err, IsNil)
705-
c.Assert(isNull, Equals, output.IsNull(i))
726+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
706727
if !isNull {
707728
c.Assert(val, Equals, t64s[i], commentf(i))
708729
}
@@ -711,12 +732,14 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
711732
case types.ETDuration:
712733
err := baseFunc.vecEvalDuration(input, output)
713734
c.Assert(err, IsNil)
735+
// do not forget to call ResizeXXX/ReserveXXX
736+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
714737
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
715738
d64s := output.GoDurations()
716739
for row := it.Begin(); row != it.End(); row = it.Next() {
717740
val, isNull, err := baseFunc.evalDuration(row)
718741
c.Assert(err, IsNil)
719-
c.Assert(isNull, Equals, output.IsNull(i))
742+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
720743
if !isNull {
721744
c.Assert(val.Duration, Equals, d64s[i], commentf(i))
722745
}
@@ -725,11 +748,13 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
725748
case types.ETJson:
726749
err := baseFunc.vecEvalJSON(input, output)
727750
c.Assert(err, IsNil)
751+
// do not forget to call ResizeXXX/ReserveXXX
752+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
728753
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
729754
for row := it.Begin(); row != it.End(); row = it.Next() {
730755
val, isNull, err := baseFunc.evalJSON(row)
731756
c.Assert(err, IsNil)
732-
c.Assert(isNull, Equals, output.IsNull(i))
757+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
733758
if !isNull {
734759
var cmp int
735760
cmp = json.CompareBinary(val, output.GetJSON(i))
@@ -740,11 +765,13 @@ func testVectorizedBuiltinFunc(c *C, vecExprCases vecExprBenchCases) {
740765
case types.ETString:
741766
err := baseFunc.vecEvalString(input, output)
742767
c.Assert(err, IsNil)
768+
// do not forget to call ResizeXXX/ReserveXXX
769+
c.Assert(getColumnLen(output, testCase.retEvalType), Equals, input.NumRows())
743770
vecWarnCnt = ctx.GetSessionVars().StmtCtx.WarningCount()
744771
for row := it.Begin(); row != it.End(); row = it.Next() {
745772
val, isNull, err := baseFunc.evalString(row)
746773
c.Assert(err, IsNil)
747-
c.Assert(isNull, Equals, output.IsNull(i))
774+
c.Assert(isNull, Equals, output.IsNull(i), commentf(i))
748775
if !isNull {
749776
c.Assert(val, Equals, output.GetString(i), commentf(i))
750777
}

expression/builtin.go

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// limitations under the License.
1717

1818
//go:generate go run generator/control_vec.go
19+
//go:generate go run generator/time_vec.go
1920

2021
package expression
2122

expression/builtin_cast_vec.go

+29-2
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,38 @@ func (b *builtinCastRealAsDurationSig) vecEvalDuration(input *chunk.Chunk, resul
362362
}
363363

364364
func (b *builtinCastTimeAsDurationSig) vectorized() bool {
365-
return false
365+
return true
366366
}
367367

368368
func (b *builtinCastTimeAsDurationSig) vecEvalDuration(input *chunk.Chunk, result *chunk.Column) error {
369-
return errors.Errorf("not implemented")
369+
n := input.NumRows()
370+
arg0, err := b.bufAllocator.get(types.ETDatetime, n)
371+
if err != nil {
372+
return err
373+
}
374+
defer b.bufAllocator.put(arg0)
375+
if err := b.args[0].VecEvalTime(b.ctx, input, arg0); err != nil {
376+
return err
377+
}
378+
arg0s := arg0.Times()
379+
result.ResizeGoDuration(n, false)
380+
result.MergeNulls(arg0)
381+
ds := result.GoDurations()
382+
for i, t := range arg0s {
383+
if result.IsNull(i) {
384+
continue
385+
}
386+
d, err := t.ConvertToDuration()
387+
if err != nil {
388+
return err
389+
}
390+
d, err = d.RoundFrac(int8(b.tp.Decimal))
391+
if err != nil {
392+
return err
393+
}
394+
ds[i] = d.Duration
395+
}
396+
return nil
370397
}
371398

372399
func (b *builtinCastDurationAsDurationSig) vectorized() bool {

expression/builtin_cast_vec_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,29 @@ var vecBuiltinCastCases = map[string][]vecExprBenchCase{
2828
{retEvalType: types.ETDuration, childrenTypes: []types.EvalType{types.ETInt}, geners: []dataGenerator{new(randDurInt)}},
2929
{retEvalType: types.ETReal, childrenTypes: []types.EvalType{types.ETReal}},
3030
{retEvalType: types.ETReal, childrenTypes: []types.EvalType{types.ETDecimal}},
31+
{retEvalType: types.ETDuration, childrenTypes: []types.EvalType{types.ETDatetime},
32+
geners: []dataGenerator{&dateTimeGenerWithFsp{
33+
defaultGener: defaultGener{nullRation: 0.2, eType: types.ETDatetime},
34+
fsp: 1,
35+
}},
36+
},
3137
},
3238
}
3339

40+
type dateTimeGenerWithFsp struct {
41+
defaultGener
42+
fsp int8
43+
}
44+
45+
func (g *dateTimeGenerWithFsp) gen() interface{} {
46+
result := g.defaultGener.gen()
47+
if t, ok := result.(types.Time); ok {
48+
t.Fsp = g.fsp
49+
return t
50+
}
51+
return result
52+
}
53+
3454
func (s *testEvaluatorSuite) TestVectorizedBuiltinCastEvalOneVec(c *C) {
3555
testVectorizedEvalOneVec(c, vecBuiltinCastCases)
3656
}

0 commit comments

Comments
 (0)