From 7a916f0111ea714fc37837ec7b2f62840bb6b54f Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 22:45:43 +0200 Subject: [PATCH] [release-17.0] json: Fix quoting JSON keys (#14066) (#14068) Signed-off-by: Dirkjan Bussink Signed-off-by: Florent Poinsard Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Florent Poinsard --- go/mysql/json/marshal.go | 6 ++-- go/mysql/json/marshal_test.go | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 go/mysql/json/marshal_test.go diff --git a/go/mysql/json/marshal.go b/go/mysql/json/marshal.go index e1ea916151d..8e63cddb171 100644 --- a/go/mysql/json/marshal.go +++ b/go/mysql/json/marshal.go @@ -42,9 +42,9 @@ func (v *Value) marshalSQLInternal(top bool, dst []byte) []byte { if i != 0 { dst = append(dst, ", "...) } - dst = append(dst, "_utf8mb4'"...) - dst = append(dst, vv.k...) - dst = append(dst, "', "...) + dst = append(dst, "_utf8mb4"...) + dst = append(dst, sqltypes.EncodeStringSQL(vv.k)...) + dst = append(dst, ", "...) dst = vv.v.marshalSQLInternal(false, dst) } dst = append(dst, ')') diff --git a/go/mysql/json/marshal_test.go b/go/mysql/json/marshal_test.go new file mode 100644 index 00000000000..9329c3cd49a --- /dev/null +++ b/go/mysql/json/marshal_test.go @@ -0,0 +1,57 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package json + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestMarshalSQLTo(t *testing.T) { + testcases := []struct { + input string + expected string + }{ + { + input: "null", + expected: "CAST(_utf8mb4'null' as JSON)", + }, + { + input: `{}`, + expected: `JSON_OBJECT()`, + }, + { + input: `{"a": 1}`, + expected: `JSON_OBJECT(_utf8mb4'a', 1)`, + }, + { + input: `{"key with ' in it": []}`, + expected: `JSON_OBJECT(_utf8mb4'key with \' in it', JSON_ARRAY())`, + }, + } + for _, tc := range testcases { + t.Run(tc.input, func(t *testing.T) { + var p Parser + + v, err := p.Parse(tc.input) + require.NoError(t, err) + buf := v.MarshalSQLTo(nil) + require.Equal(t, tc.expected, string(buf)) + }) + } +}