diff --git a/expression/bench_test.go b/expression/bench_test.go index ba6c64e32a432..4c1a5c11a4e02 100644 --- a/expression/bench_test.go +++ b/expression/bench_test.go @@ -661,7 +661,7 @@ func genVecExprBenchCase(ctx sessionctx.Context, funcName string, testCase vecEx panic(err) } - output = chunk.New([]*types.FieldType{eType2FieldType(testCase.retEvalType)}, 1024, 1024) + output = chunk.New([]*types.FieldType{eType2FieldType(expr.GetType().EvalType())}, 1024, 1024) return expr, fts, input, output } @@ -681,7 +681,7 @@ func testVectorizedEvalOneVec(c *C, vecExprCases vecExprBenchCases) { c.Assert(evalOneColumn(ctx, expr, it, output2, 0), IsNil, Commentf("func: %v, case: %+v", funcName, testCase)) c1, c2 := output.Column(0), output2.Column(0) - switch testCase.retEvalType { + switch expr.GetType().EvalType() { case types.ETInt: for i := 0; i < input.NumRows(); i++ { c.Assert(c1.IsNull(i), Equals, c2.IsNull(i), commentf(i)) diff --git a/expression/builtin_time_vec.go b/expression/builtin_time_vec.go index 9dcb5f30faaaf..19e714e8e3d04 100644 --- a/expression/builtin_time_vec.go +++ b/expression/builtin_time_vec.go @@ -176,11 +176,86 @@ func (b *builtinStringStringTimeDiffSig) vecEvalDuration(input *chunk.Chunk, res } func (b *builtinDayNameSig) vectorized() bool { - return false + return true +} + +func (b *builtinDayNameSig) vecEvalIndex(input *chunk.Chunk, apply func(i, res int), applyNull func(i int)) error { + n := input.NumRows() + buf, err := b.bufAllocator.get(types.ETDatetime, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf) + if err := b.args[0].VecEvalTime(b.ctx, input, buf); err != nil { + return err + } + + ds := buf.Times() + for i := 0; i < n; i++ { + if buf.IsNull(i) { + applyNull(i) + continue + } + if ds[i].InvalidZero() { + if err := handleInvalidTimeError(b.ctx, types.ErrIncorrectDatetimeValue.GenWithStackByArgs(ds[i].String())); err != nil { + return err + } + applyNull(i) + continue + } + // Monday is 0, ... Sunday = 6 in MySQL + // but in go, Sunday is 0, ... Saturday is 6 + // we will do a conversion. + res := (int(ds[i].Time.Weekday()) + 6) % 7 + apply(i, res) + } + return nil +} + +// evalString evals a builtinDayNameSig. +// See https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_dayname +func (b *builtinDayNameSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + result.ReserveString(n) + + return b.vecEvalIndex(input, + func(i, res int) { + result.AppendString(types.WeekdayNames[res]) + }, + func(i int) { + result.AppendNull() + }, + ) +} + +func (b *builtinDayNameSig) vecEvalReal(input *chunk.Chunk, result *chunk.Column) error { + n := input.NumRows() + result.ResizeFloat64(n, false) + f64s := result.Float64s() + + return b.vecEvalIndex(input, + func(i, res int) { + f64s[i] = float64(res) + }, + func(i int) { + result.SetNull(i, true) + }, + ) } func (b *builtinDayNameSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) error { - return errors.Errorf("not implemented") + n := input.NumRows() + result.ResizeInt64(n, false) + i64s := result.Int64s() + + return b.vecEvalIndex(input, + func(i, res int) { + i64s[i] = int64(res) + }, + func(i int) { + result.SetNull(i, true) + }, + ) } func (b *builtinWeekDaySig) vectorized() bool { diff --git a/expression/builtin_time_vec_test.go b/expression/builtin_time_vec_test.go index c346fbc3903fb..0a7def873677b 100644 --- a/expression/builtin_time_vec_test.go +++ b/expression/builtin_time_vec_test.go @@ -161,6 +161,11 @@ var vecBuiltinTimeCases = map[string][]vecExprBenchCase{ ast.DayOfMonth: { {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDatetime}}, }, + ast.DayName: { + {retEvalType: types.ETString, childrenTypes: []types.EvalType{types.ETDatetime}}, + {retEvalType: types.ETInt, childrenTypes: []types.EvalType{types.ETDatetime}}, + {retEvalType: types.ETReal, childrenTypes: []types.EvalType{types.ETDatetime}}, + }, ast.UTCDate: { {retEvalType: types.ETDatetime}, },