From 0127047db5f2479aee706df0a74b4bcce4a2a448 Mon Sep 17 00:00:00 2001 From: tsthght <781181214@qq.com> Date: Wed, 9 Oct 2019 11:58:46 +0800 Subject: [PATCH] expression: implement vectorized evaluation for 'builtinCastRealAsStringSig' (#12533) --- expression/builtin_cast_vec.go | 46 +++++++++++++++++++++++++++-- expression/builtin_cast_vec_test.go | 1 + 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index 3999295db3a0d..7551d8240efd7 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -156,11 +156,53 @@ func (b *builtinCastTimeAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk } func (b *builtinCastRealAsStringSig) vectorized() bool { - return false + return true } func (b *builtinCastRealAsStringSig) vecEvalString(input *chunk.Chunk, result *chunk.Column) error { - return errors.Errorf("not implemented") + n := input.NumRows() + buf, err := b.bufAllocator.get(types.ETReal, n) + if err != nil { + return err + } + defer b.bufAllocator.put(buf) + if err := b.args[0].VecEvalReal(b.ctx, input, buf); err != nil { + return err + } + + bits := 64 + if b.args[0].GetType().Tp == mysql.TypeFloat { + // b.args[0].EvalReal() casts the value from float32 to float64, for example: + // float32(208.867) is cast to float64(208.86700439) + // If we strconv.FormatFloat the value with 64bits, the result is incorrect! + bits = 32 + } + + var isNull bool + var res string + f64s := buf.Float64s() + result.ReserveString(n) + sc := b.ctx.GetSessionVars().StmtCtx + for i, v := range f64s { + if buf.IsNull(i) { + result.AppendNull() + continue + } + res, err = types.ProduceStrWithSpecifiedTp(strconv.FormatFloat(v, 'f', -1, bits), b.tp, sc, false) + if err != nil { + return err + } + res, isNull, err = padZeroForBinaryType(res, b.tp, b.ctx) + if err != nil { + return err + } + if isNull { + result.AppendNull() + continue + } + result.AppendString(res) + } + return nil } func (b *builtinCastDecimalAsStringSig) vectorized() bool { diff --git a/expression/builtin_cast_vec_test.go b/expression/builtin_cast_vec_test.go index 2ea368f913a32..3b604290f8392 100644 --- a/expression/builtin_cast_vec_test.go +++ b/expression/builtin_cast_vec_test.go @@ -37,6 +37,7 @@ var vecBuiltinCastCases = map[string][]vecExprBenchCase{ }, {retEvalType: types.ETString, childrenTypes: []types.EvalType{types.ETInt}}, {retEvalType: types.ETDecimal, childrenTypes: []types.EvalType{types.ETDatetime}}, + {retEvalType: types.ETString, childrenTypes: []types.EvalType{types.ETReal}}, {retEvalType: types.ETString, childrenTypes: []types.EvalType{types.ETJson}}, {retEvalType: types.ETString, childrenTypes: []types.EvalType{types.ETDecimal}}, },