From 844c114d10a050900a892f4a08ce8bad6a0e9fbb Mon Sep 17 00:00:00 2001 From: dy <34701401+dyzsr@users.noreply.github.com> Date: Sat, 29 Aug 2020 22:51:31 +0800 Subject: [PATCH] expression: bug fix for vectorized casting real as time (#19485) --- expression/builtin_cast_vec.go | 7 ++++- expression/builtin_cast_vec_test.go | 41 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index 6bbe7d670ef13..c4bf75657c12a 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -522,7 +522,12 @@ func (b *builtinCastRealAsTimeSig) vecEvalTime(input *chunk.Chunk, result *chunk if buf.IsNull(i) { continue } - tm, err := types.ParseTime(stmt, strconv.FormatFloat(f64s[i], 'f', -1, 64), b.tp.Tp, fsp) + fv := strconv.FormatFloat(f64s[i], 'f', -1, 64) + if fv == "0" { + times[i] = types.ZeroTime + continue + } + tm, err := types.ParseTime(stmt, fv, b.tp.Tp, fsp) if err != nil { if err = handleInvalidTimeError(b.ctx, err); err != nil { return err diff --git a/expression/builtin_cast_vec_test.go b/expression/builtin_cast_vec_test.go index 321b9359d6525..1b4fcd3ff4659 100644 --- a/expression/builtin_cast_vec_test.go +++ b/expression/builtin_cast_vec_test.go @@ -155,6 +155,47 @@ func (s *testEvaluatorSuite) TestVectorizedBuiltinCastFunc(c *C) { testVectorizedBuiltinFunc(c, vecBuiltinCastCases) } +func (s *testEvaluatorSuite) TestVectorizedCastRealAsTime(c *C) { + col := &Column{RetType: types.NewFieldType(mysql.TypeDouble), Index: 0} + baseFunc, err := newBaseBuiltinFunc(mock.NewContext(), "", []Expression{col}) + if err != nil { + panic(err) + } + cast := &builtinCastRealAsTimeSig{baseFunc} + + inputs := []*chunk.Chunk{ + genCastRealAsTime(), + } + + for _, input := range inputs { + result := chunk.NewColumn(types.NewFieldType(mysql.TypeDatetime), input.NumRows()) + c.Assert(cast.vecEvalTime(input, result), IsNil) + for i := 0; i < input.NumRows(); i++ { + res, isNull, err := cast.evalTime(input.GetRow(i)) + c.Assert(err, IsNil) + if isNull { + c.Assert(result.IsNull(i), IsTrue) + continue + } + c.Assert(result.IsNull(i), IsFalse) + c.Assert(result.GetTime(i).Compare(res), Equals, 0) + } + } +} + +func genCastRealAsTime() *chunk.Chunk { + input := chunk.NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeDouble)}, 10) + gen := newDefaultRandGen() + for i := 0; i < 10; i++ { + if i < 5 { + input.AppendFloat64(0, 0) + } else { + input.AppendFloat64(0, gen.Float64()*100000) + } + } + return input +} + // for issue https://github.com/pingcap/tidb/issues/16825 func (s *testEvaluatorSuite) TestVectorizedCastStringAsDecimalWithUnsignedFlagInUnion(c *C) { col := &Column{RetType: types.NewFieldType(mysql.TypeString), Index: 0}