From 286047be6bbcb0f2ef70ea4b0ee51d17c587d30c Mon Sep 17 00:00:00 2001 From: tsthght <781181214@qq.com> Date: Fri, 18 Oct 2019 17:30:49 +0800 Subject: [PATCH] expression: implement vectorized evaluation for 'builtinCastStringAsJSONSig' (#12802) --- expression/bench_test.go | 10 ++++++++ expression/builtin_cast_vec.go | 38 +++++++++++++++++++++++++++-- expression/builtin_cast_vec_test.go | 1 + 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/expression/bench_test.go b/expression/bench_test.go index eb0fee0f6e..e68bb8c224 100644 --- a/expression/bench_test.go +++ b/expression/bench_test.go @@ -252,6 +252,16 @@ func (g *defaultGener) gen() interface{} { return nil } +type jsonStringGener struct{} + +func (g *jsonStringGener) gen() interface{} { + j := new(json.BinaryJSON) + if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, rand.Int()))); err != nil { + panic(err) + } + return j.String() +} + type rangeDurationGener struct { nullRation float64 } diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index ed14a1e6fb..90443dee72 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -513,11 +513,45 @@ func (b *builtinCastTimeAsRealSig) vecEvalReal(input *chunk.Chunk, result *chunk } func (b *builtinCastStringAsJSONSig) vectorized() bool { - return false + return true } func (b *builtinCastStringAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error { - return errors.Errorf("not implemented") + 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.ReserveJSON(n) + hasParse := mysql.HasParseToJSONFlag(b.tp.Flag) + if hasParse { + var res json.BinaryJSON + for i := 0; i < n; i++ { + if buf.IsNull(i) { + result.AppendNull() + continue + } + res, err = json.ParseBinaryFromString(buf.GetString(i)) + if err != nil { + return err + } + result.AppendJSON(res) + } + } else { + for i := 0; i < n; i++ { + if buf.IsNull(i) { + result.AppendNull() + continue + } + result.AppendJSON(json.CreateBinary(buf.GetString(i))) + } + } + return nil } func (b *builtinCastRealAsDecimalSig) vectorized() bool { diff --git a/expression/builtin_cast_vec_test.go b/expression/builtin_cast_vec_test.go index fce168c9fd..719937e990 100644 --- a/expression/builtin_cast_vec_test.go +++ b/expression/builtin_cast_vec_test.go @@ -52,6 +52,7 @@ var vecBuiltinCastCases = map[string][]vecExprBenchCase{ {retEvalType: types.ETJson, childrenTypes: []types.EvalType{types.ETReal}}, {retEvalType: types.ETJson, childrenTypes: []types.EvalType{types.ETDatetime}}, {retEvalType: types.ETJson, childrenTypes: []types.EvalType{types.ETJson}}, + {retEvalType: types.ETJson, childrenTypes: []types.EvalType{types.ETString}, geners: []dataGenerator{&jsonStringGener{}}}, {retEvalType: types.ETJson, childrenTypes: []types.EvalType{types.ETDecimal}}, }, }