From 2c5e6893b4021c3e0899851ac6b57ee6735272a3 Mon Sep 17 00:00:00 2001 From: dongyan Date: Wed, 26 Aug 2020 18:29:47 +0800 Subject: [PATCH 1/2] expression: bug fix for 'vec cast real as time' --- expression/builtin_cast_vec.go | 7 ++++++- 1 file changed, 6 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 From 061597dbdbd5c9f4d7f0e5920cd05aff37b738bd Mon Sep 17 00:00:00 2001 From: dongyan Date: Thu, 27 Aug 2020 10:58:23 +0800 Subject: [PATCH 2/2] add test cases for vec cast real as time --- expression/builtin_cast_vec_test.go | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) 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}