From fb07e86bb8d559ff6daedd6c19d44559df167726 Mon Sep 17 00:00:00 2001 From: Chengpeng Yan <41809508+Reminiscent@users.noreply.github.com> Date: Wed, 25 Sep 2019 19:08:47 +0800 Subject: [PATCH] expression: implement vectorized evaluation for `builtinTimestamp1ArgSig` (#12339) --- expression/bench_test.go | 37 +++++++++++++++++++++++++ expression/builtin_time_vec.go | 43 +++++++++++++++++++++++++++++ expression/builtin_time_vec_test.go | 6 ++++ 3 files changed, 86 insertions(+) diff --git a/expression/bench_test.go b/expression/bench_test.go index dca165e0e5..290b7bbb6e 100644 --- a/expression/bench_test.go +++ b/expression/bench_test.go @@ -311,6 +311,43 @@ func (g *randLenStrGener) gen() interface{} { return string(buf) } +// dataTimeStrGener is used to generate strings which are dataTime format +type dataTimeStrGener struct{} + +func (g *dataTimeStrGener) gen() interface{} { + year := rand.Intn(2200) + month := rand.Intn(10) + 1 + day := rand.Intn(20) + 1 + hour := rand.Intn(12) + minute := rand.Intn(60) + second := rand.Intn(60) + + return fmt.Sprintf("%d-%d-%d %d:%d:%d", + year, month, day, hour, minute, second) +} + +// timeStrGener is used to generate strings which are time format +type timeStrGener struct{} + +func (g *timeStrGener) gen() interface{} { + year := rand.Intn(2200) + month := rand.Intn(10) + 1 + day := rand.Intn(20) + 1 + + return fmt.Sprintf("%d-%d-%d", year, month, day) +} + +// dataStrGener is used to generate strings which are data format +type dataStrGener struct{} + +func (g *dataStrGener) gen() interface{} { + hour := rand.Intn(12) + minute := rand.Intn(60) + second := rand.Intn(60) + + return fmt.Sprintf("%d:%d:%d", hour, minute, second) +} + type randDurInt struct{} func (g *randDurInt) gen() interface{} { diff --git a/expression/builtin_time_vec.go b/expression/builtin_time_vec.go index 297514ddba..3388f2352f 100644 --- a/expression/builtin_time_vec.go +++ b/expression/builtin_time_vec.go @@ -122,3 +122,46 @@ func (b *builtinDateSig) vecEvalTime(input *chunk.Chunk, result *chunk.Column) e func (b *builtinDateSig) vectorized() bool { return true } + +func (b *builtinTimestamp1ArgSig) vecEvalTime(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + buf, err := b.bufAllocator.get(types.ETString, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf) + if err := b.args[0].VecEvalString(b.ctx, input, buf); err != nil { + return err + } + + result.ResizeTime(n, false) + result.MergeNulls(buf) + times := result.Times() + sc := b.ctx.GetSessionVars().StmtCtx + var tm types.Time + for i := 0; i < n; i++ { + if result.IsNull(i) { + continue + } + s := buf.GetString(i) + + if b.isFloat { + tm, err = types.ParseTimeFromFloatString(sc, s, mysql.TypeDatetime, types.GetFsp(s)) + } else { + tm, err = types.ParseTime(sc, s, mysql.TypeDatetime, types.GetFsp(s)) + } + if err != nil { + if err = handleInvalidTimeError(b.ctx, err); err != nil { + return err + } + result.SetNull(i, true) + continue + } + times[i] = tm + } + return nil +} + +func (b *builtinTimestamp1ArgSig) vectorized() bool { + return true +} diff --git a/expression/builtin_time_vec_test.go b/expression/builtin_time_vec_test.go index fc58f65173..85bd8f34b8 100644 --- a/expression/builtin_time_vec_test.go +++ b/expression/builtin_time_vec_test.go @@ -34,6 +34,12 @@ var vecBuiltinTimeCases = map[string][]vecExprBenchCase{ ast.Date: { {retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETDatetime}}, }, + ast.Timestamp: { + {retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETString}, geners: []dataGenerator{new(dataTimeStrGener)}}, + {retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETString}, geners: []dataGenerator{new(timeStrGener)}}, + {retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETString}, geners: []dataGenerator{new(dataStrGener)}}, + {retEvalType: types.ETDatetime, childrenTypes: []types.EvalType{types.ETString}}, + }, } func (s *testEvaluatorSuite) TestVectorizedBuiltinTimeEvalOneVec(c *C) {