diff --git a/.github/workflows/integration-test-dumpling-common.yml b/.github/workflows/integration-test-dumpling-common.yml index ab2d066f26acd..f73e07341ec5e 100644 --- a/.github/workflows/integration-test-dumpling-common.yml +++ b/.github/workflows/integration-test-dumpling-common.yml @@ -28,6 +28,13 @@ jobs: steps: - name: 'checkout repository' uses: actions/checkout@v3 + with: + # FIXME: the version of dumpling is getting from git + # if it doesn't contain a meaningful git history, + # the release version will be empty and the program will panic. + # + # See the `DUMPLING_LDFLAGS` in `Makefile.common` for more information + fetch-depth: 0 - name: 'set up golang' uses: actions/setup-go@v3 with: diff --git a/build/nogo_config.json b/build/nogo_config.json index 4a7de9dac0cde..f5dfccad4195c 100644 --- a/build/nogo_config.json +++ b/build/nogo_config.json @@ -200,8 +200,8 @@ "br/pkg/lightning/mydump/": "br/pkg/lightning/mydump/", "br/pkg/lightning/restore/opts": "br/pkg/lightning/restore/opts", "executor/aggregate.go": "executor/aggregate.go", - "types/json/binary_functions.go": "types/json/binary_functions.go", - "types/json/binary_test.go": "types/json/binary_test.go", + "types/json_binary_functions.go": "types/json_binary_functions.go", + "types/json_binary_test.go": "types/json_binary_test.go", "ddl/backfilling.go": "ddl/backfilling.go", "ddl/column.go": "ddl/column.go", "ddl/index.go": "ddl/index.go", @@ -355,8 +355,8 @@ "br/pkg/lightning/mydump/": "br/pkg/lightning/mydump/", "br/pkg/lightning/restore/opts": "br/pkg/lightning/restore/opts", "executor/aggregate.go": "executor/aggregate.go", - "types/json/binary_functions.go": "types/json/binary_functions.go", - "types/json/binary_test.go": "types/json/binary_test.go", + "types/json_binary_functions.go": "types/json_binary_functions.go", + "types/json_binary_test.go": "types/json_binary_test.go", "ddl/backfilling.go": "ddl/backfilling.go", "ddl/column.go": "ddl/column.go", "ddl/index.go": "ddl/index.go", @@ -718,8 +718,8 @@ "br/pkg/lightning/mydump/": "br/pkg/lightning/mydump/", "br/pkg/lightning/restore/opts": "br/pkg/lightning/restore/opts", "executor/aggregate.go": "executor/aggregate.go", - "types/json/binary_functions.go": "types/json/binary_functions.go", - "types/json/binary_test.go": "types/json/binary_test.go", + "types/json_binary_functions.go": "types/json_binary_functions.go", + "types/json_binary_test.go": "types/json_binary_test.go", "ddl/": "enable to ddl", "expression/builtin_cast.go": "enable expression/builtin_cast.go", "planner/core/plan.go": "planner/core/plan.go", diff --git a/config/BUILD.bazel b/config/BUILD.bazel index e8ef74e64045a..e06843bec3df2 100644 --- a/config/BUILD.bazel +++ b/config/BUILD.bazel @@ -12,7 +12,6 @@ go_library( deps = [ "//br/pkg/streamhelper/config", "//parser/terror", - "//types/json", "//util/logutil", "//util/tikvutil", "//util/versioninfo", diff --git a/config/config.go b/config/config.go index 9586ec41d6e89..018f4427d5699 100644 --- a/config/config.go +++ b/config/config.go @@ -34,7 +34,6 @@ import ( zaplog "github.com/pingcap/log" logbackupconf "github.com/pingcap/tidb/br/pkg/streamhelper/config" "github.com/pingcap/tidb/parser/terror" - typejson "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/tikvutil" "github.com/pingcap/tidb/util/versioninfo" @@ -1350,12 +1349,6 @@ var hideConfig = []string{ "performance.index-usage-sync-lease", } -// jsonifyPath converts the item to json path, so it can be extracted. -func jsonifyPath(str string) string { - s := strings.Split(str, ".") - return fmt.Sprintf("$.\"%s\"", strings.Join(s, "\".\"")) -} - // GetJSONConfig returns the config as JSON with hidden items removed // It replaces the earlier HideConfig() which used strings.Split() in // an way that didn't work for similarly named items (like enable). @@ -1364,46 +1357,45 @@ func GetJSONConfig() (string, error) { if err != nil { return "", err } - jsonValue, err := typejson.ParseBinaryFromString(string(j)) + + jsonValue := make(map[string]interface{}) + err = json.Unmarshal(j, &jsonValue) if err != nil { return "", err } - // Approximately length of removed items + hidden items. - pathExprs := make([]typejson.PathExpression, 0, len(removedConfig)+len(hideConfig)) - var pathExpr typejson.PathExpression - // Patch out removed items. + removedPaths := make([]string, 0, len(removedConfig)+len(hideConfig)) for removedItem := range removedConfig { - s := jsonifyPath(removedItem) - pathExpr, err = typejson.ParseJSONPathExpr(s) - if err != nil { - // Should not be reachable, but not worth bailing for. - // It just means we can't patch out this line. - continue - } - pathExprs = append(pathExprs, pathExpr) - } - // Patch out hidden items - for _, hiddenItem := range hideConfig { - s := jsonifyPath(hiddenItem) - pathExpr, err = typejson.ParseJSONPathExpr(s) - if err != nil { - // Should not be reachable, but not worth bailing for. - // It just means we can't patch out this line. - continue - } - pathExprs = append(pathExprs, pathExpr) + removedPaths = append(removedPaths, removedItem) } - newJSONValue, err := jsonValue.Remove(pathExprs) - if err != nil { - return "", err + removedPaths = append(removedPaths, hideConfig...) + + for _, path := range removedPaths { + s := strings.Split(path, ".") + curValue := jsonValue + for i, key := range s { + if i == len(s)-1 { + delete(curValue, key) + } + + if curValue[key] != nil { + mapValue, ok := curValue[key].(map[string]interface{}) + if !ok { + break + } + + curValue = mapValue + } else { + break + } + } } - // Convert back to GoJSON so it can be pretty formatted. - // This is expected for compatibility with previous versions. - buf, err := newJSONValue.MarshalJSON() + + buf, err := json.Marshal(jsonValue) if err != nil { return "", err } + var resBuf bytes.Buffer if err = json.Indent(&resBuf, buf, "", "\t"); err != nil { return "", err diff --git a/executor/BUILD.bazel b/executor/BUILD.bazel index 8766552a3f984..fac40d3fe486f 100644 --- a/executor/BUILD.bazel +++ b/executor/BUILD.bazel @@ -148,7 +148,6 @@ go_library( "//telemetry", "//tidb-binlog/node", "//types", - "//types/json", "//util", "//util/admin", "//util/bitmap", @@ -385,7 +384,6 @@ go_test( "//testkit/testsetup", "//testkit/testutil", "//types", - "//types/json", "//util", "//util/benchdaily", "//util/chunk", diff --git a/executor/aggfuncs/BUILD.bazel b/executor/aggfuncs/BUILD.bazel index 1bb3c1133eec9..07d6a56159c7b 100644 --- a/executor/aggfuncs/BUILD.bazel +++ b/executor/aggfuncs/BUILD.bazel @@ -41,7 +41,6 @@ go_library( "//sessionctx", "//sessionctx/variable", "//types", - "//types/json", "//util/chunk", "//util/codec", "//util/collate", @@ -102,7 +101,6 @@ go_test( "//testkit", "//testkit/testsetup", "//types", - "//types/json", "//util/chunk", "//util/codec", "//util/collate", diff --git a/executor/aggfuncs/aggfunc_test.go b/executor/aggfuncs/aggfunc_test.go index 9a273cd47a0fb..1d1a98a2d2d48 100644 --- a/executor/aggfuncs/aggfunc_test.go +++ b/executor/aggfuncs/aggfunc_test.go @@ -31,7 +31,6 @@ import ( "github.com/pingcap/tidb/planner/util" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" @@ -493,7 +492,7 @@ func getDataGenFunc(ft *types.FieldType) func(i int) types.Datum { case mysql.TypeDuration: return func(i int) types.Datum { return types.NewDurationDatum(types.Duration{Duration: time.Duration(i)}) } case mysql.TypeJSON: - return func(i int) types.Datum { return types.NewDatum(json.CreateBinary(int64(i))) } + return func(i int) types.Datum { return types.NewDatum(types.CreateBinaryJSON(int64(i))) } case mysql.TypeEnum: elems := []string{"e", "d", "c", "b", "a"} return func(i int) types.Datum { diff --git a/executor/aggfuncs/func_count_distinct.go b/executor/aggfuncs/func_count_distinct.go index f9e1c66db4bbb..b90310c72ee30 100644 --- a/executor/aggfuncs/func_count_distinct.go +++ b/executor/aggfuncs/func_count_distinct.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" @@ -398,7 +397,7 @@ func evalAndEncode( } encodedBytes = appendDuration(encodedBytes, buf, val) case types.ETJson: - var val json.BinaryJSON + var val types.BinaryJSON val, isNull, err = arg.EvalJSON(sctx, row) if err != nil || isNull { break @@ -466,7 +465,7 @@ func appendDuration(encodedBytes, buf []byte, val types.Duration) []byte { return encodedBytes } -func appendJSON(encodedBytes, _ []byte, val json.BinaryJSON) []byte { +func appendJSON(encodedBytes, _ []byte, val types.BinaryJSON) []byte { encodedBytes = append(encodedBytes, val.TypeCode) encodedBytes = append(encodedBytes, val.Value...) return encodedBytes diff --git a/executor/aggfuncs/func_first_row.go b/executor/aggfuncs/func_first_row.go index ffe3d1df9520e..312dc9ebcf021 100644 --- a/executor/aggfuncs/func_first_row.go +++ b/executor/aggfuncs/func_first_row.go @@ -21,7 +21,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/stringutil" ) @@ -103,7 +102,7 @@ type partialResult4FirstRowDuration struct { type partialResult4FirstRowJSON struct { basePartialResult4FirstRow - val json.BinaryJSON + val types.BinaryJSON } type partialResult4FirstRowEnum struct { diff --git a/executor/aggfuncs/func_first_row_test.go b/executor/aggfuncs/func_first_row_test.go index f12fbd72dc93a..0137a7b1a0ff7 100644 --- a/executor/aggfuncs/func_first_row_test.go +++ b/executor/aggfuncs/func_first_row_test.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" ) @@ -42,7 +41,7 @@ func TestMergePartialResult4FirstRow(t *testing.T) { buildAggTester(ast.AggFuncFirstRow, mysql.TypeString, 5, "0", "2", "0"), buildAggTester(ast.AggFuncFirstRow, mysql.TypeDate, 5, types.TimeFromDays(365), types.TimeFromDays(367), types.TimeFromDays(365)), buildAggTester(ast.AggFuncFirstRow, mysql.TypeDuration, 5, types.Duration{Duration: time.Duration(0)}, types.Duration{Duration: time.Duration(2)}, types.Duration{Duration: time.Duration(0)}), - buildAggTester(ast.AggFuncFirstRow, mysql.TypeJSON, 5, json.CreateBinary(int64(0)), json.CreateBinary(int64(2)), json.CreateBinary(int64(0))), + buildAggTester(ast.AggFuncFirstRow, mysql.TypeJSON, 5, types.CreateBinaryJSON(int64(0)), types.CreateBinaryJSON(int64(2)), types.CreateBinaryJSON(int64(0))), buildAggTester(ast.AggFuncFirstRow, mysql.TypeEnum, 5, enumE, enumC, enumE), buildAggTester(ast.AggFuncFirstRow, mysql.TypeSet, 5, setE, setED, setE), } diff --git a/executor/aggfuncs/func_json_arrayagg.go b/executor/aggfuncs/func_json_arrayagg.go index 7c747b84932cb..7b74cb536b511 100644 --- a/executor/aggfuncs/func_json_arrayagg.go +++ b/executor/aggfuncs/func_json_arrayagg.go @@ -19,7 +19,7 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/types/json" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" ) @@ -54,7 +54,7 @@ func (e *jsonArrayagg) AppendFinalResult2Chunk(sctx sessionctx.Context, pr Parti return nil } - chk.AppendJSON(e.ordinal, json.CreateBinary(p.entries)) + chk.AppendJSON(e.ordinal, types.CreateBinaryJSON(p.entries)) return nil } @@ -72,11 +72,11 @@ func (e *jsonArrayagg) UpdatePartialResult(sctx sessionctx.Context, rowsInGroup } switch x := realItem.(type) { - case nil, bool, int64, uint64, float64, string, json.BinaryJSON, json.Opaque: + case nil, bool, int64, uint64, float64, string, types.BinaryJSON, types.Opaque: p.entries = append(p.entries, realItem) memDelta += getValMemDelta(realItem) default: - return 0, json.ErrUnsupportedSecondArgumentType.GenWithStackByArgs(x) + return 0, types.ErrUnsupportedSecondArgumentType.GenWithStackByArgs(x) } } return memDelta, nil diff --git a/executor/aggfuncs/func_json_arrayagg_test.go b/executor/aggfuncs/func_json_arrayagg_test.go index d737402825dfd..2f70dee11f00c 100644 --- a/executor/aggfuncs/func_json_arrayagg_test.go +++ b/executor/aggfuncs/func_json_arrayagg_test.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" ) @@ -56,7 +55,7 @@ func TestMergePartialResult4JsonArrayagg(t *testing.T) { entries3 = append(entries3, entries1...) entries3 = append(entries3, entries2...) - tests = append(tests, buildAggTester(ast.AggFuncJsonArrayagg, argType, numRows, json.CreateBinary(entries1), json.CreateBinary(entries2), json.CreateBinary(entries3))) + tests = append(tests, buildAggTester(ast.AggFuncJsonArrayagg, argType, numRows, types.CreateBinaryJSON(entries1), types.CreateBinaryJSON(entries2), types.CreateBinaryJSON(entries3))) } for _, test := range tests { @@ -83,7 +82,7 @@ func TestJsonArrayagg(t *testing.T) { // to adapt the `genSrcChk` Chunk format entries = append(entries, nil) - tests = append(tests, buildAggTester(ast.AggFuncJsonArrayagg, argType, numRows, nil, json.CreateBinary(entries))) + tests = append(tests, buildAggTester(ast.AggFuncJsonArrayagg, argType, numRows, nil, types.CreateBinaryJSON(entries))) } for _, test := range tests { @@ -114,7 +113,7 @@ func jsonArrayaggMemDeltaGens(srcChk *chunk.Chunk, dataType *types.FieldType) (m memDelta += int64(len(val)) case mysql.TypeJSON: val := row.GetJSON(0) - // +1 for the memory usage of the TypeCode of json + // +1 for the memory usage of the JSONTypeCode of json memDelta += int64(len(val.Value) + 1) case mysql.TypeDuration: val := row.GetDuration(0, dataType.GetDecimal()) diff --git a/executor/aggfuncs/func_json_objectagg.go b/executor/aggfuncs/func_json_objectagg.go index 38f815d5724aa..73914eefc2304 100644 --- a/executor/aggfuncs/func_json_objectagg.go +++ b/executor/aggfuncs/func_json_objectagg.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/hack" ) @@ -62,7 +61,7 @@ func (e *jsonObjectAgg) AppendFinalResult2Chunk(sctx sessionctx.Context, pr Part return nil } - chk.AppendJSON(e.ordinal, json.CreateBinary(p.entries)) + chk.AppendJSON(e.ordinal, types.CreateBinaryJSON(p.entries)) return nil } @@ -76,11 +75,11 @@ func (e *jsonObjectAgg) UpdatePartialResult(sctx sessionctx.Context, rowsInGroup key = strings.Clone(key) if keyIsNull { - return 0, json.ErrJSONDocumentNULLKey + return 0, types.ErrJSONDocumentNULLKey } if e.args[0].GetType().GetCharset() == charset.CharsetBin { - return 0, json.ErrInvalidJSONCharset.GenWithStackByArgs(e.args[0].GetType().GetCharset()) + return 0, types.ErrInvalidJSONCharset.GenWithStackByArgs(e.args[0].GetType().GetCharset()) } value, err := e.args[1].Eval(row) @@ -94,7 +93,7 @@ func (e *jsonObjectAgg) UpdatePartialResult(sctx sessionctx.Context, rowsInGroup } switch x := realVal.(type) { - case nil, bool, int64, uint64, float64, string, json.BinaryJSON, json.Opaque: + case nil, bool, int64, uint64, float64, string, types.BinaryJSON, types.Opaque: if _, ok := p.entries[key]; !ok { memDelta += int64(len(key)) + getValMemDelta(realVal) if len(p.entries)+1 > (1< 0 || !e.isMax && cmp < 0 { oldMem := len(p.val.Value) newMem := len(input.Value) @@ -1446,7 +1445,7 @@ func (e *maxMin4JSON) MergePartialResult(sctx sessionctx.Context, src, dst Parti *p2 = *p1 return 0, nil } - cmp := json.CompareBinary(p1.val, p2.val) + cmp := types.CompareBinaryJSON(p1.val, p2.val) if e.isMax && cmp > 0 || !e.isMax && cmp < 0 { p2.val = p1.val p2.isNull = false diff --git a/executor/aggfuncs/func_max_min_test.go b/executor/aggfuncs/func_max_min_test.go index 0e9256b67b3a8..2505b186fe61b 100644 --- a/executor/aggfuncs/func_max_min_test.go +++ b/executor/aggfuncs/func_max_min_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/stretchr/testify/require" ) @@ -114,7 +113,7 @@ func TestMergePartialResult4MaxMin(t *testing.T) { buildAggTester(ast.AggFuncMax, mysql.TypeString, 5, "4", "4", "4"), buildAggTester(ast.AggFuncMax, mysql.TypeDate, 5, types.TimeFromDays(369), types.TimeFromDays(369), types.TimeFromDays(369)), buildAggTester(ast.AggFuncMax, mysql.TypeDuration, 5, types.Duration{Duration: time.Duration(4)}, types.Duration{Duration: time.Duration(4)}, types.Duration{Duration: time.Duration(4)}), - buildAggTester(ast.AggFuncMax, mysql.TypeJSON, 5, json.CreateBinary(int64(4)), json.CreateBinary(int64(4)), json.CreateBinary(int64(4))), + buildAggTester(ast.AggFuncMax, mysql.TypeJSON, 5, types.CreateBinaryJSON(int64(4)), types.CreateBinaryJSON(int64(4)), types.CreateBinaryJSON(int64(4))), buildAggTester(ast.AggFuncMax, mysql.TypeEnum, 5, enumE, enumC, enumE), buildAggTester(ast.AggFuncMax, mysql.TypeSet, 5, setED, setED, setED), @@ -126,7 +125,7 @@ func TestMergePartialResult4MaxMin(t *testing.T) { buildAggTester(ast.AggFuncMin, mysql.TypeString, 5, "0", "2", "0"), buildAggTester(ast.AggFuncMin, mysql.TypeDate, 5, types.TimeFromDays(365), types.TimeFromDays(367), types.TimeFromDays(365)), buildAggTester(ast.AggFuncMin, mysql.TypeDuration, 5, types.Duration{Duration: time.Duration(0)}, types.Duration{Duration: time.Duration(2)}, types.Duration{Duration: time.Duration(0)}), - buildAggTester(ast.AggFuncMin, mysql.TypeJSON, 5, json.CreateBinary(int64(0)), json.CreateBinary(int64(2)), json.CreateBinary(int64(0))), + buildAggTester(ast.AggFuncMin, mysql.TypeJSON, 5, types.CreateBinaryJSON(int64(0)), types.CreateBinaryJSON(int64(2)), types.CreateBinaryJSON(int64(0))), buildAggTester(ast.AggFuncMin, mysql.TypeEnum, 5, enumA, enumA, enumA), buildAggTester(ast.AggFuncMin, mysql.TypeSet, 5, setC, setC, setC), } @@ -150,7 +149,7 @@ func TestMaxMin(t *testing.T) { buildAggTester(ast.AggFuncMax, mysql.TypeString, 5, nil, "4", "4"), buildAggTester(ast.AggFuncMax, mysql.TypeDate, 5, nil, types.TimeFromDays(369)), buildAggTester(ast.AggFuncMax, mysql.TypeDuration, 5, nil, types.Duration{Duration: time.Duration(4)}), - buildAggTester(ast.AggFuncMax, mysql.TypeJSON, 5, nil, json.CreateBinary(int64(4))), + buildAggTester(ast.AggFuncMax, mysql.TypeJSON, 5, nil, types.CreateBinaryJSON(int64(4))), buildAggTester(ast.AggFuncMin, mysql.TypeLonglong, 5, nil, 0), buildAggTesterWithFieldType(ast.AggFuncMin, unsignedType, 5, nil, 0), @@ -160,7 +159,7 @@ func TestMaxMin(t *testing.T) { buildAggTester(ast.AggFuncMin, mysql.TypeString, 5, nil, "0"), buildAggTester(ast.AggFuncMin, mysql.TypeDate, 5, nil, types.TimeFromDays(365)), buildAggTester(ast.AggFuncMin, mysql.TypeDuration, 5, nil, types.Duration{Duration: time.Duration(0)}), - buildAggTester(ast.AggFuncMin, mysql.TypeJSON, 5, nil, json.CreateBinary(int64(0))), + buildAggTester(ast.AggFuncMin, mysql.TypeJSON, 5, nil, types.CreateBinaryJSON(int64(0))), } for _, test := range tests { test := test diff --git a/executor/aggfuncs/func_value.go b/executor/aggfuncs/func_value.go index 0260594ec21a5..efffe4d5f514e 100644 --- a/executor/aggfuncs/func_value.go +++ b/executor/aggfuncs/func_value.go @@ -21,7 +21,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" ) @@ -190,7 +189,7 @@ func (v *value4Duration) appendResult(chk *chunk.Chunk, colIdx int) { } type value4JSON struct { - val json.BinaryJSON + val types.BinaryJSON isNull bool } diff --git a/executor/aggfuncs/window_func_test.go b/executor/aggfuncs/window_func_test.go index 8c9928962a31c..a44541e872b1d 100644 --- a/executor/aggfuncs/window_func_test.go +++ b/executor/aggfuncs/window_func_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/mock" @@ -186,7 +185,7 @@ func TestWindowFunctions(t *testing.T) { buildWindowTester(ast.WindowFuncFirstValue, mysql.TypeString, 0, 1, 2, "0", "0"), buildWindowTester(ast.WindowFuncFirstValue, mysql.TypeDate, 0, 1, 2, types.TimeFromDays(365), types.TimeFromDays(365)), buildWindowTester(ast.WindowFuncFirstValue, mysql.TypeDuration, 0, 1, 2, types.Duration{Duration: time.Duration(0)}, types.Duration{Duration: time.Duration(0)}), - buildWindowTester(ast.WindowFuncFirstValue, mysql.TypeJSON, 0, 1, 2, json.CreateBinary(int64(0)), json.CreateBinary(int64(0))), + buildWindowTester(ast.WindowFuncFirstValue, mysql.TypeJSON, 0, 1, 2, types.CreateBinaryJSON(int64(0)), types.CreateBinaryJSON(int64(0))), buildWindowTester(ast.WindowFuncLastValue, mysql.TypeLonglong, 1, 0, 2, 1, 1), diff --git a/executor/aggregate.go b/executor/aggregate.go index f505049149e65..cbcd2c8ec3793 100644 --- a/executor/aggregate.go +++ b/executor/aggregate.go @@ -32,7 +32,6 @@ import ( "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/channel" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" @@ -1829,7 +1828,7 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express previousIsNull = isNull } case types.ETJson: - var previousKey, key json.BinaryJSON + var previousKey, key types.BinaryJSON if !previousIsNull { previousKey = col.GetJSON(0) } @@ -1840,7 +1839,7 @@ func (e *vecGroupChecker) evalGroupItemsAndResolveGroups(item expression.Express } if e.sameGroup[i] { if isNull == previousIsNull { - if !isNull && json.CompareBinary(previousKey, key) != 0 { + if !isNull && types.CompareBinaryJSON(previousKey, key) != 0 { e.sameGroup[i] = false } } else { diff --git a/executor/executor_required_rows_test.go b/executor/executor_required_rows_test.go index d378185361f00..b647b64acd576 100644 --- a/executor/executor_required_rows_test.go +++ b/executor/executor_required_rows_test.go @@ -31,7 +31,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/disk" "github.com/pingcap/tidb/util/mathutil" @@ -890,7 +889,7 @@ func TestVecGroupCheckerDATARACE(t *testing.T) { chk.Column(0).Decimals()[0] = *types.NewDecFromInt(123) case mysql.TypeJSON: chk.Column(0).ReserveJSON(1) - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) require.NoError(t, j.UnmarshalJSON([]byte(fmt.Sprintf(`{"%v":%v}`, 123, 123)))) chk.Column(0).AppendJSON(*j) } @@ -917,7 +916,7 @@ func TestVecGroupCheckerDATARACE(t *testing.T) { require.Equal(t, `{"123": 123}`, vgc.firstRowDatums[0].GetMysqlJSON().String()) require.Equal(t, `{"123": 123}`, vgc.lastRowDatums[0].GetMysqlJSON().String()) chk.Column(0).ReserveJSON(1) - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) require.NoError(t, j.UnmarshalJSON([]byte(fmt.Sprintf(`{"%v":%v}`, 456, 456)))) chk.Column(0).AppendJSON(*j) require.Equal(t, `{"123": 123}`, vgc.firstRowDatums[0].GetMysqlJSON().String()) diff --git a/executor/hash_table_test.go b/executor/hash_table_test.go index bacc50ab1bfbf..3b4a4acee5284 100644 --- a/executor/hash_table_test.go +++ b/executor/hash_table_test.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/memory" @@ -49,7 +48,7 @@ func initBuildChunk(numRows int) (*chunk.Chunk, []*types.FieldType) { oldChk.AppendString(2, str) oldChk.AppendString(3, str) oldChk.AppendMyDecimal(4, types.NewDecFromStringForTest(str)) - oldChk.AppendJSON(5, json.CreateBinary(str)) + oldChk.AppendJSON(5, types.CreateBinaryJSON(str)) } return oldChk, colTypes } diff --git a/executor/infoschema_reader.go b/executor/infoschema_reader.go index b67ff04c1e6d7..e97089d9a1538 100644 --- a/executor/infoschema_reader.go +++ b/executor/infoschema_reader.go @@ -54,7 +54,6 @@ import ( "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" - binaryJson "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" @@ -1285,7 +1284,7 @@ func (e *memtableRetriever) dataForTiKVStoreStatus(ctx sessionctx.Context) (err if err != nil { return err } - bj := binaryJson.BinaryJSON{} + bj := types.BinaryJSON{} if err = bj.UnmarshalJSON(data); err != nil { return err } diff --git a/executor/show.go b/executor/show.go index cc60c2215f2bd..f902d23680637 100644 --- a/executor/show.go +++ b/executor/show.go @@ -55,7 +55,6 @@ import ( "github.com/pingcap/tidb/table/tables" "github.com/pingcap/tidb/tidb-binlog/node" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" @@ -1776,7 +1775,7 @@ func (e *ShowExec) appendRow(row []interface{}) { e.result.AppendMyDecimal(i, x) case types.Time: e.result.AppendTime(i, x) - case json.BinaryJSON: + case types.BinaryJSON: e.result.AppendJSON(i, x) case types.Duration: e.result.AppendDuration(i, x) @@ -1980,7 +1979,7 @@ func (e *ShowExec) fetchShowSessionStates(ctx context.Context) error { if err != nil { return errors.Trace(err) } - stateJSON := json.BinaryJSON{} + stateJSON := types.BinaryJSON{} if err = stateJSON.UnmarshalJSON(stateBytes); err != nil { return err } @@ -2000,7 +1999,7 @@ func (e *ShowExec) fetchShowSessionStates(ctx context.Context) error { if err != nil { return errors.Trace(err) } - tokenJSON := json.BinaryJSON{} + tokenJSON := types.BinaryJSON{} if err = tokenJSON.UnmarshalJSON(tokenBytes); err != nil { return err } diff --git a/executor/show_placement.go b/executor/show_placement.go index 63e34bb246cea..ae562105476be 100644 --- a/executor/show_placement.go +++ b/executor/show_placement.go @@ -29,7 +29,7 @@ import ( "github.com/pingcap/tidb/store/helper" "github.com/pingcap/tidb/table" "github.com/pingcap/tidb/tablecodec" - "github.com/pingcap/tidb/types/json" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/sqlexec" "golang.org/x/exp/slices" @@ -39,7 +39,7 @@ type showPlacementLabelsResultBuilder struct { labelKey2values map[string]interface{} } -func (b *showPlacementLabelsResultBuilder) AppendStoreLabels(bj json.BinaryJSON) error { +func (b *showPlacementLabelsResultBuilder) AppendStoreLabels(bj types.BinaryJSON) error { if b.labelKey2values == nil { b.labelKey2values = make(map[string]interface{}) } @@ -53,7 +53,7 @@ func (b *showPlacementLabelsResultBuilder) AppendStoreLabels(bj json.BinaryJSON) return nil } - if bj.TypeCode != json.TypeCodeArray { + if bj.TypeCode != types.JSONTypeCodeArray { return errors.New("only array or null type is allowed") } @@ -83,7 +83,7 @@ func (b *showPlacementLabelsResultBuilder) BuildRows() ([][]interface{}, error) return nil, errors.Trace(err) } - valuesJSON := json.BinaryJSON{} + valuesJSON := types.BinaryJSON{} err = valuesJSON.UnmarshalJSON(d) if err != nil { return nil, errors.Trace(err) diff --git a/executor/show_placement_labels_test.go b/executor/show_placement_labels_test.go index a6d17b6b5e203..e1970ba62d80c 100644 --- a/executor/show_placement_labels_test.go +++ b/executor/show_placement_labels_test.go @@ -19,7 +19,7 @@ import ( "testing" "github.com/pingcap/tidb/store/helper" - "github.com/pingcap/tidb/types/json" + "github.com/pingcap/tidb/types" "github.com/stretchr/testify/require" ) @@ -51,7 +51,7 @@ func TestShowPlacementLabelsBuilder(t *testing.T) { } b := &showPlacementLabelsResultBuilder{} - toBinaryJSON := func(obj interface{}) (bj json.BinaryJSON) { + toBinaryJSON := func(obj interface{}) (bj types.BinaryJSON) { d, err := gjson.Marshal(obj) require.NoError(t, err) err = bj.UnmarshalJSON(d) @@ -74,8 +74,8 @@ func TestShowPlacementLabelsBuilder(t *testing.T) { bj := toBinaryJSON(expect[1]) require.Equal(t, expect[0].(string), row[0].(string)) - require.Equal(t, bj.TypeCode, row[1].(json.BinaryJSON).TypeCode) - require.Equal(t, bj.Value, row[1].(json.BinaryJSON).Value) + require.Equal(t, bj.TypeCode, row[1].(types.BinaryJSON).TypeCode) + require.Equal(t, bj.Value, row[1].(types.BinaryJSON).Value) } } } diff --git a/expression/BUILD.bazel b/expression/BUILD.bazel index 55e7dc328f0af..f8165beb16a86 100644 --- a/expression/BUILD.bazel +++ b/expression/BUILD.bazel @@ -79,7 +79,6 @@ go_library( "//sessionctx/stmtctx", "//sessionctx/variable", "//types", - "//types/json", "//types/parser_driver", "//util", "//util/chunk", @@ -203,7 +202,6 @@ go_test( "//testkit/testsetup", "//testkit/testutil", "//types", - "//types/json", "//types/parser_driver", "//util", "//util/benchdaily", diff --git a/expression/bench_test.go b/expression/bench_test.go index 37afaec7b6928..d74dc06805549 100644 --- a/expression/bench_test.go +++ b/expression/bench_test.go @@ -37,7 +37,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/benchdaily" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mathutil" @@ -283,7 +282,7 @@ func (g *defaultGener) gen() interface{} { } return d case types.ETJson: - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, g.randGen.Int()))); err != nil { panic(err) } @@ -342,7 +341,7 @@ type constJSONGener struct { } func (g *constJSONGener) gen() interface{} { - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) if err := j.UnmarshalJSON([]byte(g.jsonStr)); err != nil { panic(err) } @@ -372,7 +371,7 @@ func (g *decimalJSONGener) gen() interface{} { if err := (&types.MyDecimal{}).FromFloat64(f); err != nil { panic(err) } - return json.CreateBinary(f) + return types.CreateBinaryJSON(f) } type jsonStringGener struct { @@ -384,7 +383,7 @@ func newJSONStringGener() *jsonStringGener { } func (g *jsonStringGener) gen() interface{} { - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, g.randGen.Int()))); err != nil { panic(err) } @@ -429,7 +428,7 @@ func newJSONTimeGener() *jsonTimeGener { func (g *jsonTimeGener) gen() interface{} { tm := types.NewTime(getRandomTime(g.randGen.Rand), mysql.TypeDatetime, types.DefaultFsp) - return json.CreateBinary(tm.String()) + return types.CreateBinaryJSON(tm.String()) } type rangeDurationGener struct { @@ -1225,7 +1224,7 @@ func fillColumnWithGener(eType types.EvalType, chk *chunk.Chunk, colIdx int, gen case types.ETDuration: col.AppendDuration(v.(types.Duration)) case types.ETJson: - col.AppendJSON(v.(json.BinaryJSON)) + col.AppendJSON(v.(types.BinaryJSON)) case types.ETString: col.AppendString(v.(string)) } @@ -1651,7 +1650,7 @@ func testVectorizedBuiltinFunc(t *testing.T, vecExprCases vecExprBenchCases) { require.NoErrorf(t, err, commentf(i)) require.Equal(t, output.IsNull(i), isNull, commentf(i)) if !isNull { - cmp := json.CompareBinary(val, output.GetJSON(i)) + cmp := types.CompareBinaryJSON(val, output.GetJSON(i)) require.Zero(t, cmp, commentf(i)) } i++ diff --git a/expression/builtin.go b/expression/builtin.go index 4add493d48f1a..f0179f262f85d 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -37,7 +37,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/set" @@ -296,8 +295,8 @@ func (b *baseBuiltinFunc) evalDuration(row chunk.Row) (types.Duration, bool, err return types.Duration{}, false, errors.Errorf("baseBuiltinFunc.evalDuration() should never be called, please contact the TiDB team for help") } -func (b *baseBuiltinFunc) evalJSON(row chunk.Row) (json.BinaryJSON, bool, error) { - return json.BinaryJSON{}, false, errors.Errorf("baseBuiltinFunc.evalJSON() should never be called, please contact the TiDB team for help") +func (b *baseBuiltinFunc) evalJSON(row chunk.Row) (types.BinaryJSON, bool, error) { + return types.BinaryJSON{}, false, errors.Errorf("baseBuiltinFunc.evalJSON() should never be called, please contact the TiDB team for help") } func (b *baseBuiltinFunc) vectorized() bool { @@ -478,7 +477,7 @@ type builtinFunc interface { // evalDuration evaluates duration representation of builtinFunc by given row. evalDuration(row chunk.Row) (val types.Duration, isNull bool, err error) // evalJSON evaluates JSON representation of builtinFunc by given row. - evalJSON(row chunk.Row) (val json.BinaryJSON, isNull bool, err error) + evalJSON(row chunk.Row) (val types.BinaryJSON, isNull bool, err error) // getArgs returns the arguments expressions. getArgs() []Expression // equal check if this function equals to another function. diff --git a/expression/builtin_cast.go b/expression/builtin_cast.go index 6e107f82e1548..97280b061ab60 100644 --- a/expression/builtin_cast.go +++ b/expression/builtin_cast.go @@ -37,7 +37,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tipb/go-tipb" ) @@ -636,17 +635,17 @@ func (b *builtinCastIntAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastIntAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCastIntAsJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { val, isNull, err := b.args[0].EvalInt(b.ctx, row) if isNull || err != nil { return res, isNull, err } if mysql.HasIsBooleanFlag(b.args[0].GetType().GetFlag()) { - res = json.CreateBinary(val != 0) + res = types.CreateBinaryJSON(val != 0) } else if mysql.HasUnsignedFlag(b.args[0].GetType().GetFlag()) { - res = json.CreateBinary(uint64(val)) + res = types.CreateBinaryJSON(uint64(val)) } else { - res = json.CreateBinary(val) + res = types.CreateBinaryJSON(val) } return res, false, nil } @@ -661,10 +660,10 @@ func (b *builtinCastRealAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastRealAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCastRealAsJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { val, isNull, err := b.args[0].EvalReal(b.ctx, row) // FIXME: `select json_type(cast(1111.11 as json))` should return `DECIMAL`, we return `DOUBLE` now. - return json.CreateBinary(val), isNull, err + return types.CreateBinaryJSON(val), isNull, err } type builtinCastDecimalAsJSONSig struct { @@ -677,17 +676,17 @@ func (b *builtinCastDecimalAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastDecimalAsJSONSig) evalJSON(row chunk.Row) (json.BinaryJSON, bool, error) { +func (b *builtinCastDecimalAsJSONSig) evalJSON(row chunk.Row) (types.BinaryJSON, bool, error) { val, isNull, err := b.args[0].EvalDecimal(b.ctx, row) if isNull || err != nil { - return json.BinaryJSON{}, true, err + return types.BinaryJSON{}, true, err } // FIXME: `select json_type(cast(1111.11 as json))` should return `DECIMAL`, we return `DOUBLE` now. f64, err := val.ToFloat64() if err != nil { - return json.BinaryJSON{}, true, err + return types.BinaryJSON{}, true, err } - return json.CreateBinary(f64), isNull, err + return types.CreateBinaryJSON(f64), isNull, err } type builtinCastStringAsJSONSig struct { @@ -700,7 +699,7 @@ func (b *builtinCastStringAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastStringAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCastStringAsJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { val, isNull, err := b.args[0].EvalString(b.ctx, row) if isNull || err != nil { return res, isNull, err @@ -715,16 +714,16 @@ func (b *builtinCastStringAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSO copy(buf, val) } - res := json.CreateBinary(json.Opaque{ + res := types.CreateBinaryJSON(types.Opaque{ TypeCode: b.args[0].GetType().GetType(), Buf: buf, }) return res, false, err } else if mysql.HasParseToJSONFlag(b.tp.GetFlag()) { - res, err = json.ParseBinaryFromString(val) + res, err = types.ParseBinaryJSONFromString(val) } else { - res = json.CreateBinary(val) + res = types.CreateBinaryJSON(val) } return res, false, err } @@ -739,13 +738,13 @@ func (b *builtinCastDurationAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastDurationAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCastDurationAsJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { val, isNull, err := b.args[0].EvalDuration(b.ctx, row) if isNull || err != nil { return res, isNull, err } val.Fsp = types.MaxFsp - return json.CreateBinary(val.String()), false, nil + return types.CreateBinaryJSON(val.String()), false, nil } type builtinCastTimeAsJSONSig struct { @@ -758,7 +757,7 @@ func (b *builtinCastTimeAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastTimeAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCastTimeAsJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { val, isNull, err := b.args[0].EvalTime(b.ctx, row) if isNull || err != nil { return res, isNull, err @@ -766,7 +765,7 @@ func (b *builtinCastTimeAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, if val.Type() == mysql.TypeDatetime || val.Type() == mysql.TypeTimestamp { val.SetFsp(types.MaxFsp) } - return json.CreateBinary(val.String()), false, nil + return types.CreateBinaryJSON(val.String()), false, nil } type builtinCastRealAsRealSig struct { @@ -1640,7 +1639,7 @@ func (b *builtinCastJSONAsJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCastJSONAsJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCastJSONAsJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { return b.args[0].EvalJSON(b.ctx, row) } diff --git a/expression/builtin_cast_test.go b/expression/builtin_cast_test.go index 00bac3f47e25e..dd8fd96748e6e 100644 --- a/expression/builtin_cast_test.go +++ b/expression/builtin_cast_test.go @@ -25,7 +25,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -284,13 +283,13 @@ var ( dt = types.NewTime(types.FromDate(year, int(month), day, 0, 0, 0, 0), mysql.TypeDate, types.DefaultFsp) // jsonInt indicates json(3) - jsonInt = types.NewDatum(json.CreateBinary(int64(3))) + jsonInt = types.NewDatum(types.CreateBinaryJSON(int64(3))) // jsonTime indicates "CURRENT_DAY 12:59:59" - jsonTime = types.NewDatum(json.CreateBinary(tm.String())) + jsonTime = types.NewDatum(types.CreateBinaryJSON(tm.String())) // jsonDuration indicates - jsonDuration = types.NewDatum(json.CreateBinary(duration.String())) + jsonDuration = types.NewDatum(types.CreateBinaryJSON(duration.String())) ) func TestCastFuncSig(t *testing.T) { @@ -1128,7 +1127,7 @@ func TestCastJSONAsDecimalSig(t *testing.T) { {`"1234567890123456789012345678901234567890123456789012345"`, types.NewDecFromStringForTest("1234567890123456789012345678901234567890123456789012345")}, } for _, tt := range tests { - j, err := json.ParseBinaryFromString(tt.In) + j, err := types.ParseBinaryJSONFromString(tt.In) require.NoError(t, err) row := chunk.MutRowFromDatums([]types.Datum{types.NewDatum(j)}) res, isNull, err := sig.evalDecimal(row.ToRow()) @@ -1565,31 +1564,31 @@ func TestCastBinaryStringAsJSONSig(t *testing.T) { var tests = []struct { str string tp *types.FieldType - result json.BinaryJSON + result types.BinaryJSON resultStr string }{ { "a", types.NewFieldTypeWithCollation(mysql.TypeVarString, charset.CollationBin, 4), - json.BinaryJSON{TypeCode: json.TypeCodeOpaque, Value: []byte{0xfd, 1, 'a'}}, + types.BinaryJSON{TypeCode: types.JSONTypeCodeOpaque, Value: []byte{0xfd, 1, 'a'}}, `"base64:type253:YQ=="`, }, { "test", types.NewFieldTypeWithCollation(mysql.TypeVarString, charset.CollationBin, 4), - json.BinaryJSON{TypeCode: json.TypeCodeOpaque, Value: []byte{0xfd, 4, 't', 'e', 's', 't'}}, + types.BinaryJSON{TypeCode: types.JSONTypeCodeOpaque, Value: []byte{0xfd, 4, 't', 'e', 's', 't'}}, `"base64:type253:dGVzdA=="`, }, { "a", types.NewFieldTypeWithCollation(mysql.TypeString, charset.CollationBin, 4), - json.BinaryJSON{TypeCode: json.TypeCodeOpaque, Value: []byte{0xfe, 4, 'a', 0, 0, 0}}, + types.BinaryJSON{TypeCode: types.JSONTypeCodeOpaque, Value: []byte{0xfe, 4, 'a', 0, 0, 0}}, `"base64:type254:YQAAAA=="`, }, { "a", types.NewFieldTypeWithCollation(mysql.TypeBlob, charset.CollationBin, 4), - json.BinaryJSON{TypeCode: json.TypeCodeOpaque, Value: []byte{0xfc, 1, 'a'}}, + types.BinaryJSON{TypeCode: types.JSONTypeCodeOpaque, Value: []byte{0xfc, 1, 'a'}}, `"base64:type252:YQ=="`, }, } diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index fe28cab8de64a..952c90308c6fb 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" ) @@ -185,7 +184,7 @@ func (b *builtinCastTimeAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk if tp == mysql.TypeDatetime || tp == mysql.TypeTimestamp { tms[i].SetFsp(types.MaxFsp) } - result.AppendJSON(json.CreateBinary(tms[i].String())) + result.AppendJSON(types.CreateBinaryJSON(tms[i].String())) } return nil } @@ -427,7 +426,7 @@ func (b *builtinCastRealAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk if buf.IsNull(i) { result.AppendNull() } else { - result.AppendJSON(json.CreateBinary(f64s[i])) + result.AppendJSON(types.CreateBinaryJSON(f64s[i])) } } return nil @@ -790,7 +789,7 @@ func (b *builtinCastStringAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chu result.ReserveJSON(n) typ := b.args[0].GetType() if types.IsBinaryStr(typ) { - var res json.BinaryJSON + var res types.BinaryJSON for i := 0; i < n; i++ { if buf.IsNull(i) { result.AppendNull() @@ -805,20 +804,20 @@ func (b *builtinCastStringAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chu copy(resultBuf, val) } - res = json.CreateBinary(json.Opaque{ + res = types.CreateBinaryJSON(types.Opaque{ TypeCode: b.args[0].GetType().GetType(), Buf: resultBuf, }) result.AppendJSON(res) } } else if mysql.HasParseToJSONFlag(b.tp.GetFlag()) { - var res json.BinaryJSON + var res types.BinaryJSON for i := 0; i < n; i++ { if buf.IsNull(i) { result.AppendNull() continue } - res, err = json.ParseBinaryFromString(buf.GetString(i)) + res, err = types.ParseBinaryJSONFromString(buf.GetString(i)) if err != nil { return err } @@ -830,7 +829,7 @@ func (b *builtinCastStringAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chu result.AppendNull() continue } - result.AppendJSON(json.CreateBinary(buf.GetString(i))) + result.AppendJSON(types.CreateBinaryJSON(buf.GetString(i))) } } return nil @@ -1089,7 +1088,7 @@ func (b *builtinCastIntAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk. if buf.IsNull(i) { result.AppendNull() } else { - result.AppendJSON(json.CreateBinary(nums[i] != 0)) + result.AppendJSON(types.CreateBinaryJSON(nums[i] != 0)) } } } else if mysql.HasUnsignedFlag(b.args[0].GetType().GetFlag()) { @@ -1097,7 +1096,7 @@ func (b *builtinCastIntAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk. if buf.IsNull(i) { result.AppendNull() } else { - result.AppendJSON(json.CreateBinary(uint64(nums[i]))) + result.AppendJSON(types.CreateBinaryJSON(uint64(nums[i]))) } } } else { @@ -1105,7 +1104,7 @@ func (b *builtinCastIntAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *chunk. if buf.IsNull(i) { result.AppendNull() } else { - result.AppendJSON(json.CreateBinary(nums[i])) + result.AppendJSON(types.CreateBinaryJSON(nums[i])) } } } @@ -1946,7 +1945,7 @@ func (b *builtinCastDecimalAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *ch if err != nil { return err } - result.AppendJSON(json.CreateBinary(f)) + result.AppendJSON(types.CreateBinaryJSON(f)) } return nil } @@ -1976,7 +1975,7 @@ func (b *builtinCastDurationAsJSONSig) vecEvalJSON(input *chunk.Chunk, result *c continue } dur.Duration = ds[i] - result.AppendJSON(json.CreateBinary(dur.String())) + result.AppendJSON(types.CreateBinaryJSON(dur.String())) } return nil } diff --git a/expression/builtin_cast_vec_test.go b/expression/builtin_cast_vec_test.go index 45515af264689..a5542efd680f9 100644 --- a/expression/builtin_cast_vec_test.go +++ b/expression/builtin_cast_vec_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -128,7 +127,7 @@ func (g *randJSONDuration) gen() interface{} { d := types.Duration{ Duration: time.Duration(rand.Intn(12))*time.Hour + time.Duration(rand.Intn(60))*time.Minute + time.Duration(rand.Intn(60))*time.Second + time.Duration(rand.Intn(1000))*time.Millisecond, Fsp: 3} - return json.CreateBinary(d.String()) + return types.CreateBinaryJSON(d.String()) } type datetimeJSONGener struct{} @@ -146,7 +145,7 @@ func (g *datetimeJSONGener) gen() interface{} { 0, 3, ) - return json.CreateBinary(d.String()) + return types.CreateBinaryJSON(d.String()) } func TestVectorizedBuiltinCastEvalOneVec(t *testing.T) { diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 1aaf49c03883d..3baa86b635ba6 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -25,7 +25,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tipb/go-tipb" @@ -371,7 +370,7 @@ func (b *builtinCoalesceJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinCoalesceJSONSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinCoalesceJSONSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { for _, a := range b.getArgs() { res, isNull, err = a.EvalJSON(b.ctx, row) if err != nil || !isNull { @@ -2744,7 +2743,7 @@ func (b *builtinNullEQJSONSig) evalInt(row chunk.Row) (val int64, isNull bool, e case isNull0 != isNull1: return res, false, nil default: - cmpRes := json.CompareBinary(arg0, arg1) + cmpRes := types.CompareBinaryJSON(arg0, arg1) if cmpRes == 0 { res = 1 } @@ -2992,5 +2991,5 @@ func CompareJSON(sctx sessionctx.Context, lhsArg, rhsArg Expression, lhsRow, rhs if isNull0 || isNull1 { return compareNull(isNull0, isNull1), true, nil } - return int64(json.CompareBinary(arg0, arg1)), false, nil + return int64(types.CompareBinaryJSON(arg0, arg1)), false, nil } diff --git a/expression/builtin_compare_test.go b/expression/builtin_compare_test.go index b5b4b6cb3fb55..78229b77b1f60 100644 --- a/expression/builtin_compare_test.go +++ b/expression/builtin_compare_test.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/stretchr/testify/require" ) @@ -88,7 +87,7 @@ func TestCompare(t *testing.T) { intVal, uintVal, realVal, stringVal, decimalVal := 1, uint64(1), 1.1, "123", types.NewDecFromFloatForTest(123.123) timeVal := types.NewTime(types.FromGoTime(time.Now()), mysql.TypeDatetime, 6) durationVal := types.Duration{Duration: 12*time.Hour + 1*time.Minute + 1*time.Second} - jsonVal := json.CreateBinary("123") + jsonVal := types.CreateBinaryJSON("123") // test cases for generating function signatures. tests := []struct { arg0 interface{} diff --git a/expression/builtin_compare_vec_generated.go b/expression/builtin_compare_vec_generated.go index 7149807860aa1..e4dca22a50acc 100644 --- a/expression/builtin_compare_vec_generated.go +++ b/expression/builtin_compare_vec_generated.go @@ -18,7 +18,6 @@ package expression import ( "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" ) @@ -236,7 +235,7 @@ func (b *builtinLTJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) if result.IsNull(i) { continue } - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) i64s[i] = boolToInt64(val < 0) } return nil @@ -460,7 +459,7 @@ func (b *builtinLEJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) if result.IsNull(i) { continue } - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) i64s[i] = boolToInt64(val <= 0) } return nil @@ -684,7 +683,7 @@ func (b *builtinGTJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) if result.IsNull(i) { continue } - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) i64s[i] = boolToInt64(val > 0) } return nil @@ -908,7 +907,7 @@ func (b *builtinGEJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) if result.IsNull(i) { continue } - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) i64s[i] = boolToInt64(val >= 0) } return nil @@ -1132,7 +1131,7 @@ func (b *builtinEQJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) if result.IsNull(i) { continue } - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) i64s[i] = boolToInt64(val == 0) } return nil @@ -1356,7 +1355,7 @@ func (b *builtinNEJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) if result.IsNull(i) { continue } - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) i64s[i] = boolToInt64(val != 0) } return nil @@ -1603,7 +1602,7 @@ func (b *builtinNullEQJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Colu i64s[i] = 1 case isNull0 != isNull1: i64s[i] = 0 - case json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) == 0: + case types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) == 0: i64s[i] = 1 } } diff --git a/expression/builtin_control.go b/expression/builtin_control.go index e03581084418c..de055b936505e 100644 --- a/expression/builtin_control.go +++ b/expression/builtin_control.go @@ -18,7 +18,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mathutil" "github.com/pingcap/tipb/go-tipb" @@ -509,7 +508,7 @@ func (b *builtinCaseWhenJSONSig) Clone() builtinFunc { // evalJSON evals a builtinCaseWhenJSONSig. // See https://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html#operator_case -func (b *builtinCaseWhenJSONSig) evalJSON(row chunk.Row) (ret json.BinaryJSON, isNull bool, err error) { +func (b *builtinCaseWhenJSONSig) evalJSON(row chunk.Row) (ret types.BinaryJSON, isNull bool, err error) { var condition int64 args, l := b.getArgs(), len(b.getArgs()) for i := 0; i < l-1; i += 2 { @@ -718,7 +717,7 @@ func (b *builtinIfJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinIfJSONSig) evalJSON(row chunk.Row) (ret json.BinaryJSON, isNull bool, err error) { +func (b *builtinIfJSONSig) evalJSON(row chunk.Row) (ret types.BinaryJSON, isNull bool, err error) { arg0, isNull0, err := b.args[0].EvalInt(b.ctx, row) if err != nil { return ret, true, err @@ -906,7 +905,7 @@ func (b *builtinIfNullJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinIfNullJSONSig) evalJSON(row chunk.Row) (json.BinaryJSON, bool, error) { +func (b *builtinIfNullJSONSig) evalJSON(row chunk.Row) (types.BinaryJSON, bool, error) { arg0, isNull, err := b.args[0].EvalJSON(b.ctx, row) if !isNull { return arg0, err != nil, err diff --git a/expression/builtin_info_test.go b/expression/builtin_info_test.go index 96e652ab00b8e..bb04746bc62a2 100644 --- a/expression/builtin_info_test.go +++ b/expression/builtin_info_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/testkit/testutil" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mock" "github.com/pingcap/tidb/util/printer" @@ -164,7 +163,7 @@ func TestBenchMark(t *testing.T) { {3, types.CurrentTime(mysql.TypeDatetime), 0, false}, {3, types.CurrentTime(mysql.TypeTimestamp), 0, false}, {3, types.CurrentTime(mysql.TypeDuration), 0, false}, - {3, json.CreateBinary("[1]"), 0, false}, + {3, types.CreateBinaryJSON("[1]"), 0, false}, } for _, c := range cases { diff --git a/expression/builtin_json.go b/expression/builtin_json.go index 13037623d7613..3db95a03830c9 100644 --- a/expression/builtin_json.go +++ b/expression/builtin_json.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tipb/go-tipb" @@ -117,7 +116,7 @@ func (c *jsonTypeFunctionClass) getFunction(ctx sessionctx.Context, args []Expre } func (b *builtinJSONTypeSig) evalString(row chunk.Row) (res string, isNull bool, err error) { - var j json.BinaryJSON + var j types.BinaryJSON j, isNull, err = b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return "", isNull, err @@ -157,19 +156,19 @@ func (c *jsonExtractFunctionClass) getFunction(ctx sessionctx.Context, args []Ex return sig, nil } -func (b *builtinJSONExtractSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONExtractSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return } - pathExprs := make([]json.PathExpression, 0, len(b.args)-1) + pathExprs := make([]types.JSONPathExpression, 0, len(b.args)-1) for _, arg := range b.args[1:] { var s string s, isNull, err = arg.EvalString(b.ctx, row) if isNull || err != nil { return res, isNull, err } - pathExpr, err := json.ParseJSONPathExpr(s) + pathExpr, err := types.ParseJSONPathExpr(s) if err != nil { return res, true, err } @@ -228,9 +227,9 @@ func (b *builtinJSONUnquoteSig) evalString(row chunk.Row) (str string, isNull bo return "", isNull, err } if len(str) >= 2 && str[0] == '"' && str[len(str)-1] == '"' && !goJSON.Valid([]byte(str)) { - return "", false, json.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.") + return "", false, types.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.") } - str, err = json.UnquoteString(str) + str, err = types.UnquoteString(str) if err != nil { return "", false, err } @@ -275,8 +274,8 @@ func (c *jsonSetFunctionClass) getFunction(ctx sessionctx.Context, args []Expres return sig, nil } -func (b *builtinJSONSetSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { - res, isNull, err = jsonModify(b.ctx, b.args, row, json.ModifySet) +func (b *builtinJSONSetSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { + res, isNull, err = jsonModify(b.ctx, b.args, row, types.JSONModifySet) return res, isNull, err } @@ -318,8 +317,8 @@ func (c *jsonInsertFunctionClass) getFunction(ctx sessionctx.Context, args []Exp return sig, nil } -func (b *builtinJSONInsertSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { - res, isNull, err = jsonModify(b.ctx, b.args, row, json.ModifyInsert) +func (b *builtinJSONInsertSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { + res, isNull, err = jsonModify(b.ctx, b.args, row, types.JSONModifyInsert) return res, isNull, err } @@ -361,8 +360,8 @@ func (c *jsonReplaceFunctionClass) getFunction(ctx sessionctx.Context, args []Ex return sig, nil } -func (b *builtinJSONReplaceSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { - res, isNull, err = jsonModify(b.ctx, b.args, row, json.ModifyReplace) +func (b *builtinJSONReplaceSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { + res, isNull, err = jsonModify(b.ctx, b.args, row, types.JSONModifyReplace) return res, isNull, err } @@ -398,20 +397,20 @@ func (c *jsonRemoveFunctionClass) getFunction(ctx sessionctx.Context, args []Exp return sig, nil } -func (b *builtinJSONRemoveSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONRemoveSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return res, isNull, err } - pathExprs := make([]json.PathExpression, 0, len(b.args)-1) + pathExprs := make([]types.JSONPathExpression, 0, len(b.args)-1) for _, arg := range b.args[1:] { var s string s, isNull, err = arg.EvalString(b.ctx, row) if isNull || err != nil { return res, isNull, err } - var pathExpr json.PathExpression - pathExpr, err = json.ParseJSONPathExpr(s) + var pathExpr types.JSONPathExpression + pathExpr, err = types.ParseJSONPathExpr(s) if err != nil { return res, true, err } @@ -467,17 +466,17 @@ func (c *jsonMergeFunctionClass) getFunction(ctx sessionctx.Context, args []Expr return sig, nil } -func (b *builtinJSONMergeSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { - values := make([]json.BinaryJSON, 0, len(b.args)) +func (b *builtinJSONMergeSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { + values := make([]types.BinaryJSON, 0, len(b.args)) for _, arg := range b.args { - var value json.BinaryJSON + var value types.BinaryJSON value, isNull, err = arg.EvalJSON(b.ctx, row) if isNull || err != nil { return res, isNull, err } values = append(values, value) } - res = json.MergeBinary(values) + res = types.MergeBinaryJSON(values) // function "JSON_MERGE" is deprecated since MySQL 5.7.22. Synonym for function "JSON_MERGE_PRESERVE". // See https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#function_json-merge if b.pbCode == tipb.ScalarFuncSig_JsonMergeSig { @@ -510,7 +509,7 @@ func (c *jsonObjectFunctionClass) getFunction(ctx sessionctx.Context, args []Exp argTps := make([]types.EvalType, 0, len(args)) for i := 0; i < len(args)-1; i += 2 { if args[i].GetType().EvalType() == types.ETString && args[i].GetType().GetCharset() == charset.CharsetBin { - return nil, json.ErrInvalidJSONCharset.GenWithStackByArgs(args[i].GetType().GetCharset()) + return nil, types.ErrInvalidJSONCharset.GenWithStackByArgs(args[i].GetType().GetCharset()) } argTps = append(argTps, types.ETString, types.ETJson) } @@ -526,14 +525,14 @@ func (c *jsonObjectFunctionClass) getFunction(ctx sessionctx.Context, args []Exp return sig, nil } -func (b *builtinJSONObjectSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONObjectSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { if len(b.args)&1 == 1 { err = ErrIncorrectParameterCount.GenWithStackByArgs(ast.JSONObject) return res, true, err } jsons := make(map[string]interface{}, len(b.args)>>1) var key string - var value json.BinaryJSON + var value types.BinaryJSON for i, arg := range b.args { if i&1 == 0 { key, isNull, err = arg.EvalString(b.ctx, row) @@ -550,12 +549,12 @@ func (b *builtinJSONObjectSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isN return res, true, err } if isNull { - value = json.CreateBinary(nil) + value = types.CreateBinaryJSON(nil) } jsons[key] = value } } - return json.CreateBinary(jsons), false, nil + return types.CreateBinaryJSON(jsons), false, nil } type jsonArrayFunctionClass struct { @@ -592,7 +591,7 @@ func (c *jsonArrayFunctionClass) getFunction(ctx sessionctx.Context, args []Expr return sig, nil } -func (b *builtinJSONArraySig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONArraySig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { jsons := make([]interface{}, 0, len(b.args)) for _, arg := range b.args { j, isNull, err := arg.EvalJSON(b.ctx, row) @@ -600,11 +599,11 @@ func (b *builtinJSONArraySig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNu return res, true, err } if isNull { - j = json.CreateBinary(nil) + j = types.CreateBinaryJSON(nil) } jsons = append(jsons, j) } - return json.CreateBinary(jsons), false, nil + return types.CreateBinaryJSON(jsons), false, nil } type jsonContainsPathFunctionClass struct { @@ -648,38 +647,38 @@ func (b *builtinJSONContainsPathSig) evalInt(row chunk.Row) (res int64, isNull b return res, isNull, err } containType = strings.ToLower(containType) - if containType != json.ContainsPathAll && containType != json.ContainsPathOne { - return res, true, json.ErrInvalidJSONContainsPathType + if containType != types.JSONContainsPathAll && containType != types.JSONContainsPathOne { + return res, true, types.ErrInvalidJSONContainsPathType } - var pathExpr json.PathExpression + var pathExpr types.JSONPathExpression contains := int64(1) for i := 2; i < len(b.args); i++ { path, isNull, err := b.args[i].EvalString(b.ctx, row) if isNull || err != nil { return res, isNull, err } - if pathExpr, err = json.ParseJSONPathExpr(path); err != nil { + if pathExpr, err = types.ParseJSONPathExpr(path); err != nil { return res, true, err } - _, exists := obj.Extract([]json.PathExpression{pathExpr}) + _, exists := obj.Extract([]types.JSONPathExpression{pathExpr}) switch { - case exists && containType == json.ContainsPathOne: + case exists && containType == types.JSONContainsPathOne: return 1, false, nil - case !exists && containType == json.ContainsPathOne: + case !exists && containType == types.JSONContainsPathOne: contains = 0 - case !exists && containType == json.ContainsPathAll: + case !exists && containType == types.JSONContainsPathAll: return 0, false, nil } } return contains, false, nil } -func jsonModify(ctx sessionctx.Context, args []Expression, row chunk.Row, mt json.ModifyType) (res json.BinaryJSON, isNull bool, err error) { +func jsonModify(ctx sessionctx.Context, args []Expression, row chunk.Row, mt types.JSONModifyType) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = args[0].EvalJSON(ctx, row) if isNull || err != nil { return res, isNull, err } - pathExprs := make([]json.PathExpression, 0, (len(args)-1)/2+1) + pathExprs := make([]types.JSONPathExpression, 0, (len(args)-1)/2+1) for i := 1; i < len(args); i += 2 { // TODO: We can cache pathExprs if args are constants. var s string @@ -687,22 +686,22 @@ func jsonModify(ctx sessionctx.Context, args []Expression, row chunk.Row, mt jso if isNull || err != nil { return res, isNull, err } - var pathExpr json.PathExpression - pathExpr, err = json.ParseJSONPathExpr(s) + var pathExpr types.JSONPathExpression + pathExpr, err = types.ParseJSONPathExpr(s) if err != nil { return res, true, err } pathExprs = append(pathExprs, pathExpr) } - values := make([]json.BinaryJSON, 0, (len(args)-1)/2+1) + values := make([]types.BinaryJSON, 0, (len(args)-1)/2+1) for i := 2; i < len(args); i += 2 { - var value json.BinaryJSON + var value types.BinaryJSON value, isNull, err = args[i].EvalJSON(ctx, row) if err != nil { return res, true, err } if isNull { - value = json.CreateBinary(nil) + value = types.CreateBinaryJSON(nil) } values = append(values, value) } @@ -732,10 +731,10 @@ func (c *jsonContainsFunctionClass) verifyArgs(args []Expression) error { return err } if evalType := args[0].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString { - return json.ErrInvalidJSONData.GenWithStackByArgs(1, "json_contains") + return types.ErrInvalidJSONData.GenWithStackByArgs(1, "json_contains") } if evalType := args[1].GetType().EvalType(); evalType != types.ETJson && evalType != types.ETString { - return json.ErrInvalidJSONData.GenWithStackByArgs(2, "json_contains") + return types.ErrInvalidJSONData.GenWithStackByArgs(2, "json_contains") } return nil } @@ -767,27 +766,27 @@ func (b *builtinJSONContainsSig) evalInt(row chunk.Row) (res int64, isNull bool, if isNull || err != nil { return res, isNull, err } - var pathExpr json.PathExpression + var pathExpr types.JSONPathExpression if len(b.args) == 3 { path, isNull, err := b.args[2].EvalString(b.ctx, row) if isNull || err != nil { return res, isNull, err } - pathExpr, err = json.ParseJSONPathExpr(path) + pathExpr, err = types.ParseJSONPathExpr(path) if err != nil { return res, true, err } if pathExpr.ContainsAnyAsterisk() { - return res, true, json.ErrInvalidJSONPathWildcard + return res, true, types.ErrInvalidJSONPathWildcard } var exists bool - obj, exists = obj.Extract([]json.PathExpression{pathExpr}) + obj, exists = obj.Extract([]types.JSONPathExpression{pathExpr}) if !exists { return res, true, nil } } - if json.ContainsBinary(obj, target) { + if types.ContainsBinaryJSON(obj, target) { return 1, false, nil } return 0, false, nil @@ -930,7 +929,7 @@ func (b *builtinJSONArrayAppendSig) Clone() builtinFunc { return newSig } -func (b *builtinJSONArrayAppendSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONArrayAppendSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = b.args[0].EvalJSON(b.ctx, row) if err != nil || isNull { return res, true, err @@ -947,7 +946,7 @@ func (b *builtinJSONArrayAppendSig) evalJSON(row chunk.Row) (res json.BinaryJSON return res, true, err } if vNull { - value = json.CreateBinary(nil) + value = types.CreateBinaryJSON(nil) } res, isNull, err = b.appendJSONArray(res, s, value) if isNull || err != nil { @@ -957,31 +956,31 @@ func (b *builtinJSONArrayAppendSig) evalJSON(row chunk.Row) (res json.BinaryJSON return res, false, nil } -func (b *builtinJSONArrayAppendSig) appendJSONArray(res json.BinaryJSON, p string, v json.BinaryJSON) (json.BinaryJSON, bool, error) { +func (b *builtinJSONArrayAppendSig) appendJSONArray(res types.BinaryJSON, p string, v types.BinaryJSON) (types.BinaryJSON, bool, error) { // We should do the following checks to get correct values in res.Extract - pathExpr, err := json.ParseJSONPathExpr(p) + pathExpr, err := types.ParseJSONPathExpr(p) if err != nil { - return res, true, json.ErrInvalidJSONPath.GenWithStackByArgs(p) + return res, true, types.ErrInvalidJSONPath.GenWithStackByArgs(p) } if pathExpr.ContainsAnyAsterisk() { - return res, true, json.ErrInvalidJSONPathWildcard.GenWithStackByArgs(p) + return res, true, types.ErrInvalidJSONPathWildcard.GenWithStackByArgs(p) } - obj, exists := res.Extract([]json.PathExpression{pathExpr}) + obj, exists := res.Extract([]types.JSONPathExpression{pathExpr}) if !exists { // If path not exists, just do nothing and no errors. return res, false, nil } - if obj.TypeCode != json.TypeCodeArray { + if obj.TypeCode != types.JSONTypeCodeArray { // res.Extract will return a json object instead of an array if there is an object at path pathExpr. // JSON_ARRAY_APPEND({"a": "b"}, "$", {"b": "c"}) => [{"a": "b"}, {"b", "c"}] // We should wrap them to a single array first. - obj = json.CreateBinary([]interface{}{obj}) + obj = types.CreateBinaryJSON([]interface{}{obj}) } - obj = json.MergeBinary([]json.BinaryJSON{obj, v}) - res, err = res.Modify([]json.PathExpression{pathExpr}, []json.BinaryJSON{obj}, json.ModifySet) + obj = types.MergeBinaryJSON([]types.BinaryJSON{obj, v}) + res, err = res.Modify([]types.JSONPathExpression{pathExpr}, []types.BinaryJSON{obj}, types.JSONModifySet) return res, false, err } @@ -1024,7 +1023,7 @@ func (b *builtinJSONArrayInsertSig) Clone() builtinFunc { return newSig } -func (b *builtinJSONArrayInsertSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONArrayInsertSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = b.args[0].EvalJSON(b.ctx, row) if err != nil || isNull { return res, true, err @@ -1037,12 +1036,12 @@ func (b *builtinJSONArrayInsertSig) evalJSON(row chunk.Row) (res json.BinaryJSON return res, true, err } - pathExpr, err := json.ParseJSONPathExpr(s) + pathExpr, err := types.ParseJSONPathExpr(s) if err != nil { - return res, true, json.ErrInvalidJSONPath.GenWithStackByArgs(s) + return res, true, types.ErrInvalidJSONPath.GenWithStackByArgs(s) } if pathExpr.ContainsAnyAsterisk() { - return res, true, json.ErrInvalidJSONPathWildcard.GenWithStackByArgs(s) + return res, true, types.ErrInvalidJSONPathWildcard.GenWithStackByArgs(s) } value, isnull, err := b.args[i+1].EvalJSON(b.ctx, row) @@ -1051,7 +1050,7 @@ func (b *builtinJSONArrayInsertSig) evalJSON(row chunk.Row) (res json.BinaryJSON } if isnull { - value = json.CreateBinary(nil) + value = types.CreateBinaryJSON(nil) } res, err = res.ArrayInsert(pathExpr, value) @@ -1105,10 +1104,10 @@ func (b *builtinJSONMergePatchSig) Clone() builtinFunc { return newSig } -func (b *builtinJSONMergePatchSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { - values := make([]*json.BinaryJSON, 0, len(b.args)) +func (b *builtinJSONMergePatchSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { + values := make([]*types.BinaryJSON, 0, len(b.args)) for _, arg := range b.args { - var value json.BinaryJSON + var value types.BinaryJSON value, isNull, err = arg.EvalJSON(b.ctx, row) if err != nil { return @@ -1119,7 +1118,7 @@ func (b *builtinJSONMergePatchSig) evalJSON(row chunk.Row) (res json.BinaryJSON, values = append(values, &value) } } - tmpRes, err := json.MergePatchBinary(values) + tmpRes, err := types.MergePatchBinaryJSON(values) if err != nil { return } @@ -1292,9 +1291,9 @@ func (c *jsonSearchFunctionClass) getFunction(ctx sessionctx.Context, args []Exp return sig, nil } -func (b *builtinJSONSearchSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONSearchSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { // json_doc - var obj json.BinaryJSON + var obj types.BinaryJSON obj, isNull, err = b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return res, isNull, err @@ -1307,8 +1306,8 @@ func (b *builtinJSONSearchSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isN return res, isNull, err } containType = strings.ToLower(containType) - if containType != json.ContainsPathAll && containType != json.ContainsPathOne { - return res, true, errors.AddStack(json.ErrInvalidJSONContainsPathType) + if containType != types.JSONContainsPathAll && containType != types.JSONContainsPathOne { + return res, true, errors.AddStack(types.ErrInvalidJSONContainsPathType) } // search_str & escape_char @@ -1333,15 +1332,15 @@ func (b *builtinJSONSearchSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isN } } if len(b.args) >= 5 { // path... - pathExprs := make([]json.PathExpression, 0, len(b.args)-4) + pathExprs := make([]types.JSONPathExpression, 0, len(b.args)-4) for i := 4; i < len(b.args); i++ { var s string s, isNull, err = b.args[i].EvalString(b.ctx, row) if isNull || err != nil { return res, isNull, err } - var pathExpr json.PathExpression - pathExpr, err = json.ParseJSONPathExpr(s) + var pathExpr types.JSONPathExpression + pathExpr, err = types.ParseJSONPathExpr(s) if err != nil { return res, true, err } @@ -1469,12 +1468,12 @@ func (b *builtinJSONKeysSig) Clone() builtinFunc { return newSig } -func (b *builtinJSONKeysSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONKeysSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return res, isNull, err } - if res.TypeCode != json.TypeCodeObject { + if res.TypeCode != types.JSONTypeCodeObject { return res, true, nil } return res.GetKeys(), false, nil @@ -1490,7 +1489,7 @@ func (b *builtinJSONKeys2ArgsSig) Clone() builtinFunc { return newSig } -func (b *builtinJSONKeys2ArgsSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNull bool, err error) { +func (b *builtinJSONKeys2ArgsSig) evalJSON(row chunk.Row) (res types.BinaryJSON, isNull bool, err error) { res, isNull, err = b.args[0].EvalJSON(b.ctx, row) if isNull || err != nil { return res, isNull, err @@ -1501,19 +1500,19 @@ func (b *builtinJSONKeys2ArgsSig) evalJSON(row chunk.Row) (res json.BinaryJSON, return res, isNull, err } - pathExpr, err := json.ParseJSONPathExpr(path) + pathExpr, err := types.ParseJSONPathExpr(path) if err != nil { return res, true, err } if pathExpr.ContainsAnyAsterisk() { - return res, true, json.ErrInvalidJSONPathWildcard + return res, true, types.ErrInvalidJSONPathWildcard } - res, exists := res.Extract([]json.PathExpression{pathExpr}) + res, exists := res.Extract([]types.JSONPathExpression{pathExpr}) if !exists { return res, true, nil } - if res.TypeCode != json.TypeCodeObject { + if res.TypeCode != types.JSONTypeCodeObject { return res, true, nil } @@ -1560,7 +1559,7 @@ func (b *builtinJSONLengthSig) evalInt(row chunk.Row) (res int64, isNull bool, e return res, isNull, err } - if obj.TypeCode != json.TypeCodeObject && obj.TypeCode != json.TypeCodeArray { + if obj.TypeCode != types.JSONTypeCodeObject && obj.TypeCode != types.JSONTypeCodeArray { return 1, false, nil } @@ -1570,20 +1569,20 @@ func (b *builtinJSONLengthSig) evalInt(row chunk.Row) (res int64, isNull bool, e return res, isNull, err } - pathExpr, err := json.ParseJSONPathExpr(path) + pathExpr, err := types.ParseJSONPathExpr(path) if err != nil { return res, true, err } if pathExpr.ContainsAnyAsterisk() { - return res, true, json.ErrInvalidJSONPathWildcard + return res, true, types.ErrInvalidJSONPathWildcard } var exists bool - obj, exists = obj.Extract([]json.PathExpression{pathExpr}) + obj, exists = obj.Extract([]types.JSONPathExpression{pathExpr}) if !exists { return res, true, nil } - if obj.TypeCode != json.TypeCodeObject && obj.TypeCode != json.TypeCodeArray { + if obj.TypeCode != types.JSONTypeCodeObject && obj.TypeCode != types.JSONTypeCodeArray { return 1, false, nil } } diff --git a/expression/builtin_json_test.go b/expression/builtin_json_test.go index 48b47eed331f6..1ad9888db6493 100644 --- a/expression/builtin_json_test.go +++ b/expression/builtin_json_test.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/testkit/testutil" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/stretchr/testify/require" ) @@ -103,8 +102,8 @@ func TestJSONUnquote(t *testing.T) { {`"[{\"x\":\"{\\\"y\\\":12}\"}]"`, `[{"x":"{\"y\":12}"}]`, nil}, {`[{\"x\":\"{\\\"y\\\":12}\"}]`, `[{\"x\":\"{\\\"y\\\":12}\"}]`, nil}, {`"a"`, `a`, nil}, - {`""a""`, `""a""`, json.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.")}, - {`"""a"""`, `"""a"""`, json.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.")}, + {`""a""`, `""a""`, types.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.")}, + {`"""a"""`, `"""a"""`, types.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.")}, } for _, tt := range tbl { var d types.Datum @@ -144,12 +143,12 @@ func TestJSONExtract(t *testing.T) { require.NoError(t, err) switch x := tt.Expected.(type) { case string: - var j1 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() var cmp int - cmp = json.CompareBinary(j1, j2) + cmp = types.CompareBinaryJSON(j1, j2) require.NoError(t, err) require.Equal(t, 0, cmp) } @@ -191,12 +190,12 @@ func TestJSONSetInsertReplace(t *testing.T) { require.NoError(t, err) switch x := tt.Expected.(type) { case string: - var j1 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() var cmp int - cmp = json.CompareBinary(j1, j2) + cmp = types.CompareBinaryJSON(j1, j2) require.Equal(t, 0, cmp) } continue @@ -226,10 +225,10 @@ func TestJSONMerge(t *testing.T) { switch x := tt.Expected.(type) { case string: - j1, err := json.ParseBinaryFromString(x) + j1, err := types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() - cmp := json.CompareBinary(j1, j2) + cmp := types.CompareBinaryJSON(j1, j2) require.Zerof(t, cmp, "got %v expect %v", j1.String(), j2.String()) case nil: require.True(t, d.IsNull()) @@ -257,10 +256,10 @@ func TestJSONMergePreserve(t *testing.T) { switch x := tt.Expected.(type) { case string: - j1, err := json.ParseBinaryFromString(x) + j1, err := types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() - cmp := json.CompareBinary(j1, j2) + cmp := types.CompareBinaryJSON(j1, j2) require.Zerof(t, cmp, "got %v expect %v", j1.String(), j2.String()) case nil: require.True(t, d.IsNull()) @@ -285,10 +284,10 @@ func TestJSONArray(t *testing.T) { d, err := evalBuiltinFunc(f, chunk.Row{}) require.NoError(t, err) - j1, err := json.ParseBinaryFromString(tt.Expected) + j1, err := types.ParseBinaryJSONFromString(tt.Expected) require.NoError(t, err) j2 := d.GetMysqlJSON() - cmp := json.CompareBinary(j1, j2) + cmp := types.CompareBinaryJSON(j1, j2) require.Equal(t, 0, cmp) } } @@ -322,12 +321,12 @@ func TestJSONObject(t *testing.T) { require.NoError(t, err) switch x := tt.Expected.(type) { case string: - var j1 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() var cmp int - cmp = json.CompareBinary(j1, j2) + cmp = types.CompareBinaryJSON(j1, j2) require.Equal(t, 0, cmp) } continue @@ -373,12 +372,12 @@ func TestJSONRemove(t *testing.T) { require.NoError(t, err) switch x := tt.Expected.(type) { case string: - var j1 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() var cmp int - cmp = json.CompareBinary(j1, j2) + cmp = types.CompareBinaryJSON(j1, j2) require.Zerof(t, cmp, "got %v expect %v", j2.Value, j1.Value) } } else { @@ -424,16 +423,16 @@ func TestJSONContains(t *testing.T) { {[]interface{}{`[{"a":1,"b":2}]`, `{"a":1}`}, 1, nil}, {[]interface{}{`[{"a":{"a":1},"b":2}]`, `{"a":1}`}, 0, nil}, // Tests path expression contains any asterisk - {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.*"}, nil, json.ErrInvalidJSONPathWildcard}, - {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$[*]"}, nil, json.ErrInvalidJSONPathWildcard}, - {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$**.a"}, nil, json.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.*"}, nil, types.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$[*]"}, nil, types.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$**.a"}, nil, types.ErrInvalidJSONPathWildcard}, // Tests path expression does not identify a section of the target document {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.c"}, nil, nil}, {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[3]"}, nil, nil}, {[]interface{}{`{"a": [1, 2, {"aa": "xx"}]}`, `1`, "$.a[2].b"}, nil, nil}, // For issue 9957: test 'argument 1 and 2 as valid json object' - {[]interface{}{`[1,2,[1,3]]`, `a:1`}, 1, json.ErrInvalidJSONText}, - {[]interface{}{`a:1`, `1`}, 1, json.ErrInvalidJSONText}, + {[]interface{}{`[1,2,[1,3]]`, `a:1`}, 1, types.ErrInvalidJSONText}, + {[]interface{}{`a:1`, `1`}, 1, types.ErrInvalidJSONText}, } for _, tt := range tbl { args := types.MakeDatums(tt.input...) @@ -463,7 +462,7 @@ func TestJSONContains(t *testing.T) { } for _, cs := range cases { _, err := fc.getFunction(ctx, datumsToConstants(types.MakeDatums(cs.arg1, cs.arg2))) - require.True(t, json.ErrInvalidJSONData.Equal(err)) + require.True(t, types.ErrInvalidJSONData.Equal(err)) } } @@ -478,29 +477,29 @@ func TestJSONContainsPath(t *testing.T) { success bool }{ // Tests nil arguments - {[]interface{}{nil, json.ContainsPathOne, "$.c"}, nil, true}, - {[]interface{}{nil, json.ContainsPathAll, "$.c"}, nil, true}, + {[]interface{}{nil, types.JSONContainsPathOne, "$.c"}, nil, true}, + {[]interface{}{nil, types.JSONContainsPathAll, "$.c"}, nil, true}, {[]interface{}{jsonString, nil, "$.a[3]"}, nil, true}, - {[]interface{}{jsonString, json.ContainsPathOne, nil}, nil, true}, - {[]interface{}{jsonString, json.ContainsPathAll, nil}, nil, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, nil}, nil, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, nil}, nil, true}, // Tests with one path expression - {[]interface{}{jsonString, json.ContainsPathOne, "$.c.d"}, 1, true}, - {[]interface{}{jsonString, json.ContainsPathOne, "$.a.d"}, 0, true}, - {[]interface{}{jsonString, json.ContainsPathAll, "$.c.d"}, 1, true}, - {[]interface{}{jsonString, json.ContainsPathAll, "$.a.d"}, 0, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, "$.c.d"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, "$.a.d"}, 0, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, "$.c.d"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, "$.a.d"}, 0, true}, // Tests with multiple path expression - {[]interface{}{jsonString, json.ContainsPathOne, "$.a", "$.e"}, 1, true}, - {[]interface{}{jsonString, json.ContainsPathOne, "$.a", "$.c"}, 1, true}, - {[]interface{}{jsonString, json.ContainsPathAll, "$.a", "$.e"}, 0, true}, - {[]interface{}{jsonString, json.ContainsPathAll, "$.a", "$.c"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, "$.a", "$.e"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, "$.a", "$.c"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, "$.a", "$.e"}, 0, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, "$.a", "$.c"}, 1, true}, // Tests path expression contains any asterisk - {[]interface{}{jsonString, json.ContainsPathOne, "$.*"}, 1, true}, - {[]interface{}{jsonString, json.ContainsPathOne, "$[*]"}, 0, true}, - {[]interface{}{jsonString, json.ContainsPathAll, "$.*"}, 1, true}, - {[]interface{}{jsonString, json.ContainsPathAll, "$[*]"}, 0, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, "$.*"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathOne, "$[*]"}, 0, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, "$.*"}, 1, true}, + {[]interface{}{jsonString, types.JSONContainsPathAll, "$[*]"}, 0, true}, // Tests invalid json document - {[]interface{}{invalidJSON, json.ContainsPathOne, "$.a"}, nil, false}, - {[]interface{}{invalidJSON, json.ContainsPathAll, "$.a"}, nil, false}, + {[]interface{}{invalidJSON, types.JSONContainsPathOne, "$.a"}, nil, false}, + {[]interface{}{invalidJSON, types.JSONContainsPathAll, "$.a"}, nil, false}, // Tests compatible contains path {[]interface{}{jsonString, "ONE", "$.c.d"}, 1, true}, {[]interface{}{jsonString, "ALL", "$.c.d"}, 1, true}, @@ -653,12 +652,12 @@ func TestJSONKeys(t *testing.T) { require.NoError(t, err) switch x := tt.expected.(type) { case string: - var j1 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 := d.GetMysqlJSON() var cmp int - cmp = json.CompareBinary(j1, j2) + cmp = types.CompareBinaryJSON(j1, j2) require.Equal(t, 0, cmp) case nil: require.True(t, d.IsNull()) @@ -730,7 +729,7 @@ func TestJSONDepth(t *testing.T) { func TestJSONArrayAppend(t *testing.T) { ctx := createContext(t) - sampleJSON, err := json.ParseBinaryFromString(`{"b": 2}`) + sampleJSON, err := types.ParseBinaryJSONFromString(`{"b": 2}`) require.NoError(t, err) fc := funcs[ast.JSONArrayAppend] tbl := []struct { @@ -752,14 +751,14 @@ func TestJSONArrayAppend(t *testing.T) { {[]interface{}{`[]`, `$`, nil}, `[null]`, nil}, {[]interface{}{`{}`, `$`, nil}, `[{}, null]`, nil}, // Bad arguments. - {[]interface{}{`asdf`, `$`, nil}, nil, json.ErrInvalidJSONText}, - {[]interface{}{``, `$`, nil}, nil, json.ErrInvalidJSONText}, + {[]interface{}{`asdf`, `$`, nil}, nil, types.ErrInvalidJSONText}, + {[]interface{}{``, `$`, nil}, nil, types.ErrInvalidJSONText}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.d`}, nil, ErrIncorrectParameterCount}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.c`, `y`, `$.b`}, nil, ErrIncorrectParameterCount}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, nil, nil}, nil, nil}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, json.ErrInvalidJSONPath}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, json.ErrInvalidJSONPath}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, json.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, types.ErrInvalidJSONPath}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, types.ErrInvalidJSONPath}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, types.ErrInvalidJSONPathWildcard}, // Following tests come from MySQL doc. {[]interface{}{`["a", ["b", "c"], "d"]`, `$[1]`, 1}, `["a", ["b", "c", 1], "d"]`, nil}, {[]interface{}{`["a", ["b", "c"], "d"]`, `$[0]`, 2}, `[["a", 2], ["b", "c"], "d"]`, nil}, @@ -800,10 +799,10 @@ func TestJSONArrayAppend(t *testing.T) { continue } - j1, err := json.ParseBinaryFromString(tt.expected.(string)) + j1, err := types.ParseBinaryJSONFromString(tt.expected.(string)) require.NoError(t, err, comment) - require.Equal(t, 0, json.CompareBinary(j1, d.GetMysqlJSON()), comment) + require.Equal(t, 0, types.CompareBinaryJSON(j1, d.GetMysqlJSON()), comment) } } @@ -867,11 +866,11 @@ func TestJSONSearch(t *testing.T) { require.NoError(t, err) switch x := tt.expected.(type) { case string: - var j1, j2 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1, j2 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 = d.GetMysqlJSON() - cmp := json.CompareBinary(j1, j2) + cmp := types.CompareBinaryJSON(j1, j2) require.Equal(t, 0, cmp) case nil: require.True(t, d.IsNull()) @@ -904,16 +903,16 @@ func TestJSONArrayInsert(t *testing.T) { {[]interface{}{`[]`, `$[0]`, nil}, `[null]`, true, nil}, {[]interface{}{`{}`, `$[0]`, nil}, `{}`, true, nil}, // Bad arguments - {[]interface{}{`asdf`, `$`, nil}, nil, false, json.ErrInvalidJSONText}, - {[]interface{}{``, `$`, nil}, nil, false, json.ErrInvalidJSONText}, + {[]interface{}{`asdf`, `$`, nil}, nil, false, types.ErrInvalidJSONText}, + {[]interface{}{``, `$`, nil}, nil, false, types.ErrInvalidJSONText}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.d`}, nil, false, ErrIncorrectParameterCount}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.c`, `y`, `$.b`}, nil, false, ErrIncorrectParameterCount}, {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, nil, nil}, nil, true, nil}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, false, json.ErrInvalidJSONPath}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, false, json.ErrInvalidJSONPath}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, false, json.ErrInvalidJSONPathWildcard}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.b[0]`, nil, `$.a`, nil}, nil, false, json.ErrInvalidJSONPathArrayCell}, - {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.a`, nil}, nil, false, json.ErrInvalidJSONPathArrayCell}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `asdf`, nil}, nil, false, types.ErrInvalidJSONPath}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, 42, nil}, nil, false, types.ErrInvalidJSONPath}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.*`, nil}, nil, false, types.ErrInvalidJSONPathWildcard}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.b[0]`, nil, `$.a`, nil}, nil, false, types.ErrInvalidJSONPathArrayCell}, + {[]interface{}{`{"a": 1, "b": [2, 3], "c": 4}`, `$.a`, nil}, nil, false, types.ErrInvalidJSONPathArrayCell}, // Following tests come from MySQL doc. {[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[1]`, `x`}, `["a", "x", {"b": [1, 2]}, [3, 4]]`, true, nil}, {[]interface{}{`["a", {"b": [1, 2]}, [3, 4]]`, `$[100]`, `x`}, `["a", {"b": [1, 2]}, [3, 4], "x"]`, true, nil}, @@ -939,12 +938,12 @@ func TestJSONArrayInsert(t *testing.T) { require.NoError(t, err) switch x := tt.expected.(type) { case string: - var j1, j2 json.BinaryJSON - j1, err = json.ParseBinaryFromString(x) + var j1, j2 types.BinaryJSON + j1, err = types.ParseBinaryJSONFromString(x) require.NoError(t, err) j2 = d.GetMysqlJSON() var cmp int - cmp = json.CompareBinary(j1, j2) + cmp = types.CompareBinaryJSON(j1, j2) require.Equal(t, 0, cmp) case nil: require.True(t, d.IsNull()) @@ -1185,7 +1184,7 @@ func TestJSONMergePatch(t *testing.T) { if tt.expected == nil { require.True(t, d.IsNull()) } else { - j, e := json.ParseBinaryFromString(tt.expected.(string)) + j, e := types.ParseBinaryJSONFromString(tt.expected.(string)) require.NoError(t, e) require.Equal(t, j.String(), d.GetMysqlJSON().String()) } diff --git a/expression/builtin_json_vec.go b/expression/builtin_json_vec.go index d20c0dfe4705f..0e8ac6d6633f0 100644 --- a/expression/builtin_json_vec.go +++ b/expression/builtin_json_vec.go @@ -23,13 +23,13 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/sessionctx" - "github.com/pingcap/tidb/types/json" + "github.com/pingcap/tidb/types" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tipb/go-tipb" ) //revive:disable:defer -func vecJSONModify(ctx sessionctx.Context, args []Expression, bufAllocator columnBufferAllocator, input *chunk.Chunk, result *chunk.Column, mt json.ModifyType) error { +func vecJSONModify(ctx sessionctx.Context, args []Expression, bufAllocator columnBufferAllocator, input *chunk.Chunk, result *chunk.Column, mt types.JSONModifyType) error { nr := input.NumRows() jsonBuf, err := bufAllocator.get() if err != nil { @@ -68,16 +68,16 @@ func vecJSONModify(ctx sessionctx.Context, args []Expression, bufAllocator colum result.AppendNull() continue } - pathExprs := make([]json.PathExpression, 0, (len(args)-1)/2+1) - values := make([]json.BinaryJSON, 0, (len(args)-1)/2+1) - var pathExpr json.PathExpression + pathExprs := make([]types.JSONPathExpression, 0, (len(args)-1)/2+1) + values := make([]types.BinaryJSON, 0, (len(args)-1)/2+1) + var pathExpr types.JSONPathExpression isNull := false for j := 1; j < len(args); j += 2 { if strBufs[(j-1)/2].IsNull(i) { isNull = true break } - pathExpr, err = json.ParseJSONPathExpr(strBufs[(j-1)/2].GetString(i)) + pathExpr, err = types.ParseJSONPathExpr(strBufs[(j-1)/2].GetString(i)) if err != nil { return err } @@ -85,7 +85,7 @@ func vecJSONModify(ctx sessionctx.Context, args []Expression, bufAllocator colum } for j := 2; j < len(args); j += 2 { if valueBufs[j/2-1].IsNull(i) { - values = append(values, json.CreateBinary(nil)) + values = append(values, types.CreateBinaryJSON(nil)) } else { values = append(values, valueBufs[j/2-1].GetJSON(i)) } @@ -179,7 +179,7 @@ func (b *builtinJSONKeysSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colum } result.ReserveJSON(n) - var j json.BinaryJSON + var j types.BinaryJSON for i := 0; i < n; i++ { if buf.IsNull(i) { result.AppendNull() @@ -187,7 +187,7 @@ func (b *builtinJSONKeysSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colum } j = buf.GetJSON(i) - if j.TypeCode != json.TypeCodeObject { + if j.TypeCode != types.JSONTypeCodeObject { result.AppendNull() continue } @@ -201,7 +201,7 @@ func (b *builtinJSONInsertSig) vectorized() bool { } func (b *builtinJSONInsertSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error { - err := vecJSONModify(b.ctx, b.args, b.bufAllocator, input, result, json.ModifyInsert) + err := vecJSONModify(b.ctx, b.args, b.bufAllocator, input, result, types.JSONModifyInsert) return err } @@ -210,7 +210,7 @@ func (b *builtinJSONReplaceSig) vectorized() bool { } func (b *builtinJSONReplaceSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error { - err := vecJSONModify(b.ctx, b.args, b.bufAllocator, input, result, json.ModifyReplace) + err := vecJSONModify(b.ctx, b.args, b.bufAllocator, input, result, types.JSONModifyReplace) return err } @@ -235,7 +235,7 @@ func (b *builtinJSONArraySig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colu } for i := 0; i < nr; i++ { if j.IsNull(i) { - jsons[i] = append(jsons[i], json.CreateBinary(nil)) + jsons[i] = append(jsons[i], types.CreateBinaryJSON(nil)) } else { jsons[i] = append(jsons[i], j.GetJSON(i)) } @@ -243,7 +243,7 @@ func (b *builtinJSONArraySig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colu } result.ReserveJSON(nr) for i := 0; i < nr; i++ { - result.AppendJSON(json.CreateBinary(jsons[i])) + result.AppendJSON(types.CreateBinaryJSON(jsons[i])) } return nil } @@ -291,26 +291,26 @@ func (b *builtinJSONContainsSig) vecEvalInt(input *chunk.Chunk, result *chunk.Co result.MergeNulls(objCol, targetCol, pathCol) - var pathExpr json.PathExpression + var pathExpr types.JSONPathExpression for i := 0; i < nr; i++ { if result.IsNull(i) { continue } - pathExpr, err = json.ParseJSONPathExpr(pathCol.GetString(i)) + pathExpr, err = types.ParseJSONPathExpr(pathCol.GetString(i)) if err != nil { return err } if pathExpr.ContainsAnyAsterisk() { - return json.ErrInvalidJSONPathWildcard + return types.ErrInvalidJSONPathWildcard } - obj, exists := objCol.GetJSON(i).Extract([]json.PathExpression{pathExpr}) + obj, exists := objCol.GetJSON(i).Extract([]types.JSONPathExpression{pathExpr}) if !exists { result.SetNull(i, true) continue } - if json.ContainsBinary(obj, targetCol.GetJSON(i)) { + if types.ContainsBinaryJSON(obj, targetCol.GetJSON(i)) { resI64s[i] = 1 } else { resI64s[i] = 0 @@ -322,7 +322,7 @@ func (b *builtinJSONContainsSig) vecEvalInt(input *chunk.Chunk, result *chunk.Co if result.IsNull(i) { continue } - if json.ContainsBinary(objCol.GetJSON(i), targetCol.GetJSON(i)) { + if types.ContainsBinaryJSON(objCol.GetJSON(i), targetCol.GetJSON(i)) { resI64s[i] = 1 } else { resI64s[i] = 0 @@ -437,16 +437,16 @@ func (b *builtinJSONSearchSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Col return errIncorrectArgs.GenWithStackByArgs("ESCAPE") } } - var pathExprs []json.PathExpression + var pathExprs []types.JSONPathExpression if pathBufs != nil { - pathExprs = make([]json.PathExpression, 0, len(b.args)-4) + pathExprs = make([]types.JSONPathExpression, 0, len(b.args)-4) for j := 0; j < len(b.args)-4; j++ { if pathBufs[j].IsNull(i) { break } - pathExpr, err := json.ParseJSONPathExpr(pathBufs[j].GetString(i)) + pathExpr, err := types.ParseJSONPathExpr(pathBufs[j].GetString(i)) if err != nil { - return json.ErrInvalidJSONPath.GenWithStackByArgs(pathBufs[j].GetString(i)) + return types.ErrInvalidJSONPath.GenWithStackByArgs(pathBufs[j].GetString(i)) } pathExprs = append(pathExprs, pathExpr) } @@ -469,7 +469,7 @@ func (b *builtinJSONSetSig) vectorized() bool { } func (b *builtinJSONSetSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Column) error { - err := vecJSONModify(b.ctx, b.args, b.bufAllocator, input, result, json.ModifySet) + err := vecJSONModify(b.ctx, b.args, b.bufAllocator, input, result, types.JSONModifySet) return err } @@ -524,7 +524,7 @@ func (b *builtinJSONObjectSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Col valueCol := argBuffers[i] var key string - var value json.BinaryJSON + var value types.BinaryJSON for j := 0; j < nr; j++ { if keyCol.IsNull(j) { err := errors.New("JSON documents may not contain NULL member names") @@ -532,7 +532,7 @@ func (b *builtinJSONObjectSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Col } key = keyCol.GetString(j) if valueCol.IsNull(j) { - value = json.CreateBinary(nil) + value = types.CreateBinaryJSON(nil) } else { value = valueCol.GetJSON(j) } @@ -542,7 +542,7 @@ func (b *builtinJSONObjectSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Col } for i := 0; i < nr; i++ { - result.AppendJSON(json.CreateBinary(jsons[i])) + result.AppendJSON(types.CreateBinaryJSON(jsons[i])) } return nil } @@ -584,8 +584,8 @@ func (b *builtinJSONArrayInsertSig) vecEvalJSON(input *chunk.Chunk, result *chun } } } - var pathExpr json.PathExpression - var value json.BinaryJSON + var pathExpr types.JSONPathExpression + var value types.BinaryJSON result.ReserveJSON(nr) for i := 0; i < nr; i++ { if buf.IsNull(i) { @@ -600,15 +600,15 @@ func (b *builtinJSONArrayInsertSig) vecEvalJSON(input *chunk.Chunk, result *chun isnull = true break } - pathExpr, err = json.ParseJSONPathExpr(pathBufs[j].GetString(i)) + pathExpr, err = types.ParseJSONPathExpr(pathBufs[j].GetString(i)) if err != nil { - return json.ErrInvalidJSONPath.GenWithStackByArgs(pathBufs[j].GetString(i)) + return types.ErrInvalidJSONPath.GenWithStackByArgs(pathBufs[j].GetString(i)) } if pathExpr.ContainsAnyAsterisk() { - return json.ErrInvalidJSONPathWildcard.GenWithStackByArgs(pathBufs[j].GetString(i)) + return types.ErrInvalidJSONPathWildcard.GenWithStackByArgs(pathBufs[j].GetString(i)) } if valueBufs[j].IsNull(i) { - value = json.CreateBinary(nil) + value = types.CreateBinaryJSON(nil) } else { value = valueBufs[j].GetJSON(i) } @@ -656,22 +656,22 @@ func (b *builtinJSONKeys2ArgsSig) vecEvalJSON(input *chunk.Chunk, result *chunk. continue } - pathExpr, err := json.ParseJSONPathExpr(pathBuf.GetString(i)) + pathExpr, err := types.ParseJSONPathExpr(pathBuf.GetString(i)) if err != nil { return err } if pathExpr.ContainsAnyAsterisk() { - return json.ErrInvalidJSONPathWildcard + return types.ErrInvalidJSONPathWildcard } jsonItem := jsonBuf.GetJSON(i) - if jsonItem.TypeCode != json.TypeCodeObject { + if jsonItem.TypeCode != types.JSONTypeCodeObject { result.AppendNull() continue } - res, exists := jsonItem.Extract([]json.PathExpression{pathExpr}) - if !exists || res.TypeCode != json.TypeCodeObject { + res, exists := jsonItem.Extract([]types.JSONPathExpression{pathExpr}) + if !exists || res.TypeCode != types.JSONTypeCodeObject { result.AppendNull() continue } @@ -715,7 +715,7 @@ func (b *builtinJSONLengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.Colu } jsonItem := jsonBuf.GetJSON(i) - if jsonItem.TypeCode != json.TypeCodeObject && jsonItem.TypeCode != json.TypeCodeArray { + if jsonItem.TypeCode != types.JSONTypeCodeObject && jsonItem.TypeCode != types.JSONTypeCodeArray { resI64s[i] = 1 continue } @@ -725,20 +725,20 @@ func (b *builtinJSONLengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.Colu continue } - pathExpr, err := json.ParseJSONPathExpr(pathBuf.GetString(i)) + pathExpr, err := types.ParseJSONPathExpr(pathBuf.GetString(i)) if err != nil { return err } if pathExpr.ContainsAnyAsterisk() { - return json.ErrInvalidJSONPathWildcard + return types.ErrInvalidJSONPathWildcard } - obj, exists := jsonItem.Extract([]json.PathExpression{pathExpr}) + obj, exists := jsonItem.Extract([]types.JSONPathExpression{pathExpr}) if !exists { result.SetNull(i, true) continue } - if obj.TypeCode != json.TypeCodeObject && obj.TypeCode != json.TypeCodeArray { + if obj.TypeCode != types.JSONTypeCodeObject && obj.TypeCode != types.JSONTypeCodeArray { resI64s[i] = 1 continue } @@ -752,7 +752,7 @@ func (b *builtinJSONLengthSig) vecEvalInt(input *chunk.Chunk, result *chunk.Colu } jsonItem := jsonBuf.GetJSON(i) - if jsonItem.TypeCode != json.TypeCodeObject && jsonItem.TypeCode != json.TypeCodeArray { + if jsonItem.TypeCode != types.JSONTypeCodeObject && jsonItem.TypeCode != types.JSONTypeCodeArray { resI64s[i] = 1 continue } @@ -829,14 +829,14 @@ func (b *builtinJSONExtractSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Co } jsonItem := jsonBuf.GetJSON(i) - pathExprs := make([]json.PathExpression, len(pathBuffers)) + pathExprs := make([]types.JSONPathExpression, len(pathBuffers)) hasNullPath := false for k, pathBuf := range pathBuffers { if pathBuf.IsNull(i) { hasNullPath = true break } - if pathExprs[k], err = json.ParseJSONPathExpr(pathBuf.GetString(i)); err != nil { + if pathExprs[k], err = types.ParseJSONPathExpr(pathBuf.GetString(i)); err != nil { return err } } @@ -890,8 +890,8 @@ func (b *builtinJSONRemoveSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Col continue } - pathExprs := make([]json.PathExpression, 0, len(b.args)-1) - var pathExpr json.PathExpression + pathExprs := make([]types.JSONPathExpression, 0, len(b.args)-1) + var pathExpr types.JSONPathExpression isNull := false for j := 1; j < len(b.args); j++ { @@ -899,7 +899,7 @@ func (b *builtinJSONRemoveSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Col isNull = true break } - pathExpr, err = json.ParseJSONPathExpr(strBufs[j-1].GetString(i)) + pathExpr, err = types.ParseJSONPathExpr(strBufs[j-1].GetString(i)) if err != nil { return err } @@ -940,7 +940,7 @@ func (b *builtinJSONMergeSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colu } } - jsonValues := make([][]json.BinaryJSON, nr) + jsonValues := make([][]types.BinaryJSON, nr) for i := 0; i < nr; i++ { isNullFlag := false @@ -950,7 +950,7 @@ func (b *builtinJSONMergeSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colu if isNullFlag { jsonValues[i] = nil } else { - jsonValues[i] = make([]json.BinaryJSON, 0, len(b.args)) + jsonValues[i] = make([]types.BinaryJSON, 0, len(b.args)) } } for i := 0; i < len(b.args); i++ { @@ -968,7 +968,7 @@ func (b *builtinJSONMergeSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colu result.AppendNull() continue } - result.AppendJSON(json.MergeBinary(jsonValues[i])) + result.AppendJSON(types.MergeBinaryJSON(jsonValues[i])) } if b.pbCode == tipb.ScalarFuncSig_JsonMergeSig { @@ -1032,12 +1032,12 @@ func (b *builtinJSONContainsPathSig) vecEvalInt(input *chunk.Chunk, result *chun continue } containType := strings.ToLower(typeBuf.GetString(i)) - if containType != json.ContainsPathAll && containType != json.ContainsPathOne { - return json.ErrInvalidJSONContainsPathType + if containType != types.JSONContainsPathAll && containType != types.JSONContainsPathOne { + return types.ErrInvalidJSONContainsPathType } obj := jsonBuf.GetJSON(i) contains := int64(1) - var pathExpr json.PathExpression + var pathExpr types.JSONPathExpression for j := 0; j < len(pathBufs); j++ { if pathBufs[j].IsNull(i) { result.SetNull(i, true) @@ -1045,16 +1045,16 @@ func (b *builtinJSONContainsPathSig) vecEvalInt(input *chunk.Chunk, result *chun break } path := pathBufs[j].GetString(i) - if pathExpr, err = json.ParseJSONPathExpr(path); err != nil { + if pathExpr, err = types.ParseJSONPathExpr(path); err != nil { return err } - _, exists := obj.Extract([]json.PathExpression{pathExpr}) - if exists && containType == json.ContainsPathOne { + _, exists := obj.Extract([]types.JSONPathExpression{pathExpr}) + if exists && containType == types.JSONContainsPathOne { contains = 1 break - } else if !exists && containType == json.ContainsPathOne { + } else if !exists && containType == types.JSONContainsPathOne { contains = 0 - } else if !exists && containType == json.ContainsPathAll { + } else if !exists && containType == types.JSONContainsPathAll { contains = 0 break } @@ -1126,12 +1126,12 @@ func (b *builtinJSONArrayAppendSig) vecEvalJSON(input *chunk.Chunk, result *chun break } s := pathBufs[j].GetString(i) - v, vNull := json.BinaryJSON{}, valBufs[j].IsNull(i) + v, vNull := types.BinaryJSON{}, valBufs[j].IsNull(i) if !vNull { v = valBufs[j].GetJSON(i) } if vNull { - v = json.CreateBinary(nil) + v = types.CreateBinaryJSON(nil) } res, isNull, err = b.appendJSONArray(res, s, v) if err != nil { @@ -1173,9 +1173,9 @@ func (b *builtinJSONUnquoteSig) vecEvalString(input *chunk.Chunk, result *chunk. } str := buf.GetString(i) if len(str) >= 2 && str[0] == '"' && str[len(str)-1] == '"' && !goJSON.Valid([]byte(str)) { - return json.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.") + return types.ErrInvalidJSONText.GenWithStackByArgs("The document root must not be followed by other values.") } - str, err := json.UnquoteString(str) + str, err := types.UnquoteString(str) if err != nil { return err } @@ -1242,7 +1242,7 @@ func (b *builtinJSONMergePatchSig) vecEvalJSON(input *chunk.Chunk, result *chunk } result.ReserveJSON(nr) - jsonValue := make([]*json.BinaryJSON, 0, len(b.args)) + jsonValue := make([]*types.BinaryJSON, 0, len(b.args)) for i := 0; i < nr; i++ { jsonValue = jsonValue[:0] for j := 0; j < len(b.args); j++ { @@ -1254,7 +1254,7 @@ func (b *builtinJSONMergePatchSig) vecEvalJSON(input *chunk.Chunk, result *chunk } } - tmpJSON, e := json.MergePatchBinary(jsonValue) + tmpJSON, e := types.MergePatchBinaryJSON(jsonValue) if e != nil { return e } diff --git a/expression/builtin_miscellaneous.go b/expression/builtin_miscellaneous.go index dc39f66be5e23..c55d7e571dd12 100644 --- a/expression/builtin_miscellaneous.go +++ b/expression/builtin_miscellaneous.go @@ -32,7 +32,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/vitess" "github.com/pingcap/tipb/go-tipb" @@ -409,7 +408,7 @@ func (b *builtinJSONAnyValueSig) Clone() builtinFunc { // evalJSON evals a builtinJSONAnyValueSig. // See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value -func (b *builtinJSONAnyValueSig) evalJSON(row chunk.Row) (json.BinaryJSON, bool, error) { +func (b *builtinJSONAnyValueSig) evalJSON(row chunk.Row) (types.BinaryJSON, bool, error) { return b.args[0].EvalJSON(b.ctx, row) } @@ -1105,7 +1104,7 @@ func (b *builtinNameConstJSONSig) Clone() builtinFunc { return newSig } -func (b *builtinNameConstJSONSig) evalJSON(row chunk.Row) (json.BinaryJSON, bool, error) { +func (b *builtinNameConstJSONSig) evalJSON(row chunk.Row) (types.BinaryJSON, bool, error) { return b.args[1].EvalJSON(b.ctx, row) } diff --git a/expression/builtin_other.go b/expression/builtin_other.go index a956a180170a3..0f4bd85d45b43 100644 --- a/expression/builtin_other.go +++ b/expression/builtin_other.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/set" @@ -673,7 +672,7 @@ func (b *builtinInJSONSig) evalInt(row chunk.Row) (int64, bool, error) { hasNull = true continue } - result := json.CompareBinary(evaledArg, arg0) + result := types.CompareBinaryJSON(evaledArg, arg0) if result == 0 { return 1, false, nil } @@ -1389,18 +1388,18 @@ func (b *builtinValuesJSONSig) Clone() builtinFunc { // evalJSON evals a builtinValuesJSONSig. // See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_values -func (b *builtinValuesJSONSig) evalJSON(_ chunk.Row) (json.BinaryJSON, bool, error) { +func (b *builtinValuesJSONSig) evalJSON(_ chunk.Row) (types.BinaryJSON, bool, error) { row := b.ctx.GetSessionVars().CurrInsertValues if row.IsEmpty() { - return json.BinaryJSON{}, true, nil + return types.BinaryJSON{}, true, nil } if b.offset < row.Len() { if row.IsNull(b.offset) { - return json.BinaryJSON{}, true, nil + return types.BinaryJSON{}, true, nil } return row.GetJSON(b.offset), false, nil } - return json.BinaryJSON{}, true, errors.Errorf("Session current insert values len %d and column's offset %v don't match", row.Len(), b.offset) + return types.BinaryJSON{}, true, errors.Errorf("Session current insert values len %d and column's offset %v don't match", row.Len(), b.offset) } type bitCountFunctionClass struct { diff --git a/expression/builtin_other_test.go b/expression/builtin_other_test.go index 6d80ef0c9b42d..428329023f84a 100644 --- a/expression/builtin_other_test.go +++ b/expression/builtin_other_test.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/hack" @@ -264,10 +263,10 @@ func TestInFunc(t *testing.T) { duration2 := types.Duration{Duration: 12*time.Hour + 1*time.Minute} duration3 := types.Duration{Duration: 12*time.Hour + 1*time.Second} duration4 := types.Duration{Duration: 12 * time.Hour} - json1 := json.CreateBinary("123") - json2 := json.CreateBinary("123.1") - json3 := json.CreateBinary("123.2") - json4 := json.CreateBinary("123.3") + json1 := types.CreateBinaryJSON("123") + json2 := types.CreateBinaryJSON("123.1") + json3 := types.CreateBinaryJSON("123.2") + json4 := types.CreateBinaryJSON("123.3") testCases := []struct { args []interface{} res interface{} diff --git a/expression/builtin_other_vec_generated.go b/expression/builtin_other_vec_generated.go index 5d0a5b91e7bc1..0033e4f4baeb5 100644 --- a/expression/builtin_other_vec_generated.go +++ b/expression/builtin_other_vec_generated.go @@ -19,7 +19,6 @@ package expression import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" ) @@ -588,7 +587,7 @@ func (b *builtinInJSONSig) vecEvalInt(input *chunk.Chunk, result *chunk.Column) } arg0 := buf0.GetJSON(i) arg1 := buf1.GetJSON(i) - compareResult = json.CompareBinary(arg0, arg1) + compareResult = types.CompareBinaryJSON(arg0, arg1) if compareResult == 0 { result.SetNull(i, false) r64s[i] = 1 diff --git a/expression/builtin_other_vec_generated_test.go b/expression/builtin_other_vec_generated_test.go index fe5de1ea93d23..6b4e4dbd9ed71 100644 --- a/expression/builtin_other_vec_generated_test.go +++ b/expression/builtin_other_vec_generated_test.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" ) type inGener struct { @@ -63,7 +62,7 @@ func (g inGener) gen() interface{} { case types.ETDuration: return types.Duration{Duration: time.Duration(randNum)} case types.ETJson: - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) jsonStr := fmt.Sprintf("{\"key\":%v}", randNum) if err := j.UnmarshalJSON([]byte(jsonStr)); err != nil { panic(err) @@ -276,8 +275,8 @@ var vecBuiltinOtherGeneratedCases = map[string][]vecExprBenchCase{ }, constants: []*Constant{ nil, - {Value: types.NewJSONDatum(json.CreateBinary("aaaa")), RetType: types.NewFieldType(mysql.TypeJSON)}, - {Value: types.NewJSONDatum(json.CreateBinary("bbbb")), RetType: types.NewFieldType(mysql.TypeJSON)}, + {Value: types.NewJSONDatum(types.CreateBinaryJSON("aaaa")), RetType: types.NewFieldType(mysql.TypeJSON)}, + {Value: types.NewJSONDatum(types.CreateBinaryJSON("bbbb")), RetType: types.NewFieldType(mysql.TypeJSON)}, }, }, }, diff --git a/expression/builtin_vectorized_test.go b/expression/builtin_vectorized_test.go index e512dcc4d2f3c..38b3a945ebb15 100644 --- a/expression/builtin_vectorized_test.go +++ b/expression/builtin_vectorized_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -310,11 +309,11 @@ func (p *mockBuiltinDouble) vecEvalJSON(input *chunk.Chunk, result *chunk.Column result.ReserveString(input.NumRows()) for i := 0; i < input.NumRows(); i++ { j := buf.GetJSON(i) - path, err := json.ParseJSONPathExpr("$.key") + path, err := types.ParseJSONPathExpr("$.key") if err != nil { return err } - ret, ok := j.Extract([]json.PathExpression{path}) + ret, ok := j.Extract([]types.JSONPathExpression{path}) if !ok { return errors.Errorf("path not found") } @@ -385,24 +384,24 @@ func (p *mockBuiltinDouble) evalDuration(row chunk.Row) (types.Duration, bool, e return v, isNull, err } -func (p *mockBuiltinDouble) evalJSON(row chunk.Row) (json.BinaryJSON, bool, error) { +func (p *mockBuiltinDouble) evalJSON(row chunk.Row) (types.BinaryJSON, bool, error) { j, isNull, err := p.args[0].EvalJSON(p.ctx, row) if err != nil { - return json.BinaryJSON{}, false, err + return types.BinaryJSON{}, false, err } if isNull { - return json.BinaryJSON{}, true, nil + return types.BinaryJSON{}, true, nil } - path, err := json.ParseJSONPathExpr("$.key") + path, err := types.ParseJSONPathExpr("$.key") if err != nil { - return json.BinaryJSON{}, false, err + return types.BinaryJSON{}, false, err } - ret, ok := j.Extract([]json.PathExpression{path}) + ret, ok := j.Extract([]types.JSONPathExpression{path}) if !ok { - return json.BinaryJSON{}, true, err + return types.BinaryJSON{}, true, err } if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, 2*ret.GetInt64()))); err != nil { - return json.BinaryJSON{}, false, err + return types.BinaryJSON{}, false, err } return j, false, nil } @@ -455,7 +454,7 @@ func genMockRowDouble(eType types.EvalType, enableVec bool) (builtinFunc, *chunk case types.ETDuration: input.AppendDuration(0, types.Duration{Duration: time.Duration(i)}) case types.ETJson: - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) if err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"key":%v}`, i))); err != nil { return nil, nil, nil, err } @@ -519,9 +518,9 @@ func checkVecEval(t *testing.T, eType types.EvalType, sel []int, result *chunk.C } case types.ETJson: for i, j := range sel { - path, err := json.ParseJSONPathExpr("$.key") + path, err := types.ParseJSONPathExpr("$.key") require.NoError(t, err) - ret, ok := result.GetJSON(i).Extract([]json.PathExpression{path}) + ret, ok := result.GetJSON(i).Extract([]types.JSONPathExpression{path}) require.True(t, ok) require.Equal(t, int64(j*2), ret.GetInt64()) } diff --git a/expression/column.go b/expression/column.go index e37f0deb47054..dd2fc9b3c533b 100644 --- a/expression/column.go +++ b/expression/column.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "golang.org/x/exp/slices" @@ -141,9 +140,9 @@ func (col *CorrelatedColumn) EvalDuration(ctx sessionctx.Context, row chunk.Row) } // EvalJSON returns JSON representation of CorrelatedColumn. -func (col *CorrelatedColumn) EvalJSON(ctx sessionctx.Context, row chunk.Row) (json.BinaryJSON, bool, error) { +func (col *CorrelatedColumn) EvalJSON(ctx sessionctx.Context, row chunk.Row) (types.BinaryJSON, bool, error) { if col.Data.IsNull() { - return json.BinaryJSON{}, true, nil + return types.BinaryJSON{}, true, nil } return col.Data.GetMysqlJSON(), false, nil } @@ -451,9 +450,9 @@ func (col *Column) EvalDuration(ctx sessionctx.Context, row chunk.Row) (types.Du } // EvalJSON returns JSON representation of Column. -func (col *Column) EvalJSON(ctx sessionctx.Context, row chunk.Row) (json.BinaryJSON, bool, error) { +func (col *Column) EvalJSON(ctx sessionctx.Context, row chunk.Row) (types.BinaryJSON, bool, error) { if row.IsNull(col.Index) { - return json.BinaryJSON{}, true, nil + return types.BinaryJSON{}, true, nil } return row.GetJSON(col.Index), false, nil } diff --git a/expression/constant.go b/expression/constant.go index ec82ad521364a..48859f6408e05 100644 --- a/expression/constant.go +++ b/expression/constant.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" @@ -331,16 +330,16 @@ func (c *Constant) EvalDuration(ctx sessionctx.Context, row chunk.Row) (val type } // EvalJSON returns JSON representation of Constant. -func (c *Constant) EvalJSON(ctx sessionctx.Context, row chunk.Row) (json.BinaryJSON, bool, error) { +func (c *Constant) EvalJSON(ctx sessionctx.Context, row chunk.Row) (types.BinaryJSON, bool, error) { dt, lazy, err := c.getLazyDatum(row) if err != nil { - return json.BinaryJSON{}, false, err + return types.BinaryJSON{}, false, err } if !lazy { dt = c.Value } if c.GetType().GetType() == mysql.TypeNull || dt.IsNull() { - return json.BinaryJSON{}, true, nil + return types.BinaryJSON{}, true, nil } return dt.GetMysqlJSON(), false, nil } diff --git a/expression/constant_test.go b/expression/constant_test.go index e118fdd6a125a..82c3d8e489fdf 100644 --- a/expression/constant_test.go +++ b/expression/constant_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -414,9 +413,9 @@ func TestDeferredExprNotNull(t *testing.T) { xDur, _, _ := cst.EvalDuration(ctx, chunk.Row{}) require.Equal(t, 0, xDur.Compare(m.i.(types.Duration))) - m.i = json.BinaryJSON{} + m.i = types.BinaryJSON{} xJsn, _, _ := cst.EvalJSON(ctx, chunk.Row{}) - require.Equal(t, xJsn.String(), m.i.(json.BinaryJSON).String()) + require.Equal(t, xJsn.String(), m.i.(types.BinaryJSON).String()) cln := cst.Clone().(*Constant) require.Equal(t, cst.DeferredExpr, cln.DeferredExpr) diff --git a/expression/distsql_builtin_test.go b/expression/distsql_builtin_test.go index be75242690440..c17f5f78c3bf7 100644 --- a/expression/distsql_builtin_test.go +++ b/expression/distsql_builtin_test.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" @@ -920,7 +919,7 @@ func datumExpr(t *testing.T, d types.Datum) *tipb.Expr { } func newJSONDatum(t *testing.T, s string) (d types.Datum) { - j, err := json.ParseBinaryFromString(s) + j, err := types.ParseBinaryJSONFromString(s) require.NoError(t, err) d.SetMysqlJSON(j) return d diff --git a/expression/expression.go b/expression/expression.go index 05a5b0a09d294..573d0c73a5698 100644 --- a/expression/expression.go +++ b/expression/expression.go @@ -34,7 +34,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/generatedexpr" "github.com/pingcap/tidb/util/logutil" @@ -126,7 +125,7 @@ type Expression interface { EvalDuration(ctx sessionctx.Context, row chunk.Row) (val types.Duration, isNull bool, err error) // EvalJSON returns the JSON representation of expression. - EvalJSON(ctx sessionctx.Context, row chunk.Row) (val json.BinaryJSON, isNull bool, err error) + EvalJSON(ctx sessionctx.Context, row chunk.Row) (val types.BinaryJSON, isNull bool, err error) // GetType gets the type that the expression returns. GetType() *types.FieldType diff --git a/expression/generator/compare_vec.go b/expression/generator/compare_vec.go index 42004f3d5006c..423a0949deea5 100644 --- a/expression/generator/compare_vec.go +++ b/expression/generator/compare_vec.go @@ -52,7 +52,6 @@ const newLine = "\n" const builtinCompareImports = `import ( "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" ) ` @@ -89,7 +88,7 @@ func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEvalInt(in continue } {{- if eq .type.ETName "Json" }} - val := json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) + val := types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) {{- else if eq .type.ETName "Real" }} val := types.CompareFloat64(arg0[i], arg1[i]) {{- else if eq .type.ETName "String" }} @@ -146,7 +145,7 @@ func (b *builtin{{ .compare.CompareName }}{{ .type.TypeName }}Sig) vecEvalInt(in case isNull0 != isNull1: i64s[i] = 0 {{- if eq .type.ETName "Json" }} - case json.CompareBinary(buf0.GetJSON(i), buf1.GetJSON(i)) == 0: + case types.CompareBinaryJSON(buf0.GetJSON(i), buf1.GetJSON(i)) == 0: {{- else if eq .type.ETName "Real" }} case types.CompareFloat64(arg0[i], arg1[i]) == 0: {{- else if eq .type.ETName "String" }} diff --git a/expression/generator/other_vec.go b/expression/generator/other_vec.go index 55b446f49fbc2..6a120b4c810ea 100644 --- a/expression/generator/other_vec.go +++ b/expression/generator/other_vec.go @@ -52,7 +52,6 @@ const newLine = "\n" const builtinOtherImports = `import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" ) @@ -109,7 +108,7 @@ var builtinInTmpl = template.Must(template.New("builtinInTmpl").Parse(` {{- else if eq .Input.TypeName "Duration" -}} compareResult = types.CompareDuration(arg0, arg1) {{- else if eq .Input.TypeName "JSON" -}} - compareResult = json.CompareBinary(arg0, arg1) + compareResult = types.CompareBinaryJSON(arg0, arg1) {{- else if eq .Input.TypeName "String" -}} compareResult = types.CompareString(arg0, arg1, b.collation) {{- else -}} @@ -286,7 +285,6 @@ import ( "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" ) type inGener struct { @@ -323,7 +321,7 @@ func (g inGener) gen() interface{} { case types.ETDuration: return types.Duration{ Duration: time.Duration(randNum) } case types.ETJson: - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) jsonStr := fmt.Sprintf("{\"key\":%v}", randNum) if err := j.UnmarshalJSON([]byte(jsonStr)); err != nil { panic(err) @@ -380,8 +378,8 @@ var vecBuiltin{{ .Category }}GeneratedCases = map[string][]vecExprBenchCase { {Value: types.NewTimeDatum(dateTimeFromString("2019-01-01")), RetType: types.NewFieldType(mysql.TypeDatetime)}, {{- end }} {{- if eq .Input.ETName "Json" }} - {Value: types.NewJSONDatum(json.CreateBinary("aaaa")), RetType: types.NewFieldType(mysql.TypeJSON)}, - {Value: types.NewJSONDatum(json.CreateBinary("bbbb")), RetType: types.NewFieldType(mysql.TypeJSON)}, + {Value: types.NewJSONDatum(types.CreateBinaryJSON("aaaa")), RetType: types.NewFieldType(mysql.TypeJSON)}, + {Value: types.NewJSONDatum(types.CreateBinaryJSON("bbbb")), RetType: types.NewFieldType(mysql.TypeJSON)}, {{- end }} {{- if eq .Input.ETName "Duration" }} {Value: types.NewDurationDatum(types.Duration{Duration: time.Duration(1000)}), RetType: types.NewFieldType(mysql.TypeDuration)}, diff --git a/expression/integration_test.go b/expression/integration_test.go index 9245855474a37..eb0e5b7fe58ef 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -43,7 +43,6 @@ import ( "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/testkit" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/sem" @@ -6297,7 +6296,7 @@ func TestBuiltinFuncJSONMergePatch_InColumn(t *testing.T) { if tt.expected == nil { result.Check(testkit.Rows("")) } else { - j, e := json.ParseBinaryFromString(tt.expected.(string)) + j, e := types.ParseBinaryJSONFromString(tt.expected.(string)) require.NoError(t, e) result.Check(testkit.Rows(j.String())) } @@ -6417,7 +6416,7 @@ func TestBuiltinFuncJSONMergePatch_InExpression(t *testing.T) { if tt.expected == nil { result.Check(testkit.Rows("")) } else { - j, e := json.ParseBinaryFromString(tt.expected.(string)) + j, e := types.ParseBinaryJSONFromString(tt.expected.(string)) require.NoError(t, e) result.Check(testkit.Rows(j.String())) } diff --git a/expression/scalar_function.go b/expression/scalar_function.go index 4d489d43c1656..f59f07d480f41 100644 --- a/expression/scalar_function.go +++ b/expression/scalar_function.go @@ -27,7 +27,6 @@ import ( "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/hack" @@ -425,7 +424,7 @@ func (sf *ScalarFunction) EvalDuration(ctx sessionctx.Context, row chunk.Row) (t } // EvalJSON implements Expression interface. -func (sf *ScalarFunction) EvalJSON(ctx sessionctx.Context, row chunk.Row) (json.BinaryJSON, bool, error) { +func (sf *ScalarFunction) EvalJSON(ctx sessionctx.Context, row chunk.Row) (types.BinaryJSON, bool, error) { return sf.Function.evalJSON(row) } diff --git a/expression/util_test.go b/expression/util_test.go index 5aa35d81ec4a9..b041cffee32c4 100644 --- a/expression/util_test.go +++ b/expression/util_test.go @@ -25,7 +25,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/mock" @@ -561,11 +560,11 @@ func (m *MockExpr) EvalDuration(ctx sessionctx.Context, row chunk.Row) (val type } return types.Duration{}, m.i == nil, m.err } -func (m *MockExpr) EvalJSON(ctx sessionctx.Context, row chunk.Row) (val json.BinaryJSON, isNull bool, err error) { - if x, ok := m.i.(json.BinaryJSON); ok { +func (m *MockExpr) EvalJSON(ctx sessionctx.Context, row chunk.Row) (val types.BinaryJSON, isNull bool, err error) { + if x, ok := m.i.(types.BinaryJSON); ok { return x, false, m.err } - return json.BinaryJSON{}, m.i == nil, m.err + return types.BinaryJSON{}, m.i == nil, m.err } func (m *MockExpr) ReverseEval(sc *stmtctx.StatementContext, res types.Datum, rType types.RoundingType) (val types.Datum, err error) { return types.Datum{}, m.err diff --git a/server/BUILD.bazel b/server/BUILD.bazel index 8c6cc78c9d5c1..9894c3e2189b4 100644 --- a/server/BUILD.bazel +++ b/server/BUILD.bazel @@ -176,7 +176,6 @@ go_test( "//testkit/external", "//testkit/testsetup", "//types", - "//types/json", "//util", "//util/arena", "//util/chunk", diff --git a/server/util_test.go b/server/util_test.go index 7a5040b43cd3c..a335d88c4ef42 100644 --- a/server/util_test.go +++ b/server/util_test.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -235,7 +234,7 @@ func TestDumpTextValue(t *testing.T) { require.Equal(t, "sname", mustDecodeStr(t, bs)) js := types.Datum{} - binaryJSON, err := json.ParseBinaryFromString(`{"a": 1, "b": 2}`) + binaryJSON, err := types.ParseBinaryJSONFromString(`{"a": 1, "b": 2}`) require.NoError(t, err) js.SetMysqlJSON(binaryJSON) columns[0].Type = mysql.TypeJSON diff --git a/statistics/BUILD.bazel b/statistics/BUILD.bazel index 10fce2b2150dd..654c1a56cb602 100644 --- a/statistics/BUILD.bazel +++ b/statistics/BUILD.bazel @@ -99,7 +99,6 @@ go_test( "//testkit/testmain", "//testkit/testsetup", "//types", - "//types/json", "//util/chunk", "//util/codec", "//util/collate", diff --git a/statistics/statistics_test.go b/statistics/statistics_test.go index a72f6edff9d12..ee6d871580af3 100644 --- a/statistics/statistics_test.go +++ b/statistics/statistics_test.go @@ -27,7 +27,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" @@ -646,7 +645,7 @@ func SubTestBuild() func(*testing.T) { require.Equal(t, 99999, int(count)) datum := types.Datum{} - datum.SetMysqlJSON(json.BinaryJSON{TypeCode: json.TypeCodeLiteral}) + datum.SetMysqlJSON(types.BinaryJSON{TypeCode: types.JSONTypeCodeLiteral}) item := &SampleItem{Value: datum} collector = &SampleCollector{ Count: 1, diff --git a/table/BUILD.bazel b/table/BUILD.bazel index de9150fad4fdf..6293b37b02dd9 100644 --- a/table/BUILD.bazel +++ b/table/BUILD.bazel @@ -23,7 +23,6 @@ go_library( "//sessionctx", "//sessionctx/stmtctx", "//types", - "//types/json", "//util/dbterror", "//util/hack", "//util/logutil", @@ -58,7 +57,6 @@ go_test( "//sessionctx/stmtctx", "//testkit/testsetup", "//types", - "//types/json", "//util/collate", "//util/mock", "@com_github_stretchr_testify//require", diff --git a/table/column.go b/table/column.go index a76184d3a7a80..b814c8927a472 100644 --- a/table/column.go +++ b/table/column.go @@ -35,7 +35,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/logutil" "github.com/pingcap/tidb/util/timeutil" @@ -658,7 +657,7 @@ func GetZeroValue(col *model.ColumnInfo) types.Datum { case mysql.TypeEnum: d.SetMysqlEnum(types.Enum{}, col.GetCollate()) case mysql.TypeJSON: - d.SetMysqlJSON(json.CreateBinary(nil)) + d.SetMysqlJSON(types.CreateBinaryJSON(nil)) } return d } diff --git a/table/column_test.go b/table/column_test.go index 7deef53d9c29a..f9875deaf4111 100644 --- a/table/column_test.go +++ b/table/column_test.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/mock" "github.com/stretchr/testify/require" @@ -244,7 +243,7 @@ func TestGetZeroValue(t *testing.T) { }, { types.NewFieldType(mysql.TypeJSON), - types.NewDatum(json.CreateBinary(nil)), + types.NewDatum(types.CreateBinaryJSON(nil)), }, } sc := new(stmtctx.StatementContext) diff --git a/types/BUILD.bazel b/types/BUILD.bazel index 670b1df39612f..cf18e86624d08 100644 --- a/types/BUILD.bazel +++ b/types/BUILD.bazel @@ -1,5 +1,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +package_group( + name = "types_friend", + packages = [ + "-//config/...", + "//...", + ], +) + go_library( name = "types", srcs = [ @@ -19,13 +27,19 @@ go_library( "field_type_builder.go", "fsp.go", "helper.go", + "json_binary.go", + "json_binary_functions.go", + "json_constants.go", + "json_path_expr.go", "mydecimal.go", "overflow.go", "set.go", "time.go", ], importpath = "github.com/pingcap/tidb/types", - visibility = ["//visibility:public"], + visibility = [ + ":types_friend", + ], deps = [ "//errno", "//parser/ast", @@ -36,7 +50,6 @@ go_library( "//parser/terror", "//parser/types", "//sessionctx/stmtctx", - "//types/json", "//util/collate", "//util/dbterror", "//util/hack", @@ -69,6 +82,9 @@ go_test( "format_test.go", "fsp_test.go", "helper_test.go", + "json_binary_functions_test.go", + "json_binary_test.go", + "json_path_expr_test.go", "main_test.go", "mydecimal_benchmark_test.go", "mydecimal_test.go", @@ -86,7 +102,6 @@ go_test( "//sessionctx/stmtctx", "//testkit", "//testkit/testsetup", - "//types/json", "//util/collate", "//util/hack", "//util/mock", diff --git a/types/convert.go b/types/convert.go index f97eed3d24178..9ae78162586cf 100644 --- a/types/convert.go +++ b/types/convert.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/hack" ) @@ -548,25 +547,25 @@ func StrToFloat(sc *stmtctx.StatementContext, str string, isFuncCast bool) (floa } // ConvertJSONToInt64 casts JSON into int64. -func ConvertJSONToInt64(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned bool) (int64, error) { +func ConvertJSONToInt64(sc *stmtctx.StatementContext, j BinaryJSON, unsigned bool) (int64, error) { return ConvertJSONToInt(sc, j, unsigned, mysql.TypeLonglong) } // ConvertJSONToInt casts JSON into int by type. -func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned bool, tp byte) (int64, error) { +func ConvertJSONToInt(sc *stmtctx.StatementContext, j BinaryJSON, unsigned bool, tp byte) (int64, error) { switch j.TypeCode { - case json.TypeCodeObject, json.TypeCodeArray, json.TypeCodeOpaque: + case JSONTypeCodeObject, JSONTypeCodeArray, JSONTypeCodeOpaque: return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("INTEGER", j.String())) - case json.TypeCodeLiteral: + case JSONTypeCodeLiteral: switch j.Value[0] { - case json.LiteralFalse: + case JSONLiteralFalse: return 0, nil - case json.LiteralNil: + case JSONLiteralNil: return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("INTEGER", j.String())) default: return 1, nil } - case json.TypeCodeInt64: + case JSONTypeCodeInt64: i := j.GetInt64() if unsigned { uBound := IntergerUnsignedUpperBound(tp) @@ -578,7 +577,7 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned uBound := IntergerSignedUpperBound(tp) i, err := ConvertIntToInt(i, lBound, uBound, tp) return i, sc.HandleOverflow(err, err) - case json.TypeCodeUint64: + case JSONTypeCodeUint64: u := j.GetUint64() if unsigned { uBound := IntergerUnsignedUpperBound(tp) @@ -589,7 +588,7 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned uBound := IntergerSignedUpperBound(tp) i, err := ConvertUintToInt(u, uBound, tp) return i, sc.HandleOverflow(err, err) - case json.TypeCodeFloat64: + case JSONTypeCodeFloat64: f := j.GetFloat64() if !unsigned { lBound := IntergerSignedLowerBound(tp) @@ -600,7 +599,7 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned bound := IntergerUnsignedUpperBound(tp) u, err := ConvertFloatToUint(sc, f, bound, tp) return int64(u), sc.HandleOverflow(err, err) - case json.TypeCodeString: + case JSONTypeCodeString: str := string(hack.String(j.GetString())) if !unsigned { r, e := StrToInt(sc, str, false) @@ -613,26 +612,26 @@ func ConvertJSONToInt(sc *stmtctx.StatementContext, j json.BinaryJSON, unsigned } // ConvertJSONToFloat casts JSON into float64. -func ConvertJSONToFloat(sc *stmtctx.StatementContext, j json.BinaryJSON) (float64, error) { +func ConvertJSONToFloat(sc *stmtctx.StatementContext, j BinaryJSON) (float64, error) { switch j.TypeCode { - case json.TypeCodeObject, json.TypeCodeArray, json.TypeCodeOpaque: + case JSONTypeCodeObject, JSONTypeCodeArray, JSONTypeCodeOpaque: return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("FLOAT", j.String())) - case json.TypeCodeLiteral: + case JSONTypeCodeLiteral: switch j.Value[0] { - case json.LiteralFalse: + case JSONLiteralFalse: return 0, nil - case json.LiteralNil: + case JSONLiteralNil: return 0, sc.HandleTruncate(ErrTruncatedWrongVal.GenWithStackByArgs("FLOAT", j.String())) default: return 1, nil } - case json.TypeCodeInt64: + case JSONTypeCodeInt64: return float64(j.GetInt64()), nil - case json.TypeCodeUint64: + case JSONTypeCodeUint64: return float64(j.GetUint64()), nil - case json.TypeCodeFloat64: + case JSONTypeCodeFloat64: return j.GetFloat64(), nil - case json.TypeCodeString: + case JSONTypeCodeString: str := string(hack.String(j.GetString())) return StrToFloat(sc, str, false) } @@ -640,28 +639,28 @@ func ConvertJSONToFloat(sc *stmtctx.StatementContext, j json.BinaryJSON) (float6 } // ConvertJSONToDecimal casts JSON into decimal. -func ConvertJSONToDecimal(sc *stmtctx.StatementContext, j json.BinaryJSON) (*MyDecimal, error) { +func ConvertJSONToDecimal(sc *stmtctx.StatementContext, j BinaryJSON) (*MyDecimal, error) { var err error = nil res := new(MyDecimal) switch j.TypeCode { - case json.TypeCodeObject, json.TypeCodeArray, json.TypeCodeOpaque: + case JSONTypeCodeObject, JSONTypeCodeArray, JSONTypeCodeOpaque: err = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", j.String()) - case json.TypeCodeLiteral: + case JSONTypeCodeLiteral: switch j.Value[0] { - case json.LiteralFalse: + case JSONLiteralFalse: res = res.FromInt(0) - case json.LiteralNil: + case JSONLiteralNil: err = ErrTruncatedWrongVal.GenWithStackByArgs("DECIMAL", j.String()) default: res = res.FromInt(1) } - case json.TypeCodeInt64: + case JSONTypeCodeInt64: res = res.FromInt(j.GetInt64()) - case json.TypeCodeUint64: + case JSONTypeCodeUint64: res = res.FromUint(j.GetUint64()) - case json.TypeCodeFloat64: + case JSONTypeCodeFloat64: err = res.FromFloat64(j.GetFloat64()) - case json.TypeCodeString: + case JSONTypeCodeString: err = res.FromString(j.GetString()) } err = sc.HandleTruncate(err) diff --git a/types/convert_test.go b/types/convert_test.go index be715a61141e6..a36ab16f4b5ed 100644 --- a/types/convert_test.go +++ b/types/convert_test.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx/stmtctx" - "github.com/pingcap/tidb/types/json" "github.com/stretchr/testify/require" ) @@ -276,20 +275,20 @@ func TestConvertType(t *testing.T) { v, err = Convert(ZeroDuration, ft) require.NoError(t, err) require.Equal(t, int64(0), v) - bj1, err := json.ParseBinaryFromString("99") + bj1, err := ParseBinaryJSONFromString("99") require.NoError(t, err) v, err = Convert(bj1, ft) require.NoError(t, err) require.Equal(t, int64(1999), v) - bj2, err := json.ParseBinaryFromString("-1") + bj2, err := ParseBinaryJSONFromString("-1") require.NoError(t, err) _, err = Convert(bj2, ft) require.Error(t, err) - bj3, err := json.ParseBinaryFromString("{\"key\": 99}") + bj3, err := ParseBinaryJSONFromString("{\"key\": 99}") require.NoError(t, err) _, err = Convert(bj3, ft) require.Error(t, err) - bj4, err := json.ParseBinaryFromString("[99, 0, 1]") + bj4, err := ParseBinaryJSONFromString("[99, 0, 1]") require.NoError(t, err) _, err = Convert(bj4, ft) require.Error(t, err) @@ -1077,7 +1076,7 @@ func TestConvertJSONToInt(t *testing.T) { {in: `"1234"`, out: 1234}, } for _, tt := range tests { - j, err := json.ParseBinaryFromString(tt.in) + j, err := ParseBinaryJSONFromString(tt.in) require.NoError(t, err) casted, err := ConvertJSONToInt64(new(stmtctx.StatementContext), j, false) @@ -1094,24 +1093,24 @@ func TestConvertJSONToFloat(t *testing.T) { var tests = []struct { in interface{} out float64 - ty json.TypeCode + ty JSONTypeCode err bool }{ - {in: make(map[string]interface{}), ty: json.TypeCodeObject, err: true}, - {in: make([]interface{}, 0), ty: json.TypeCodeArray, err: true}, - {in: int64(3), out: 3, ty: json.TypeCodeInt64}, - {in: int64(-3), out: -3, ty: json.TypeCodeInt64}, - {in: uint64(1 << 63), out: 1 << 63, ty: json.TypeCodeUint64}, - {in: float64(4.5), out: 4.5, ty: json.TypeCodeFloat64}, - {in: true, out: 1, ty: json.TypeCodeLiteral}, - {in: false, out: 0, ty: json.TypeCodeLiteral}, - {in: nil, ty: json.TypeCodeLiteral, err: true}, - {in: "hello", ty: json.TypeCodeString, err: true}, - {in: "123.456hello", out: 123.456, ty: json.TypeCodeString, err: true}, - {in: "1234", out: 1234, ty: json.TypeCodeString}, + {in: make(map[string]interface{}), ty: JSONTypeCodeObject, err: true}, + {in: make([]interface{}, 0), ty: JSONTypeCodeArray, err: true}, + {in: int64(3), out: 3, ty: JSONTypeCodeInt64}, + {in: int64(-3), out: -3, ty: JSONTypeCodeInt64}, + {in: uint64(1 << 63), out: 1 << 63, ty: JSONTypeCodeUint64}, + {in: float64(4.5), out: 4.5, ty: JSONTypeCodeFloat64}, + {in: true, out: 1, ty: JSONTypeCodeLiteral}, + {in: false, out: 0, ty: JSONTypeCodeLiteral}, + {in: nil, ty: JSONTypeCodeLiteral, err: true}, + {in: "hello", ty: JSONTypeCodeString, err: true}, + {in: "123.456hello", out: 123.456, ty: JSONTypeCodeString, err: true}, + {in: "1234", out: 1234, ty: JSONTypeCodeString}, } for _, tt := range tests { - j := json.CreateBinary(tt.in) + j := CreateBinaryJSON(tt.in) require.Equal(t, tt.ty, j.TypeCode) casted, err := ConvertJSONToFloat(new(stmtctx.StatementContext), j) if tt.err { @@ -1139,7 +1138,7 @@ func TestConvertJSONToDecimal(t *testing.T) { {in: `null`, out: NewDecFromStringForTest("0"), err: true}, } for _, tt := range tests { - j, err := json.ParseBinaryFromString(tt.in) + j, err := ParseBinaryJSONFromString(tt.in) require.NoError(t, err) casted, err := ConvertJSONToDecimal(new(stmtctx.StatementContext), j) errMsg := fmt.Sprintf("input: %v, casted: %v, out: %v, json: %#v", tt.in, casted, tt.out, j) diff --git a/types/datum.go b/types/datum.go index 7c08bea7a6666..d68f1672753b2 100644 --- a/types/datum.go +++ b/types/datum.go @@ -31,7 +31,6 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/parser/types" "github.com/pingcap/tidb/sessionctx/stmtctx" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/hack" "github.com/pingcap/tidb/util/logutil" @@ -397,12 +396,12 @@ func (d *Datum) SetMysqlSet(b Set, collation string) { } // GetMysqlJSON gets json.BinaryJSON value -func (d *Datum) GetMysqlJSON() json.BinaryJSON { - return json.BinaryJSON{TypeCode: byte(d.i), Value: d.b} +func (d *Datum) GetMysqlJSON() BinaryJSON { + return BinaryJSON{TypeCode: byte(d.i), Value: d.b} } // SetMysqlJSON sets json.BinaryJSON value -func (d *Datum) SetMysqlJSON(b json.BinaryJSON) { +func (d *Datum) SetMysqlJSON(b BinaryJSON) { d.k = KindMysqlJSON d.i = int64(b.TypeCode) d.b = b.Value @@ -557,7 +556,7 @@ func (d *Datum) SetValueWithDefaultCollation(val interface{}) { d.SetBinaryLiteral(BinaryLiteral(x)) case Set: d.SetMysqlSet(x, mysql.DefaultCollationName) - case json.BinaryJSON: + case BinaryJSON: d.SetMysqlJSON(x) case Time: d.SetMysqlTime(x) @@ -605,7 +604,7 @@ func (d *Datum) SetValue(val interface{}, tp *types.FieldType) { d.SetBinaryLiteral(BinaryLiteral(x)) case Set: d.SetMysqlSet(x, tp.GetCollate()) - case json.BinaryJSON: + case BinaryJSON: d.SetMysqlJSON(x) case Time: d.SetMysqlTime(x) @@ -855,12 +854,12 @@ func (d *Datum) compareMysqlSet(sc *stmtctx.StatementContext, set Set, comparer } } -func (d *Datum) compareMysqlJSON(_ *stmtctx.StatementContext, target json.BinaryJSON) (int, error) { +func (d *Datum) compareMysqlJSON(_ *stmtctx.StatementContext, target BinaryJSON) (int, error) { origin, err := d.ToMysqlJSON() if err != nil { return 0, errors.Trace(err) } - return json.CompareBinary(origin, target), nil + return CompareBinaryJSON(origin, target), nil } func (d *Datum) compareMysqlTime(sc *stmtctx.StatementContext, time Time) (int, error) { @@ -1669,43 +1668,43 @@ func (d *Datum) convertToMysqlSet(sc *stmtctx.StatementContext, target *FieldTyp func (d *Datum) convertToMysqlJSON(_ *stmtctx.StatementContext, _ *FieldType) (ret Datum, err error) { switch d.k { case KindString, KindBytes: - var j json.BinaryJSON - if j, err = json.ParseBinaryFromString(d.GetString()); err == nil { + var j BinaryJSON + if j, err = ParseBinaryJSONFromString(d.GetString()); err == nil { ret.SetMysqlJSON(j) } case KindMysqlSet, KindMysqlEnum: - var j json.BinaryJSON + var j BinaryJSON var s string if s, err = d.ToString(); err == nil { - if j, err = json.ParseBinaryFromString(s); err == nil { + if j, err = ParseBinaryJSONFromString(s); err == nil { ret.SetMysqlJSON(j) } } case KindInt64: i64 := d.GetInt64() - ret.SetMysqlJSON(json.CreateBinary(i64)) + ret.SetMysqlJSON(CreateBinaryJSON(i64)) case KindUint64: u64 := d.GetUint64() - ret.SetMysqlJSON(json.CreateBinary(u64)) + ret.SetMysqlJSON(CreateBinaryJSON(u64)) case KindFloat32, KindFloat64: f64 := d.GetFloat64() - ret.SetMysqlJSON(json.CreateBinary(f64)) + ret.SetMysqlJSON(CreateBinaryJSON(f64)) case KindMysqlDecimal: var f64 float64 if f64, err = d.GetMysqlDecimal().ToFloat64(); err == nil { - ret.SetMysqlJSON(json.CreateBinary(f64)) + ret.SetMysqlJSON(CreateBinaryJSON(f64)) } case KindMysqlJSON: ret = *d case KindBinaryLiteral: - err = json.ErrInvalidJSONCharset.GenWithStackByArgs(charset.CharsetBin) + err = ErrInvalidJSONCharset.GenWithStackByArgs(charset.CharsetBin) default: var s string if s, err = d.ToString(); err == nil { // TODO: fix precision of MysqlTime. For example, // On MySQL 5.7 CAST(NOW() AS JSON) -> "2011-11-11 11:11:11.111111", // But now we can only return "2011-11-11 11:11:11". - ret.SetMysqlJSON(json.CreateBinary(s)) + ret.SetMysqlJSON(CreateBinaryJSON(s)) } } return ret, errors.Trace(err) @@ -1986,7 +1985,7 @@ func (d *Datum) ToBytes() ([]byte, error) { // ToMysqlJSON is similar to convertToMysqlJSON, except the // latter parses from string, but the former uses it as primitive. -func (d *Datum) ToMysqlJSON() (j json.BinaryJSON, err error) { +func (d *Datum) ToMysqlJSON() (j BinaryJSON, err error) { var in interface{} switch d.Kind() { case KindMysqlJSON: @@ -2013,7 +2012,7 @@ func (d *Datum) ToMysqlJSON() (j json.BinaryJSON, err error) { err = errors.Trace(err) return } - j = json.CreateBinary(in) + j = CreateBinaryJSON(in) return } @@ -2155,7 +2154,7 @@ func NewDecimalDatum(dec *MyDecimal) (d Datum) { } // NewJSONDatum creates a new Datum from a BinaryJSON value -func NewJSONDatum(j json.BinaryJSON) (d Datum) { +func NewJSONDatum(j BinaryJSON) (d Datum) { d.SetMysqlJSON(j) return d } diff --git a/types/datum_test.go b/types/datum_test.go index 698a69fd6b731..b477e2874b07f 100644 --- a/types/datum_test.go +++ b/types/datum_test.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/hack" "github.com/stretchr/testify/assert" @@ -78,22 +77,22 @@ func TestToBool(t *testing.T) { testDatumToBool(t, NewBinaryLiteralFromUint(0, -1), 0) testDatumToBool(t, Enum{Name: "a", Value: 1}, 1) testDatumToBool(t, Set{Name: "a", Value: 1}, 1) - testDatumToBool(t, json.CreateBinary(int64(1)), 1) - testDatumToBool(t, json.CreateBinary(int64(0)), 0) - testDatumToBool(t, json.CreateBinary("0"), 1) - testDatumToBool(t, json.CreateBinary("aaabbb"), 1) - testDatumToBool(t, json.CreateBinary(float64(0.0)), 0) - testDatumToBool(t, json.CreateBinary(float64(3.1415)), 1) - testDatumToBool(t, json.CreateBinary([]interface{}{int64(1), int64(2)}), 1) - testDatumToBool(t, json.CreateBinary(map[string]interface{}{"ke": "val"}), 1) - testDatumToBool(t, json.CreateBinary("0000-00-00 00:00:00"), 1) - testDatumToBool(t, json.CreateBinary("0778"), 1) - testDatumToBool(t, json.CreateBinary("0000"), 1) - testDatumToBool(t, json.CreateBinary(nil), 1) - testDatumToBool(t, json.CreateBinary([]interface{}{nil}), 1) - testDatumToBool(t, json.CreateBinary(true), 1) - testDatumToBool(t, json.CreateBinary(false), 1) - testDatumToBool(t, json.CreateBinary(""), 1) + testDatumToBool(t, CreateBinaryJSON(int64(1)), 1) + testDatumToBool(t, CreateBinaryJSON(int64(0)), 0) + testDatumToBool(t, CreateBinaryJSON("0"), 1) + testDatumToBool(t, CreateBinaryJSON("aaabbb"), 1) + testDatumToBool(t, CreateBinaryJSON(float64(0.0)), 0) + testDatumToBool(t, CreateBinaryJSON(float64(3.1415)), 1) + testDatumToBool(t, CreateBinaryJSON([]interface{}{int64(1), int64(2)}), 1) + testDatumToBool(t, CreateBinaryJSON(map[string]interface{}{"ke": "val"}), 1) + testDatumToBool(t, CreateBinaryJSON("0000-00-00 00:00:00"), 1) + testDatumToBool(t, CreateBinaryJSON("0778"), 1) + testDatumToBool(t, CreateBinaryJSON("0000"), 1) + testDatumToBool(t, CreateBinaryJSON(nil), 1) + testDatumToBool(t, CreateBinaryJSON([]interface{}{nil}), 1) + testDatumToBool(t, CreateBinaryJSON(true), 1) + testDatumToBool(t, CreateBinaryJSON(false), 1) + testDatumToBool(t, CreateBinaryJSON(""), 1) t1, err := ParseTime(&stmtctx.StatementContext{TimeZone: time.UTC}, "2011-11-10 11:11:11.999999", mysql.TypeTimestamp, 6) require.NoError(t, err) testDatumToBool(t, t1, 1) @@ -133,7 +132,7 @@ func TestToInt64(t *testing.T) { testDatumToInt64(t, NewBinaryLiteralFromUint(100, -1), int64(100)) testDatumToInt64(t, Enum{Name: "a", Value: 1}, int64(1)) testDatumToInt64(t, Set{Name: "a", Value: 1}, int64(1)) - testDatumToInt64(t, json.CreateBinary(int64(3)), int64(3)) + testDatumToInt64(t, CreateBinaryJSON(int64(3)), int64(3)) t1, err := ParseTime(&stmtctx.StatementContext{ TimeZone: time.UTC, @@ -568,7 +567,7 @@ func TestMarshalDatum(t *testing.T) { NewMysqlEnumDatum(Enum{Name: "a", Value: 1}), NewCollateMysqlEnumDatum(Enum{Name: "a", Value: 1}, charset.CollationASCII), NewMysqlSetDatum(e, charset.CollationGBKBin), - NewJSONDatum(json.CreateBinary(int64(1))), + NewJSONDatum(CreateBinaryJSON(int64(1))), MinNotNullDatum(), MaxValueDatum(), } diff --git a/types/field_type.go b/types/field_type.go index 0cf5dae4c60a9..904206df1f282 100644 --- a/types/field_type.go +++ b/types/field_type.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/parser/charset" "github.com/pingcap/tidb/parser/mysql" ast "github.com/pingcap/tidb/parser/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/dbterror" "github.com/pingcap/tidb/util/mathutil" @@ -318,7 +317,7 @@ func DefaultTypeForValue(value interface{}, tp *FieldType, char string, collate tp.SetFlen(len(x.Name)) tp.SetDecimal(UnspecifiedLength) SetBinChsClnFlag(tp) - case json.BinaryJSON: + case BinaryJSON: tp.SetType(mysql.TypeJSON) tp.SetFlen(UnspecifiedLength) tp.SetDecimal(0) diff --git a/types/json/BUILD.bazel b/types/json/BUILD.bazel deleted file mode 100644 index 12321a21f60fd..0000000000000 --- a/types/json/BUILD.bazel +++ /dev/null @@ -1,42 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") - -go_library( - name = "json", - srcs = [ - "binary.go", - "binary_functions.go", - "constants.go", - "path_expr.go", - ], - importpath = "github.com/pingcap/tidb/types/json", - visibility = ["//visibility:public"], - deps = [ - "//errno", - "//parser/mysql", - "//parser/terror", - "//util/dbterror", - "//util/hack", - "//util/kvcache", - "//util/stringutil", - "@com_github_pingcap_errors//:errors", - "@org_golang_x_exp//slices", - ], -) - -go_test( - name = "json_test", - timeout = "short", - srcs = [ - "binary_functions_test.go", - "binary_test.go", - "main_test.go", - "path_expr_test.go", - ], - embed = [":json"], - flaky = True, - deps = [ - "//testkit/testsetup", - "@com_github_stretchr_testify//require", - "@org_uber_go_goleak//:goleak", - ], -) diff --git a/types/json/main_test.go b/types/json/main_test.go deleted file mode 100644 index 329bed3e3f0fc..0000000000000 --- a/types/json/main_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2021 PingCAP, Inc. -// -// 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/pingcap/tidb/testkit/testsetup" - "go.uber.org/goleak" -) - -const benchStr = `{"a":[1,"2",{"aa":"bb"},4,null],"b":true,"c":null}` - -func TestMain(m *testing.M) { - testsetup.SetupForCommonTest() - opts := []goleak.Option{ - goleak.IgnoreTopFunction("github.com/golang/glog.(*loggingT).flushDaemon"), - goleak.IgnoreTopFunction("go.etcd.io/etcd/client/pkg/v3/logutil.(*MergeLogger).outputLoop"), - goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), - } - goleak.VerifyTestMain(m, opts...) -} diff --git a/types/json/binary.go b/types/json_binary.go similarity index 81% rename from types/json/binary.go rename to types/json_binary.go index d03932722ba65..da7614f620f04 100644 --- a/types/json/binary.go +++ b/types/json_binary.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package json +package types import ( "bytes" @@ -109,7 +109,7 @@ import ( // BinaryJSON represents a binary encoded JSON object. // It can be randomly accessed without deserialization. type BinaryJSON struct { - TypeCode TypeCode + TypeCode JSONTypeCode Value []byte } @@ -135,21 +135,21 @@ func (bj BinaryJSON) MarshalJSON() ([]byte, error) { func (bj BinaryJSON) marshalTo(buf []byte) ([]byte, error) { switch bj.TypeCode { - case TypeCodeOpaque: - return marshalOpaqueTo(buf, bj.GetOpaque()), nil - case TypeCodeString: - return marshalStringTo(buf, bj.GetString()), nil - case TypeCodeLiteral: - return marshalLiteralTo(buf, bj.Value[0]), nil - case TypeCodeInt64: + case JSONTypeCodeOpaque: + return jsonMarshalOpaqueTo(buf, bj.GetOpaque()), nil + case JSONTypeCodeString: + return jsonMarshalStringTo(buf, bj.GetString()), nil + case JSONTypeCodeLiteral: + return jsonMarshalLiteralTo(buf, bj.Value[0]), nil + case JSONTypeCodeInt64: return strconv.AppendInt(buf, bj.GetInt64(), 10), nil - case TypeCodeUint64: + case JSONTypeCodeUint64: return strconv.AppendUint(buf, bj.GetUint64(), 10), nil - case TypeCodeFloat64: + case JSONTypeCodeFloat64: return bj.marshalFloat64To(buf) - case TypeCodeArray: + case JSONTypeCodeArray: return bj.marshalArrayTo(buf) - case TypeCodeObject: + case JSONTypeCodeObject: return bj.marshalObjTo(buf) } return buf, nil @@ -159,22 +159,22 @@ func (bj BinaryJSON) marshalTo(buf []byte) ([]byte, error) { func (bj BinaryJSON) IsZero() bool { isZero := false switch bj.TypeCode { - case TypeCodeString: + case JSONTypeCodeString: isZero = false - case TypeCodeLiteral: + case JSONTypeCodeLiteral: isZero = false - case TypeCodeInt64: + case JSONTypeCodeInt64: isZero = bj.GetInt64() == 0 - case TypeCodeUint64: + case JSONTypeCodeUint64: isZero = bj.GetUint64() == 0 - case TypeCodeFloat64: + case JSONTypeCodeFloat64: isZero = bj.GetFloat64() == 0 - case TypeCodeArray: + case JSONTypeCodeArray: isZero = false - case TypeCodeObject: + case JSONTypeCodeObject: isZero = false // FIXME: TiDB always casts the json to double BINARY so this function will never be called. - case TypeCodeOpaque: + case JSONTypeCodeOpaque: isZero = false } return isZero @@ -182,12 +182,12 @@ func (bj BinaryJSON) IsZero() bool { // GetInt64 gets the int64 value. func (bj BinaryJSON) GetInt64() int64 { - return int64(endian.Uint64(bj.Value)) + return int64(jsonEndian.Uint64(bj.Value)) } // GetUint64 gets the uint64 value. func (bj BinaryJSON) GetUint64() uint64 { - return endian.Uint64(bj.Value) + return jsonEndian.Uint64(bj.Value) } // GetFloat64 gets the float64 value. @@ -231,14 +231,14 @@ func (bj BinaryJSON) GetKeys() BinaryJSON { count := bj.GetElemCount() ret := make([]BinaryJSON, 0, count) for i := 0; i < count; i++ { - ret = append(ret, CreateBinary(string(bj.objectGetKey(i)))) + ret = append(ret, CreateBinaryJSON(string(bj.objectGetKey(i)))) } - return buildBinaryArray(ret) + return buildBinaryJSONArray(ret) } // GetElemCount gets the count of Object or Array. func (bj BinaryJSON) GetElemCount() int { - return int(endian.Uint32(bj.Value)) + return int(jsonEndian.Uint32(bj.Value)) } func (bj BinaryJSON) arrayGetElem(idx int) BinaryJSON { @@ -246,8 +246,8 @@ func (bj BinaryJSON) arrayGetElem(idx int) BinaryJSON { } func (bj BinaryJSON) objectGetKey(i int) []byte { - keyOff := int(endian.Uint32(bj.Value[headerSize+i*keyEntrySize:])) - keyLen := int(endian.Uint16(bj.Value[headerSize+i*keyEntrySize+keyLenOff:])) + keyOff := int(jsonEndian.Uint32(bj.Value[headerSize+i*keyEntrySize:])) + keyLen := int(jsonEndian.Uint16(bj.Value[headerSize+i*keyEntrySize+keyLenOff:])) return bj.Value[keyOff : keyOff+keyLen] } @@ -258,22 +258,22 @@ func (bj BinaryJSON) objectGetVal(i int) BinaryJSON { func (bj BinaryJSON) valEntryGet(valEntryOff int) BinaryJSON { tpCode := bj.Value[valEntryOff] - valOff := endian.Uint32(bj.Value[valEntryOff+valTypeSize:]) + valOff := jsonEndian.Uint32(bj.Value[valEntryOff+valTypeSize:]) switch tpCode { - case TypeCodeLiteral: - return BinaryJSON{TypeCode: TypeCodeLiteral, Value: bj.Value[valEntryOff+valTypeSize : valEntryOff+valTypeSize+1]} - case TypeCodeUint64, TypeCodeInt64, TypeCodeFloat64: + case JSONTypeCodeLiteral: + return BinaryJSON{TypeCode: JSONTypeCodeLiteral, Value: bj.Value[valEntryOff+valTypeSize : valEntryOff+valTypeSize+1]} + case JSONTypeCodeUint64, JSONTypeCodeInt64, JSONTypeCodeFloat64: return BinaryJSON{TypeCode: tpCode, Value: bj.Value[valOff : valOff+8]} - case TypeCodeString: + case JSONTypeCodeString: strLen, lenLen := binary.Uvarint(bj.Value[valOff:]) totalLen := uint32(lenLen) + uint32(strLen) return BinaryJSON{TypeCode: tpCode, Value: bj.Value[valOff : valOff+totalLen]} - case TypeCodeOpaque: + case JSONTypeCodeOpaque: strLen, lenLen := binary.Uvarint(bj.Value[valOff+1:]) totalLen := 1 + uint32(lenLen) + uint32(strLen) return BinaryJSON{TypeCode: tpCode, Value: bj.Value[valOff : valOff+totalLen]} } - dataSize := endian.Uint32(bj.Value[valOff+dataSizeOff:]) + dataSize := jsonEndian.Uint32(bj.Value[valOff+dataSizeOff:]) return BinaryJSON{TypeCode: tpCode, Value: bj.Value[valOff : valOff+dataSize]} } @@ -310,7 +310,7 @@ func (bj BinaryJSON) marshalFloat64To(buf []byte) ([]byte, error) { } func (bj BinaryJSON) marshalArrayTo(buf []byte) ([]byte, error) { - elemCount := int(endian.Uint32(bj.Value)) + elemCount := int(jsonEndian.Uint32(bj.Value)) buf = append(buf, '[') for i := 0; i < elemCount; i++ { if i != 0 { @@ -326,13 +326,13 @@ func (bj BinaryJSON) marshalArrayTo(buf []byte) ([]byte, error) { } func (bj BinaryJSON) marshalObjTo(buf []byte) ([]byte, error) { - elemCount := int(endian.Uint32(bj.Value)) + elemCount := int(jsonEndian.Uint32(bj.Value)) buf = append(buf, '{') for i := 0; i < elemCount; i++ { if i != 0 { buf = append(buf, ", "...) } - buf = marshalStringTo(buf, bj.objectGetKey(i)) + buf = jsonMarshalStringTo(buf, bj.objectGetKey(i)) buf = append(buf, ": "...) var err error buf, err = bj.objectGetVal(i).marshalTo(buf) @@ -343,14 +343,14 @@ func (bj BinaryJSON) marshalObjTo(buf []byte) ([]byte, error) { return append(buf, '}'), nil } -func marshalStringTo(buf, s []byte) []byte { +func jsonMarshalStringTo(buf, s []byte) []byte { // NOTE: copied from Go standard library. // NOTE: keep in sync with string above. buf = append(buf, '"') start := 0 for i := 0; i < len(s); { if b := s[i]; b < utf8.RuneSelf { - if safeSet[b] { + if jsonSafeSet[b] { i++ continue } @@ -373,7 +373,7 @@ func marshalStringTo(buf, s []byte) []byte { // user-controlled strings are rendered into JSON // and served to some browsers. buf = append(buf, `\u00`...) - buf = append(buf, hexChars[b>>4], hexChars[b&0xF]) + buf = append(buf, jsonHexChars[b>>4], jsonHexChars[b&0xF]) } i++ start = i @@ -401,7 +401,7 @@ func marshalStringTo(buf, s []byte) []byte { buf = append(buf, s[start:i]...) } buf = append(buf, `\u202`...) - buf = append(buf, hexChars[c&0xF]) + buf = append(buf, jsonHexChars[c&0xF]) i += size start = i continue @@ -416,7 +416,7 @@ func marshalStringTo(buf, s []byte) []byte { } // opaque value will yield "base64:typeXX:" -func marshalOpaqueTo(buf []byte, opaque Opaque) []byte { +func jsonMarshalOpaqueTo(buf []byte, opaque Opaque) []byte { b64 := base64.StdEncoding.EncodeToString(opaque.Buf) output := fmt.Sprintf(`"base64:type%d:%s"`, opaque.TypeCode, b64) @@ -426,20 +426,20 @@ func marshalOpaqueTo(buf []byte, opaque Opaque) []byte { return buf } -func marshalLiteralTo(b []byte, litType byte) []byte { +func jsonMarshalLiteralTo(b []byte, litType byte) []byte { switch litType { - case LiteralFalse: + case JSONLiteralFalse: return append(b, "false"...) - case LiteralTrue: + case JSONLiteralTrue: return append(b, "true"...) - case LiteralNil: + case JSONLiteralNil: return append(b, "null"...) } return b } -// ParseBinaryFromString parses a json from string. -func ParseBinaryFromString(s string) (bj BinaryJSON, err error) { +// ParseBinaryJSONFromString parses a json from string. +func ParseBinaryJSONFromString(s string) (bj BinaryJSON, err error) { if len(s) == 0 { err = ErrInvalidJSONText.GenWithStackByArgs("The document is empty") return @@ -465,8 +465,8 @@ func (bj *BinaryJSON) UnmarshalJSON(data []byte) error { return errors.Trace(err) } buf := make([]byte, 0, len(data)) - var typeCode TypeCode - typeCode, buf, err = appendBinary(buf, in) + var typeCode JSONTypeCode + typeCode, buf, err = appendBinaryJSON(buf, in) if err != nil { return errors.Trace(err) } @@ -479,7 +479,7 @@ func (bj *BinaryJSON) UnmarshalJSON(data []byte) error { // For example int64(3) == float64(3.0) func (bj BinaryJSON) HashValue(buf []byte) []byte { switch bj.TypeCode { - case TypeCodeInt64: + case JSONTypeCodeInt64: // Convert to a FLOAT if no precision is lost. // In the future, it will be better to convert to a DECIMAL value instead // See: https://github.com/pingcap/tidb/issues/9988 @@ -488,13 +488,13 @@ func (bj BinaryJSON) HashValue(buf []byte) []byte { } else { buf = append(buf, bj.Value...) } - case TypeCodeArray: - elemCount := int(endian.Uint32(bj.Value)) + case JSONTypeCodeArray: + elemCount := int(jsonEndian.Uint32(bj.Value)) for i := 0; i < elemCount; i++ { buf = bj.arrayGetElem(i).HashValue(buf) } - case TypeCodeObject: - elemCount := int(endian.Uint32(bj.Value)) + case JSONTypeCodeObject: + elemCount := int(jsonEndian.Uint32(bj.Value)) for i := 0; i < elemCount; i++ { buf = append(buf, bj.objectGetKey(i)...) buf = bj.objectGetVal(i).HashValue(buf) @@ -505,37 +505,37 @@ func (bj BinaryJSON) HashValue(buf []byte) []byte { return buf } -// CreateBinary creates a BinaryJSON from interface. -func CreateBinary(in interface{}) BinaryJSON { - typeCode, buf, err := appendBinary(nil, in) +// CreateBinaryJSON creates a BinaryJSON from interface. +func CreateBinaryJSON(in interface{}) BinaryJSON { + typeCode, buf, err := appendBinaryJSON(nil, in) if err != nil { panic(err) } return BinaryJSON{TypeCode: typeCode, Value: buf} } -func appendBinary(buf []byte, in interface{}) (TypeCode, []byte, error) { +func appendBinaryJSON(buf []byte, in interface{}) (JSONTypeCode, []byte, error) { var typeCode byte var err error switch x := in.(type) { case nil: - typeCode = TypeCodeLiteral - buf = append(buf, LiteralNil) + typeCode = JSONTypeCodeLiteral + buf = append(buf, JSONLiteralNil) case bool: - typeCode = TypeCodeLiteral + typeCode = JSONTypeCodeLiteral if x { - buf = append(buf, LiteralTrue) + buf = append(buf, JSONLiteralTrue) } else { - buf = append(buf, LiteralFalse) + buf = append(buf, JSONLiteralFalse) } case int64: - typeCode = TypeCodeInt64 + typeCode = JSONTypeCodeInt64 buf = appendBinaryUint64(buf, uint64(x)) case uint64: - typeCode = TypeCodeUint64 + typeCode = JSONTypeCodeUint64 buf = appendBinaryUint64(buf, x) case float64: - typeCode = TypeCodeFloat64 + typeCode = JSONTypeCodeFloat64 buf = appendBinaryFloat64(buf, x) case json.Number: typeCode, buf, err = appendBinaryNumber(buf, x) @@ -543,25 +543,25 @@ func appendBinary(buf []byte, in interface{}) (TypeCode, []byte, error) { return typeCode, nil, errors.Trace(err) } case string: - typeCode = TypeCodeString + typeCode = JSONTypeCodeString buf = appendBinaryString(buf, x) case BinaryJSON: typeCode = x.TypeCode buf = append(buf, x.Value...) case []interface{}: - typeCode = TypeCodeArray + typeCode = JSONTypeCodeArray buf, err = appendBinaryArray(buf, x) if err != nil { return typeCode, nil, errors.Trace(err) } case map[string]interface{}: - typeCode = TypeCodeObject + typeCode = JSONTypeCodeObject buf, err = appendBinaryObject(buf, x) if err != nil { return typeCode, nil, errors.Trace(err) } case Opaque: - typeCode = TypeCodeOpaque + typeCode = JSONTypeCodeOpaque buf = appendBinaryOpaque(buf, x) default: msg := fmt.Sprintf(unknownTypeErrorMsg, reflect.TypeOf(in)) @@ -585,11 +585,11 @@ func appendZero(buf []byte, length int) []byte { func appendUint32(buf []byte, v uint32) []byte { var tmp [4]byte - endian.PutUint32(tmp[:], v) + jsonEndian.PutUint32(tmp[:], v) return append(buf, tmp[:]...) } -func appendBinaryNumber(buf []byte, x json.Number) (TypeCode, []byte, error) { +func appendBinaryNumber(buf []byte, x json.Number) (JSONTypeCode, []byte, error) { // The type interpretation process is as follows: // - Attempt float64 if it contains Ee. // - Next attempt int64 @@ -599,19 +599,19 @@ func appendBinaryNumber(buf []byte, x json.Number) (TypeCode, []byte, error) { if strings.ContainsAny(string(x), "Ee.") { f64, err := x.Float64() if err != nil { - return TypeCodeFloat64, nil, errors.Trace(err) + return JSONTypeCodeFloat64, nil, errors.Trace(err) } - return TypeCodeFloat64, appendBinaryFloat64(buf, f64), nil + return JSONTypeCodeFloat64, appendBinaryFloat64(buf, f64), nil } else if val, err := x.Int64(); err == nil { - return TypeCodeInt64, appendBinaryUint64(buf, uint64(val)), nil + return JSONTypeCodeInt64, appendBinaryUint64(buf, uint64(val)), nil } else if val, err := strconv.ParseUint(string(x), 10, 64); err == nil { - return TypeCodeUint64, appendBinaryUint64(buf, val), nil + return JSONTypeCodeUint64, appendBinaryUint64(buf, val), nil } val, err := x.Float64() if err == nil { - return TypeCodeFloat64, appendBinaryFloat64(buf, val), nil + return JSONTypeCodeFloat64, appendBinaryFloat64(buf, val), nil } - var typeCode TypeCode + var typeCode JSONTypeCode return typeCode, nil, errors.Trace(err) } @@ -639,14 +639,14 @@ func appendBinaryOpaque(buf []byte, v Opaque) []byte { func appendBinaryFloat64(buf []byte, v float64) []byte { off := len(buf) buf = appendZero(buf, 8) - endian.PutUint64(buf[off:], math.Float64bits(v)) + jsonEndian.PutUint64(buf[off:], math.Float64bits(v)) return buf } func appendBinaryUint64(buf []byte, v uint64) []byte { off := len(buf) buf = appendZero(buf, 8) - endian.PutUint64(buf[off:], v) + jsonEndian.PutUint64(buf[off:], v) return buf } @@ -664,28 +664,28 @@ func appendBinaryArray(buf []byte, array []interface{}) ([]byte, error) { } } docSize := len(buf) - docOff - endian.PutUint32(buf[docOff+dataSizeOff:], uint32(docSize)) + jsonEndian.PutUint32(buf[docOff+dataSizeOff:], uint32(docSize)) return buf, nil } func appendBinaryValElem(buf []byte, docOff, valEntryOff int, val interface{}) ([]byte, error) { - var typeCode TypeCode + var typeCode JSONTypeCode var err error elemDocOff := len(buf) - typeCode, buf, err = appendBinary(buf, val) + typeCode, buf, err = appendBinaryJSON(buf, val) if err != nil { return nil, errors.Trace(err) } - if typeCode == TypeCodeLiteral { + if typeCode == JSONTypeCodeLiteral { litCode := buf[elemDocOff] buf = buf[:elemDocOff] - buf[valEntryOff] = TypeCodeLiteral + buf[valEntryOff] = JSONTypeCodeLiteral buf[valEntryOff+1] = litCode return buf, nil } buf[valEntryOff] = typeCode valOff := elemDocOff - docOff - endian.PutUint32(buf[valEntryOff+1:], uint32(valOff)) + jsonEndian.PutUint32(buf[valEntryOff+1:], uint32(valOff)) return buf, nil } @@ -717,8 +717,8 @@ func appendBinaryObject(buf []byte, x map[string]interface{}) ([]byte, error) { if keyLen > math.MaxUint16 { return nil, ErrJSONObjectKeyTooLong } - endian.PutUint32(buf[keyEntryOff:], uint32(keyOff)) - endian.PutUint16(buf[keyEntryOff+keyLenOff:], uint16(keyLen)) + jsonEndian.PutUint32(buf[keyEntryOff:], uint32(keyOff)) + jsonEndian.PutUint16(buf[keyEntryOff+keyLenOff:], uint16(keyLen)) buf = append(buf, field.key...) } for i, field := range fields { @@ -729,6 +729,6 @@ func appendBinaryObject(buf []byte, x map[string]interface{}) ([]byte, error) { } } docSize := len(buf) - docOff - endian.PutUint32(buf[docOff+dataSizeOff:], uint32(docSize)) + jsonEndian.PutUint32(buf[docOff+dataSizeOff:], uint32(docSize)) return buf, nil } diff --git a/types/json/binary_functions.go b/types/json_binary_functions.go similarity index 76% rename from types/json/binary_functions.go rename to types/json_binary_functions.go index 49ec801d794bf..1b445760f9397 100644 --- a/types/json/binary_functions.go +++ b/types/json_binary_functions.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package json +package types import ( "bytes" @@ -33,26 +33,26 @@ import ( // Type returns type of BinaryJSON as string. func (bj BinaryJSON) Type() string { switch bj.TypeCode { - case TypeCodeObject: + case JSONTypeCodeObject: return "OBJECT" - case TypeCodeArray: + case JSONTypeCodeArray: return "ARRAY" - case TypeCodeLiteral: + case JSONTypeCodeLiteral: switch bj.Value[0] { - case LiteralNil: + case JSONLiteralNil: return "NULL" default: return "BOOLEAN" } - case TypeCodeInt64: + case JSONTypeCodeInt64: return "INTEGER" - case TypeCodeUint64: + case JSONTypeCodeUint64: return "UNSIGNED INTEGER" - case TypeCodeFloat64: + case JSONTypeCodeFloat64: return "DOUBLE" - case TypeCodeString: + case JSONTypeCodeString: return "STRING" - case TypeCodeOpaque: + case JSONTypeCodeOpaque: typ := bj.GetOpaqueFieldType() switch typ { case mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob, mysql.TypeBlob, mysql.TypeString, mysql.TypeVarString, mysql.TypeVarchar: @@ -71,7 +71,7 @@ func (bj BinaryJSON) Type() string { // Unquote is for JSON_UNQUOTE. func (bj BinaryJSON) Unquote() (string, error) { switch bj.TypeCode { - case TypeCodeString: + case JSONTypeCodeString: str := string(hack.String(bj.GetString())) return UnquoteString(str) default: @@ -89,15 +89,15 @@ func UnquoteString(str string) (string, error) { head, tail := str[0], str[strLen-1] if head == '"' && tail == '"' { // Remove prefix and suffix '"' before unquoting - return unquoteString(str[1 : strLen-1]) + return unquoteJSONString(str[1 : strLen-1]) } // if value is not double quoted, do nothing return str, nil } -// unquoteString recognizes the escape sequences shown in: +// unquoteJSONString recognizes the escape sequences shown in: // https://dev.mysql.com/doc/refman/5.7/en/json-modification-functions.html#json-unquote-character-escape-sequences -func unquoteString(s string) (string, error) { +func unquoteJSONString(s string) (string, error) { ret := new(bytes.Buffer) for i := 0; i < len(s); i++ { if s[i] == '\\' { @@ -157,10 +157,10 @@ func decodeEscapedUnicode(s []byte) (char [4]byte, size int, err error) { return } -// quoteString escapes interior quote and other characters for JSON_QUOTE +// quoteJSONString escapes interior quote and other characters for JSON_QUOTE // https://dev.mysql.com/doc/refman/5.7/en/json-creation-functions.html#function_json-quote // TODO: add JSON_QUOTE builtin -func quoteString(s string) string { +func quoteJSONString(s string) string { var escapeByteMap = map[byte]string{ '\\': "\\\\", '"': "\\\"", @@ -193,7 +193,7 @@ func quoteString(s string) string { } } else { c, size := utf8.DecodeRune([]byte(s[i:])) - if c == utf8.RuneError && size == 1 { // refer to codes of `binary.marshalStringTo` + if c == utf8.RuneError && size == 1 { // refer to codes of `binary.jsonMarshalStringTo` if start < i { ret.WriteString(s[start:i]) } @@ -222,7 +222,7 @@ func quoteString(s string) string { // // ret: target JSON matched any path expressions. maybe autowrapped as an array. // found: true if any path expressions matched. -func (bj BinaryJSON) Extract(pathExprList []PathExpression) (ret BinaryJSON, found bool) { +func (bj BinaryJSON) Extract(pathExprList []JSONPathExpression) (ret BinaryJSON, found bool) { buf := make([]BinaryJSON, 0, 1) for _, pathExpr := range pathExprList { buf = bj.extractTo(buf, pathExpr, make(map[*byte]struct{}), false) @@ -237,21 +237,21 @@ func (bj BinaryJSON) Extract(pathExprList []PathExpression) (ret BinaryJSON, fou ret = buf[0] // Fix https://github.com/pingcap/tidb/issues/30352 if pathExprList[0].ContainsAnyAsterisk() { - ret = buildBinaryArray(buf) + ret = buildBinaryJSONArray(buf) } } else { found = true - ret = buildBinaryArray(buf) + ret = buildBinaryJSONArray(buf) } return } -func (bj BinaryJSON) extractOne(pathExpr PathExpression) []BinaryJSON { +func (bj BinaryJSON) extractOne(pathExpr JSONPathExpression) []BinaryJSON { result := make([]BinaryJSON, 0, 1) return bj.extractTo(result, pathExpr, nil, true) } -func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr PathExpression, dup map[*byte]struct{}, one bool) []BinaryJSON { +func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr JSONPathExpression, dup map[*byte]struct{}, one bool) []BinaryJSON { if len(pathExpr.legs) == 0 { if dup != nil { if _, exists := dup[&bj.Value[0]]; exists { @@ -262,8 +262,8 @@ func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr PathExpression, dup ma return append(buf, bj) } currentLeg, subPathExpr := pathExpr.popOneLeg() - if currentLeg.typ == pathLegIndex { - if bj.TypeCode != TypeCodeArray { + if currentLeg.typ == jsonPathLegIndex { + if bj.TypeCode != JSONTypeCodeArray { if currentLeg.arrayIndex <= 0 && currentLeg.arrayIndex != arrayIndexAsterisk { buf = bj.extractTo(buf, subPathExpr, dup, one) } @@ -271,16 +271,16 @@ func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr PathExpression, dup ma } elemCount := bj.GetElemCount() if currentLeg.arrayIndex == arrayIndexAsterisk { - for i := 0; i < elemCount && !finished(buf, one); i++ { + for i := 0; i < elemCount && !jsonFinished(buf, one); i++ { buf = bj.arrayGetElem(i).extractTo(buf, subPathExpr, dup, one) } } else if currentLeg.arrayIndex < elemCount { buf = bj.arrayGetElem(currentLeg.arrayIndex).extractTo(buf, subPathExpr, dup, one) } - } else if currentLeg.typ == pathLegKey && bj.TypeCode == TypeCodeObject { + } else if currentLeg.typ == jsonPathLegKey && bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() if currentLeg.dotKey == "*" { - for i := 0; i < elemCount && !finished(buf, one); i++ { + for i := 0; i < elemCount && !jsonFinished(buf, one); i++ { buf = bj.objectGetVal(i).extractTo(buf, subPathExpr, dup, one) } } else { @@ -289,16 +289,16 @@ func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr PathExpression, dup ma buf = child.extractTo(buf, subPathExpr, dup, one) } } - } else if currentLeg.typ == pathLegDoubleAsterisk { + } else if currentLeg.typ == jsonPathLegDoubleAsterisk { buf = bj.extractTo(buf, subPathExpr, dup, one) - if bj.TypeCode == TypeCodeArray { + if bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() - for i := 0; i < elemCount && !finished(buf, one); i++ { + for i := 0; i < elemCount && !jsonFinished(buf, one); i++ { buf = bj.arrayGetElem(i).extractTo(buf, pathExpr, dup, one) } - } else if bj.TypeCode == TypeCodeObject { + } else if bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() - for i := 0; i < elemCount && !finished(buf, one); i++ { + for i := 0; i < elemCount && !jsonFinished(buf, one); i++ { buf = bj.objectGetVal(i).extractTo(buf, pathExpr, dup, one) } } @@ -306,7 +306,7 @@ func (bj BinaryJSON) extractTo(buf []BinaryJSON, pathExpr PathExpression, dup ma return buf } -func finished(buf []BinaryJSON, one bool) bool { +func jsonFinished(buf []BinaryJSON, one bool) bool { return one && len(buf) > 0 } @@ -321,61 +321,61 @@ func (bj BinaryJSON) objectSearchKey(key []byte) (BinaryJSON, bool) { return BinaryJSON{}, false } -func buildBinaryArray(elems []BinaryJSON) BinaryJSON { +func buildBinaryJSONArray(elems []BinaryJSON) BinaryJSON { totalSize := headerSize + len(elems)*valEntrySize for _, elem := range elems { - if elem.TypeCode != TypeCodeLiteral { + if elem.TypeCode != JSONTypeCodeLiteral { totalSize += len(elem.Value) } } buf := make([]byte, headerSize+len(elems)*valEntrySize, totalSize) - endian.PutUint32(buf, uint32(len(elems))) - endian.PutUint32(buf[dataSizeOff:], uint32(totalSize)) - buf = buildBinaryElements(buf, headerSize, elems) - return BinaryJSON{TypeCode: TypeCodeArray, Value: buf} + jsonEndian.PutUint32(buf, uint32(len(elems))) + jsonEndian.PutUint32(buf[dataSizeOff:], uint32(totalSize)) + buf = buildBinaryJSONElements(buf, headerSize, elems) + return BinaryJSON{TypeCode: JSONTypeCodeArray, Value: buf} } -func buildBinaryElements(buf []byte, entryStart int, elems []BinaryJSON) []byte { +func buildBinaryJSONElements(buf []byte, entryStart int, elems []BinaryJSON) []byte { for i, elem := range elems { buf[entryStart+i*valEntrySize] = elem.TypeCode - if elem.TypeCode == TypeCodeLiteral { + if elem.TypeCode == JSONTypeCodeLiteral { buf[entryStart+i*valEntrySize+valTypeSize] = elem.Value[0] } else { - endian.PutUint32(buf[entryStart+i*valEntrySize+valTypeSize:], uint32(len(buf))) + jsonEndian.PutUint32(buf[entryStart+i*valEntrySize+valTypeSize:], uint32(len(buf))) buf = append(buf, elem.Value...) } } return buf } -func buildBinaryObject(keys [][]byte, elems []BinaryJSON) (BinaryJSON, error) { +func buildBinaryJSONObject(keys [][]byte, elems []BinaryJSON) (BinaryJSON, error) { totalSize := headerSize + len(elems)*(keyEntrySize+valEntrySize) for i, elem := range elems { - if elem.TypeCode != TypeCodeLiteral { + if elem.TypeCode != JSONTypeCodeLiteral { totalSize += len(elem.Value) } totalSize += len(keys[i]) } buf := make([]byte, headerSize+len(elems)*(keyEntrySize+valEntrySize), totalSize) - endian.PutUint32(buf, uint32(len(elems))) - endian.PutUint32(buf[dataSizeOff:], uint32(totalSize)) + jsonEndian.PutUint32(buf, uint32(len(elems))) + jsonEndian.PutUint32(buf[dataSizeOff:], uint32(totalSize)) for i, key := range keys { if len(key) > math.MaxUint16 { return BinaryJSON{}, ErrJSONObjectKeyTooLong } - endian.PutUint32(buf[headerSize+i*keyEntrySize:], uint32(len(buf))) - endian.PutUint16(buf[headerSize+i*keyEntrySize+keyLenOff:], uint16(len(key))) + jsonEndian.PutUint32(buf[headerSize+i*keyEntrySize:], uint32(len(buf))) + jsonEndian.PutUint16(buf[headerSize+i*keyEntrySize+keyLenOff:], uint16(len(key))) buf = append(buf, key...) } entryStart := headerSize + len(elems)*keyEntrySize - buf = buildBinaryElements(buf, entryStart, elems) - return BinaryJSON{TypeCode: TypeCodeObject, Value: buf}, nil + buf = buildBinaryJSONElements(buf, entryStart, elems) + return BinaryJSON{TypeCode: JSONTypeCodeObject, Value: buf}, nil } // Modify modifies a JSON object by insert, replace or set. // All path expressions cannot contain * or ** wildcard. // If any error occurs, the input won't be changed. -func (bj BinaryJSON) Modify(pathExprList []PathExpression, values []BinaryJSON, mt ModifyType) (retj BinaryJSON, err error) { +func (bj BinaryJSON) Modify(pathExprList []JSONPathExpression, values []BinaryJSON, mt JSONModifyType) (retj BinaryJSON, err error) { if len(pathExprList) != len(values) { // TODO: should return 1582(42000) return retj, errors.New("Incorrect parameter count") @@ -390,11 +390,11 @@ func (bj BinaryJSON) Modify(pathExprList []PathExpression, values []BinaryJSON, pathExpr, value := pathExprList[i], values[i] modifier := &binaryModifier{bj: bj} switch mt { - case ModifyInsert: + case JSONModifyInsert: bj = modifier.insert(pathExpr, value) - case ModifyReplace: + case JSONModifyReplace: bj = modifier.replace(pathExpr, value) - case ModifySet: + case JSONModifySet: bj = modifier.set(pathExpr, value) } if modifier.err != nil { @@ -407,18 +407,18 @@ func (bj BinaryJSON) Modify(pathExprList []PathExpression, values []BinaryJSON, // ArrayInsert insert a BinaryJSON into the given array cell. // All path expressions cannot contain * or ** wildcard. // If any error occurs, the input won't be changed. -func (bj BinaryJSON) ArrayInsert(pathExpr PathExpression, value BinaryJSON) (res BinaryJSON, err error) { +func (bj BinaryJSON) ArrayInsert(pathExpr JSONPathExpression, value BinaryJSON) (res BinaryJSON, err error) { // Check the path is a index if len(pathExpr.legs) < 1 { return bj, ErrInvalidJSONPathArrayCell } parentPath, lastLeg := pathExpr.popOneLastLeg() - if lastLeg.typ != pathLegIndex { + if lastLeg.typ != jsonPathLegIndex { return bj, ErrInvalidJSONPathArrayCell } // Find the target array - obj, exists := bj.Extract([]PathExpression{parentPath}) - if !exists || obj.TypeCode != TypeCodeArray { + obj, exists := bj.Extract([]JSONPathExpression{parentPath}) + if !exists || obj.TypeCode != JSONTypeCodeArray { return bj, nil } @@ -438,9 +438,9 @@ func (bj BinaryJSON) ArrayInsert(pathExpr PathExpression, value BinaryJSON) (res elem := obj.arrayGetElem(i) newArray = append(newArray, elem) } - obj = buildBinaryArray(newArray) + obj = buildBinaryJSONArray(newArray) - bj, err = bj.Modify([]PathExpression{parentPath}, []BinaryJSON{obj}, ModifySet) + bj, err = bj.Modify([]JSONPathExpression{parentPath}, []BinaryJSON{obj}, JSONModifySet) if err != nil { return bj, err } @@ -448,7 +448,7 @@ func (bj BinaryJSON) ArrayInsert(pathExpr PathExpression, value BinaryJSON) (res } // Remove removes the elements indicated by pathExprList from JSON. -func (bj BinaryJSON) Remove(pathExprList []PathExpression) (BinaryJSON, error) { +func (bj BinaryJSON) Remove(pathExprList []JSONPathExpression) (BinaryJSON, error) { for _, pathExpr := range pathExprList { if len(pathExpr.legs) == 0 { // TODO: should return 3153(42000) @@ -474,7 +474,7 @@ type binaryModifier struct { err error } -func (bm *binaryModifier) set(path PathExpression, newBj BinaryJSON) BinaryJSON { +func (bm *binaryModifier) set(path JSONPathExpression, newBj BinaryJSON) BinaryJSON { result := bm.bj.extractOne(path) if len(result) > 0 { bm.modifyPtr = &result[0].Value[0] @@ -488,7 +488,7 @@ func (bm *binaryModifier) set(path PathExpression, newBj BinaryJSON) BinaryJSON return bm.rebuild() } -func (bm *binaryModifier) replace(path PathExpression, newBj BinaryJSON) BinaryJSON { +func (bm *binaryModifier) replace(path JSONPathExpression, newBj BinaryJSON) BinaryJSON { result := bm.bj.extractOne(path) if len(result) == 0 { return bm.bj @@ -498,7 +498,7 @@ func (bm *binaryModifier) replace(path PathExpression, newBj BinaryJSON) BinaryJ return bm.rebuild() } -func (bm *binaryModifier) insert(path PathExpression, newBj BinaryJSON) BinaryJSON { +func (bm *binaryModifier) insert(path JSONPathExpression, newBj BinaryJSON) BinaryJSON { result := bm.bj.extractOne(path) if len(result) > 0 { return bm.bj @@ -511,17 +511,17 @@ func (bm *binaryModifier) insert(path PathExpression, newBj BinaryJSON) BinaryJS } // doInsert inserts the newBj to its parent, and builds the new parent. -func (bm *binaryModifier) doInsert(path PathExpression, newBj BinaryJSON) { +func (bm *binaryModifier) doInsert(path JSONPathExpression, newBj BinaryJSON) { parentPath, lastLeg := path.popOneLastLeg() result := bm.bj.extractOne(parentPath) if len(result) == 0 { return } parentBj := result[0] - if lastLeg.typ == pathLegIndex { + if lastLeg.typ == jsonPathLegIndex { bm.modifyPtr = &parentBj.Value[0] - if parentBj.TypeCode != TypeCodeArray { - bm.modifyValue = buildBinaryArray([]BinaryJSON{parentBj, newBj}) + if parentBj.TypeCode != JSONTypeCodeArray { + bm.modifyValue = buildBinaryJSONArray([]BinaryJSON{parentBj, newBj}) return } elemCount := parentBj.GetElemCount() @@ -530,10 +530,10 @@ func (bm *binaryModifier) doInsert(path PathExpression, newBj BinaryJSON) { elems = append(elems, parentBj.arrayGetElem(i)) } elems = append(elems, newBj) - bm.modifyValue = buildBinaryArray(elems) + bm.modifyValue = buildBinaryJSONArray(elems) return } - if parentBj.TypeCode != TypeCodeObject { + if parentBj.TypeCode != JSONTypeCodeObject { return } bm.modifyPtr = &parentBj.Value[0] @@ -556,10 +556,10 @@ func (bm *binaryModifier) doInsert(path PathExpression, newBj BinaryJSON) { keys = append(keys, insertKey) elems = append(elems, newBj) } - bm.modifyValue, bm.err = buildBinaryObject(keys, elems) + bm.modifyValue, bm.err = buildBinaryJSONObject(keys, elems) } -func (bm *binaryModifier) remove(path PathExpression) BinaryJSON { +func (bm *binaryModifier) remove(path JSONPathExpression) BinaryJSON { result := bm.bj.extractOne(path) if len(result) == 0 { return bm.bj @@ -571,15 +571,15 @@ func (bm *binaryModifier) remove(path PathExpression) BinaryJSON { return bm.rebuild() } -func (bm *binaryModifier) doRemove(path PathExpression) { +func (bm *binaryModifier) doRemove(path JSONPathExpression) { parentPath, lastLeg := path.popOneLastLeg() result := bm.bj.extractOne(parentPath) if len(result) == 0 { return } parentBj := result[0] - if lastLeg.typ == pathLegIndex { - if parentBj.TypeCode != TypeCodeArray { + if lastLeg.typ == jsonPathLegIndex { + if parentBj.TypeCode != JSONTypeCodeArray { return } bm.modifyPtr = &parentBj.Value[0] @@ -590,10 +590,10 @@ func (bm *binaryModifier) doRemove(path PathExpression) { elems = append(elems, parentBj.arrayGetElem(i)) } } - bm.modifyValue = buildBinaryArray(elems) + bm.modifyValue = buildBinaryJSONArray(elems) return } - if parentBj.TypeCode != TypeCodeObject { + if parentBj.TypeCode != JSONTypeCodeObject { return } bm.modifyPtr = &parentBj.Value[0] @@ -608,7 +608,7 @@ func (bm *binaryModifier) doRemove(path PathExpression) { elems = append(elems, parentBj.objectGetVal(i)) } } - bm.modifyValue, bm.err = buildBinaryObject(keys, elems) + bm.modifyValue, bm.err = buildBinaryJSONObject(keys, elems) } // rebuild merges the old and the modified JSON into a new BinaryJSON @@ -618,7 +618,7 @@ func (bm *binaryModifier) rebuild() BinaryJSON { return BinaryJSON{TypeCode: tpCode, Value: value} } -func (bm *binaryModifier) rebuildTo(buf []byte) ([]byte, TypeCode) { +func (bm *binaryModifier) rebuildTo(buf []byte) ([]byte, JSONTypeCode) { if bm.modifyPtr == &bm.bj.Value[0] { bm.modifyPtr = nil return append(buf, bm.modifyValue.Value...), bm.modifyValue.TypeCode @@ -627,13 +627,13 @@ func (bm *binaryModifier) rebuildTo(buf []byte) ([]byte, TypeCode) { } bj := bm.bj switch bj.TypeCode { - case TypeCodeLiteral, TypeCodeInt64, TypeCodeUint64, TypeCodeFloat64, TypeCodeString, TypeCodeOpaque: + case JSONTypeCodeLiteral, JSONTypeCodeInt64, JSONTypeCodeUint64, JSONTypeCodeFloat64, JSONTypeCodeString, JSONTypeCodeOpaque: return append(buf, bj.Value...), bj.TypeCode } docOff := len(buf) elemCount := bj.GetElemCount() var valEntryStart int - if bj.TypeCode == TypeCodeArray { + if bj.TypeCode == JSONTypeCodeArray { copySize := headerSize + elemCount*valEntrySize valEntryStart = headerSize buf = append(buf, bj.Value[:copySize]...) @@ -642,9 +642,9 @@ func (bm *binaryModifier) rebuildTo(buf []byte) ([]byte, TypeCode) { valEntryStart = headerSize + elemCount*keyEntrySize buf = append(buf, bj.Value[:copySize]...) if elemCount > 0 { - firstKeyOff := int(endian.Uint32(bj.Value[headerSize:])) - lastKeyOff := int(endian.Uint32(bj.Value[headerSize+(elemCount-1)*keyEntrySize:])) - lastKeyLen := int(endian.Uint16(bj.Value[headerSize+(elemCount-1)*keyEntrySize+keyLenOff:])) + firstKeyOff := int(jsonEndian.Uint32(bj.Value[headerSize:])) + lastKeyOff := int(jsonEndian.Uint32(bj.Value[headerSize+(elemCount-1)*keyEntrySize:])) + lastKeyLen := int(jsonEndian.Uint16(bj.Value[headerSize+(elemCount-1)*keyEntrySize+keyLenOff:])) buf = append(buf, bj.Value[firstKeyOff:lastKeyOff+lastKeyLen]...) } } @@ -652,19 +652,19 @@ func (bm *binaryModifier) rebuildTo(buf []byte) ([]byte, TypeCode) { valEntryOff := valEntryStart + i*valEntrySize elem := bj.valEntryGet(valEntryOff) bm.bj = elem - var tpCode TypeCode + var tpCode JSONTypeCode valOff := len(buf) - docOff buf, tpCode = bm.rebuildTo(buf) buf[docOff+valEntryOff] = tpCode - if tpCode == TypeCodeLiteral { + if tpCode == JSONTypeCodeLiteral { lastIdx := len(buf) - 1 - endian.PutUint32(buf[docOff+valEntryOff+valTypeSize:], uint32(buf[lastIdx])) + jsonEndian.PutUint32(buf[docOff+valEntryOff+valTypeSize:], uint32(buf[lastIdx])) buf = buf[:lastIdx] } else { - endian.PutUint32(buf[docOff+valEntryOff+valTypeSize:], uint32(valOff)) + jsonEndian.PutUint32(buf[docOff+valEntryOff+valTypeSize:], uint32(valOff)) } } - endian.PutUint32(buf[docOff+dataSizeOff:], uint32(len(buf)-docOff)) + jsonEndian.PutUint32(buf[docOff+dataSizeOff:], uint32(len(buf)-docOff)) return buf, bj.TypeCode } @@ -727,9 +727,9 @@ func compareFloat64Uint64(x float64, y uint64) int { return compareFloat64PrecisionLoss(x, float64(y)) } -// CompareBinary compares two binary json objects. Returns -1 if left < right, +// CompareBinaryJSON compares two binary json objects. Returns -1 if left < right, // 0 if left == right, else returns 1. -func CompareBinary(left, right BinaryJSON) int { +func CompareBinaryJSON(left, right BinaryJSON) int { precedence1 := jsonTypePrecedences[left.Type()] precedence2 := jsonTypePrecedences[right.Type()] var cmp int @@ -739,51 +739,51 @@ func CompareBinary(left, right BinaryJSON) int { cmp = 0 } switch left.TypeCode { - case TypeCodeLiteral: + case JSONTypeCodeLiteral: // false is less than true. cmp = int(right.Value[0]) - int(left.Value[0]) - case TypeCodeInt64: + case JSONTypeCodeInt64: switch right.TypeCode { - case TypeCodeInt64: + case JSONTypeCodeInt64: cmp = compareInt64(left.GetInt64(), right.GetInt64()) - case TypeCodeUint64: + case JSONTypeCodeUint64: cmp = compareInt64Uint64(left.GetInt64(), right.GetUint64()) - case TypeCodeFloat64: + case JSONTypeCodeFloat64: cmp = -compareFloat64Int64(right.GetFloat64(), left.GetInt64()) } - case TypeCodeUint64: + case JSONTypeCodeUint64: switch right.TypeCode { - case TypeCodeInt64: + case JSONTypeCodeInt64: cmp = -compareInt64Uint64(right.GetInt64(), left.GetUint64()) - case TypeCodeUint64: + case JSONTypeCodeUint64: cmp = compareUint64(left.GetUint64(), right.GetUint64()) - case TypeCodeFloat64: + case JSONTypeCodeFloat64: cmp = -compareFloat64Uint64(right.GetFloat64(), left.GetUint64()) } - case TypeCodeFloat64: + case JSONTypeCodeFloat64: switch right.TypeCode { - case TypeCodeInt64: + case JSONTypeCodeInt64: cmp = compareFloat64Int64(left.GetFloat64(), right.GetInt64()) - case TypeCodeUint64: + case JSONTypeCodeUint64: cmp = compareFloat64Uint64(left.GetFloat64(), right.GetUint64()) - case TypeCodeFloat64: + case JSONTypeCodeFloat64: cmp = compareFloat64(left.GetFloat64(), right.GetFloat64()) } - case TypeCodeString: + case JSONTypeCodeString: cmp = bytes.Compare(left.GetString(), right.GetString()) - case TypeCodeArray: + case JSONTypeCodeArray: leftCount := left.GetElemCount() rightCount := right.GetElemCount() for i := 0; i < leftCount && i < rightCount; i++ { elem1 := left.arrayGetElem(i) elem2 := right.arrayGetElem(i) - cmp = CompareBinary(elem1, elem2) + cmp = CompareBinaryJSON(elem1, elem2) if cmp != 0 { return cmp } } cmp = leftCount - rightCount - case TypeCodeObject: + case JSONTypeCodeObject: // reference: // https://github.com/mysql/mysql-server/blob/ee4455a33b10f1b1886044322e4893f587b319ed/sql/json_dom.cc#L2561 leftCount, rightCount := left.GetElemCount(), right.GetElemCount() @@ -797,12 +797,12 @@ func CompareBinary(left, right BinaryJSON) int { if cmp != 0 { return cmp } - cmp = CompareBinary(left.objectGetVal(i), right.objectGetVal(i)) + cmp = CompareBinaryJSON(left.objectGetVal(i), right.objectGetVal(i)) if cmp != 0 { return cmp } } - case TypeCodeOpaque: + case JSONTypeCodeOpaque: cmp = bytes.Compare(left.GetOpaque().Buf, right.GetOpaque().Buf) } } else { @@ -816,9 +816,9 @@ func CompareBinary(left, right BinaryJSON) int { return cmp } -// MergePatchBinary implements RFC7396 +// MergePatchBinaryJSON implements RFC7396 // https://datatracker.ietf.org/doc/html/rfc7396 -func MergePatchBinary(bjs []*BinaryJSON) (*BinaryJSON, error) { +func MergePatchBinaryJSON(bjs []*BinaryJSON) (*BinaryJSON, error) { var err error length := len(bjs) @@ -826,7 +826,7 @@ func MergePatchBinary(bjs []*BinaryJSON) (*BinaryJSON, error) { // when the last item is not object // we can return the last item directly for i := length - 1; i >= 0; i-- { - if bjs[i] == nil || bjs[i].TypeCode != TypeCodeObject { + if bjs[i] == nil || bjs[i].TypeCode != JSONTypeCodeObject { bjs = bjs[i:] break } @@ -834,7 +834,7 @@ func MergePatchBinary(bjs []*BinaryJSON) (*BinaryJSON, error) { target := bjs[0] for _, patch := range bjs[1:] { - target, err = mergePatchBinary(target, patch) + target, err = mergePatchBinaryJSON(target, patch) if err != nil { return nil, err } @@ -842,18 +842,18 @@ func MergePatchBinary(bjs []*BinaryJSON) (*BinaryJSON, error) { return target, nil } -func mergePatchBinary(target, patch *BinaryJSON) (result *BinaryJSON, err error) { +func mergePatchBinaryJSON(target, patch *BinaryJSON) (result *BinaryJSON, err error) { if patch == nil { return nil, nil } - if patch.TypeCode == TypeCodeObject { + if patch.TypeCode == JSONTypeCodeObject { if target == nil { return nil, nil } keyValMap := make(map[string]BinaryJSON) - if target.TypeCode == TypeCodeObject { + if target.TypeCode == JSONTypeCodeObject { elemCount := target.GetElemCount() for i := 0; i < elemCount; i++ { key := target.objectGetKey(i) @@ -869,12 +869,12 @@ func mergePatchBinary(target, patch *BinaryJSON) (result *BinaryJSON, err error) k := string(key) targetKV, exists := keyValMap[k] - if val.TypeCode == TypeCodeLiteral && val.Value[0] == LiteralNil { + if val.TypeCode == JSONTypeCodeLiteral && val.Value[0] == JSONLiteralNil { if exists { delete(keyValMap, k) } } else { - tmp, err = mergePatchBinary(&targetKV, &val) + tmp, err = mergePatchBinaryJSON(&targetKV, &val) if err != nil { return result, err } @@ -897,7 +897,7 @@ func mergePatchBinary(target, patch *BinaryJSON) (result *BinaryJSON, err error) values = append(values, keyValMap[string(keys[i])]) } - binaryObject, e := buildBinaryObject(keys, values) + binaryObject, e := buildBinaryJSONObject(keys, values) if e != nil { return nil, e } @@ -906,17 +906,17 @@ func mergePatchBinary(target, patch *BinaryJSON) (result *BinaryJSON, err error) return patch, nil } -// MergeBinary merges multiple BinaryJSON into one according the following rules: +// MergeBinaryJSON merges multiple BinaryJSON into one according the following rules: // 1) adjacent arrays are merged to a single array; // 2) adjacent object are merged to a single object; // 3) a scalar value is autowrapped as an array before merge; // 4) an adjacent array and object are merged by autowrapping the object as an array. -func MergeBinary(bjs []BinaryJSON) BinaryJSON { +func MergeBinaryJSON(bjs []BinaryJSON) BinaryJSON { var remain = bjs var objects []BinaryJSON var results []BinaryJSON for len(remain) > 0 { - if remain[0].TypeCode != TypeCodeObject { + if remain[0].TypeCode != JSONTypeCodeObject { results = append(results, remain[0]) remain = remain[1:] } else { @@ -932,7 +932,7 @@ func MergeBinary(bjs []BinaryJSON) BinaryJSON { func getAdjacentObjects(bjs []BinaryJSON) (objects, remain []BinaryJSON) { for i := 0; i < len(bjs); i++ { - if bjs[i].TypeCode != TypeCodeObject { + if bjs[i].TypeCode != JSONTypeCodeObject { return bjs[:i], bjs[i:] } } @@ -943,7 +943,7 @@ func mergeBinaryArray(elems []BinaryJSON) BinaryJSON { buf := make([]BinaryJSON, 0, len(elems)) for i := 0; i < len(elems); i++ { elem := elems[i] - if elem.TypeCode != TypeCodeArray { + if elem.TypeCode != JSONTypeCodeArray { buf = append(buf, elem) } else { childCount := elem.GetElemCount() @@ -952,7 +952,7 @@ func mergeBinaryArray(elems []BinaryJSON) BinaryJSON { } } } - return buildBinaryArray(buf) + return buildBinaryJSONArray(buf) } func mergeBinaryObject(objects []BinaryJSON) BinaryJSON { @@ -964,7 +964,7 @@ func mergeBinaryObject(objects []BinaryJSON) BinaryJSON { key := obj.objectGetKey(i) val := obj.objectGetVal(i) if old, ok := keyValMap[string(key)]; ok { - keyValMap[string(key)] = MergeBinary([]BinaryJSON{old, val}) + keyValMap[string(key)] = MergeBinaryJSON([]BinaryJSON{old, val}) } else { keyValMap[string(key)] = val keys = append(keys, key) @@ -978,7 +978,7 @@ func mergeBinaryObject(objects []BinaryJSON) BinaryJSON { for i, key := range keys { values[i] = keyValMap[string(key)] } - binaryObject, err := buildBinaryObject(keys, values) + binaryObject, err := buildBinaryJSONObject(keys, values) if err != nil { panic("mergeBinaryObject should never panic, please contact the TiDB team for help") } @@ -993,22 +993,22 @@ func PeekBytesAsJSON(b []byte) (n int, err error) { return } switch c := b[0]; c { - case TypeCodeObject, TypeCodeArray: + case JSONTypeCodeObject, JSONTypeCodeArray: if len(b) >= valTypeSize+headerSize { - size := endian.Uint32(b[valTypeSize+dataSizeOff:]) + size := jsonEndian.Uint32(b[valTypeSize+dataSizeOff:]) n = valTypeSize + int(size) return } - case TypeCodeString: + case JSONTypeCodeString: strLen, lenLen := binary.Uvarint(b[valTypeSize:]) return valTypeSize + int(strLen) + lenLen, nil - case TypeCodeInt64, TypeCodeUint64, TypeCodeFloat64: + case JSONTypeCodeInt64, JSONTypeCodeUint64, JSONTypeCodeFloat64: n = valTypeSize + 8 return - case TypeCodeLiteral: + case JSONTypeCodeLiteral: n = valTypeSize + 1 return - case TypeCodeOpaque: + case JSONTypeCodeOpaque: bufLen, lenLen := binary.Uvarint(b[valTypeSize+1:]) return valTypeSize + 1 + int(bufLen) + lenLen, nil } @@ -1016,31 +1016,31 @@ func PeekBytesAsJSON(b []byte) (n int, err error) { return } -// ContainsBinary check whether JSON document contains specific target according the following rules: +// ContainsBinaryJSON check whether JSON document contains specific target according the following rules: // 1) object contains a target object if and only if every key is contained in source object and the value associated with the target key is contained in the value associated with the source key; // 2) array contains a target nonarray if and only if the target is contained in some element of the array; // 3) array contains a target array if and only if every element is contained in some element of the array; // 4) scalar contains a target scalar if and only if they are comparable and are equal; -func ContainsBinary(obj, target BinaryJSON) bool { +func ContainsBinaryJSON(obj, target BinaryJSON) bool { switch obj.TypeCode { - case TypeCodeObject: - if target.TypeCode == TypeCodeObject { + case JSONTypeCodeObject: + if target.TypeCode == JSONTypeCodeObject { elemCount := target.GetElemCount() for i := 0; i < elemCount; i++ { key := target.objectGetKey(i) val := target.objectGetVal(i) - if exp, exists := obj.objectSearchKey(key); !exists || !ContainsBinary(exp, val) { + if exp, exists := obj.objectSearchKey(key); !exists || !ContainsBinaryJSON(exp, val) { return false } } return true } return false - case TypeCodeArray: - if target.TypeCode == TypeCodeArray { + case JSONTypeCodeArray: + if target.TypeCode == JSONTypeCodeArray { elemCount := target.GetElemCount() for i := 0; i < elemCount; i++ { - if !ContainsBinary(obj, target.arrayGetElem(i)) { + if !ContainsBinaryJSON(obj, target.arrayGetElem(i)) { return false } } @@ -1048,13 +1048,13 @@ func ContainsBinary(obj, target BinaryJSON) bool { } elemCount := obj.GetElemCount() for i := 0; i < elemCount; i++ { - if ContainsBinary(obj.arrayGetElem(i), target) { + if ContainsBinaryJSON(obj.arrayGetElem(i), target) { return true } } return false default: - return CompareBinary(obj, target) == 0 + return CompareBinaryJSON(obj, target) == 0 } } @@ -1070,7 +1070,7 @@ func ContainsBinary(obj, target BinaryJSON) bool { // e.g. depth of '[10, {"a": 20}]': 3 func (bj BinaryJSON) GetElemDepth() int { switch bj.TypeCode { - case TypeCodeObject: + case JSONTypeCodeObject: elemCount := bj.GetElemCount() maxDepth := 0 for i := 0; i < elemCount; i++ { @@ -1081,7 +1081,7 @@ func (bj BinaryJSON) GetElemDepth() int { } } return maxDepth + 1 - case TypeCodeArray: + case JSONTypeCodeArray: elemCount := bj.GetElemCount() maxDepth := 0 for i := 0; i < elemCount; i++ { @@ -1100,17 +1100,17 @@ func (bj BinaryJSON) GetElemDepth() int { // Search for JSON_Search // rules referenced by MySQL JSON_SEARCH function // [https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-search] -func (bj BinaryJSON) Search(containType string, search string, escape byte, pathExpres []PathExpression) (res BinaryJSON, isNull bool, err error) { - if containType != ContainsPathOne && containType != ContainsPathAll { +func (bj BinaryJSON) Search(containType string, search string, escape byte, pathExpres []JSONPathExpression) (res BinaryJSON, isNull bool, err error) { + if containType != JSONContainsPathOne && containType != JSONContainsPathAll { return res, true, ErrInvalidJSONPath } patChars, patTypes := stringutil.CompilePattern(search, escape) result := make([]interface{}, 0) - walkFn := func(fullpath PathExpression, bj BinaryJSON) (stop bool, err error) { - if bj.TypeCode == TypeCodeString && stringutil.DoMatch(string(bj.GetString()), patChars, patTypes) { + walkFn := func(fullpath JSONPathExpression, bj BinaryJSON) (stop bool, err error) { + if bj.TypeCode == JSONTypeCodeString && stringutil.DoMatch(string(bj.GetString()), patChars, patTypes) { result = append(result, fullpath.String()) - if containType == ContainsPathOne { + if containType == JSONContainsPathOne { return true, nil } } @@ -1131,27 +1131,27 @@ func (bj BinaryJSON) Search(containType string, search string, escape byte, path case 0: return res, true, nil case 1: - return CreateBinary(result[0]), false, nil + return CreateBinaryJSON(result[0]), false, nil default: - return CreateBinary(result), false, nil + return CreateBinaryJSON(result), false, nil } } // extractCallbackFn the type of CALLBACK function for extractToCallback -type extractCallbackFn func(fullpath PathExpression, bj BinaryJSON) (stop bool, err error) +type extractCallbackFn func(fullpath JSONPathExpression, bj BinaryJSON) (stop bool, err error) // extractToCallback callback alternative of extractTo // // would be more effective when walk through the whole JSON is unnecessary // // NOTICE: path [0] & [*] for JSON object other than array is INVALID, which is different from extractTo. -func (bj BinaryJSON) extractToCallback(pathExpr PathExpression, callbackFn extractCallbackFn, fullpath PathExpression) (stop bool, err error) { +func (bj BinaryJSON) extractToCallback(pathExpr JSONPathExpression, callbackFn extractCallbackFn, fullpath JSONPathExpression) (stop bool, err error) { if len(pathExpr.legs) == 0 { return callbackFn(fullpath, bj) } currentLeg, subPathExpr := pathExpr.popOneLeg() - if currentLeg.typ == pathLegIndex && bj.TypeCode == TypeCodeArray { + if currentLeg.typ == jsonPathLegIndex && bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() if currentLeg.arrayIndex == arrayIndexAsterisk { for i := 0; i < elemCount; i++ { @@ -1170,7 +1170,7 @@ func (bj BinaryJSON) extractToCallback(pathExpr PathExpression, callbackFn extra return } } - } else if currentLeg.typ == pathLegKey && bj.TypeCode == TypeCodeObject { + } else if currentLeg.typ == jsonPathLegKey && bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() if currentLeg.dotKey == "*" { for i := 0; i < elemCount; i++ { @@ -1192,14 +1192,14 @@ func (bj BinaryJSON) extractToCallback(pathExpr PathExpression, callbackFn extra } } } - } else if currentLeg.typ == pathLegDoubleAsterisk { + } else if currentLeg.typ == jsonPathLegDoubleAsterisk { // buf = bj.extractTo(buf, subPathExpr) stop, err = bj.extractToCallback(subPathExpr, callbackFn, fullpath) if stop || err != nil { return } - if bj.TypeCode == TypeCodeArray { + if bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() for i := 0; i < elemCount; i++ { // buf = bj.arrayGetElem(i).extractTo(buf, pathExpr) @@ -1209,7 +1209,7 @@ func (bj BinaryJSON) extractToCallback(pathExpr PathExpression, callbackFn extra return } } - } else if bj.TypeCode == TypeCodeObject { + } else if bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() for i := 0; i < elemCount; i++ { // buf = bj.objectGetVal(i).extractTo(buf, pathExpr) @@ -1225,14 +1225,14 @@ func (bj BinaryJSON) extractToCallback(pathExpr PathExpression, callbackFn extra } // BinaryJSONWalkFunc is used as callback function for BinaryJSON.Walk -type BinaryJSONWalkFunc func(fullpath PathExpression, bj BinaryJSON) (stop bool, err error) +type BinaryJSONWalkFunc func(fullpath JSONPathExpression, bj BinaryJSON) (stop bool, err error) // Walk traverse BinaryJSON objects -func (bj BinaryJSON) Walk(walkFn BinaryJSONWalkFunc, pathExprList ...PathExpression) (err error) { +func (bj BinaryJSON) Walk(walkFn BinaryJSONWalkFunc, pathExprList ...JSONPathExpression) (err error) { pathSet := make(map[string]bool) var doWalk extractCallbackFn - doWalk = func(fullpath PathExpression, bj BinaryJSON) (stop bool, err error) { + doWalk = func(fullpath JSONPathExpression, bj BinaryJSON) (stop bool, err error) { pathStr := fullpath.String() if _, ok := pathSet[pathStr]; ok { return false, nil @@ -1244,7 +1244,7 @@ func (bj BinaryJSON) Walk(walkFn BinaryJSONWalkFunc, pathExprList ...PathExpress return } - if bj.TypeCode == TypeCodeArray { + if bj.TypeCode == JSONTypeCodeArray { elemCount := bj.GetElemCount() for i := 0; i < elemCount; i++ { path := fullpath.pushBackOneIndexLeg(i) @@ -1253,7 +1253,7 @@ func (bj BinaryJSON) Walk(walkFn BinaryJSONWalkFunc, pathExprList ...PathExpress return } } - } else if bj.TypeCode == TypeCodeObject { + } else if bj.TypeCode == JSONTypeCodeObject { elemCount := bj.GetElemCount() for i := 0; i < elemCount; i++ { path := fullpath.pushBackOneKeyLeg(string(bj.objectGetKey(i))) @@ -1266,7 +1266,7 @@ func (bj BinaryJSON) Walk(walkFn BinaryJSONWalkFunc, pathExprList ...PathExpress return false, nil } - fullpath := PathExpression{legs: make([]pathLeg, 0, 32), flags: pathExpressionFlag(0)} + fullpath := JSONPathExpression{legs: make([]jsonPathLeg, 0, 32), flags: jsonPathExpressionFlag(0)} if len(pathExprList) > 0 { for _, pathExpr := range pathExprList { var stop bool diff --git a/types/json/binary_functions_test.go b/types/json_binary_functions_test.go similarity index 60% rename from types/json/binary_functions_test.go rename to types/json_binary_functions_test.go index 34f110154962a..fa60471412f98 100644 --- a/types/json/binary_functions_test.go +++ b/types/json_binary_functions_test.go @@ -11,7 +11,7 @@ // 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 +package types import ( "testing" @@ -35,18 +35,18 @@ func BenchmarkDecodeEscapedUnicode(b *testing.B) { } func BenchmarkMergePatchBinary(b *testing.B) { - valueA, _ := ParseBinaryFromString(`{"title":"Goodbye!","author":{"givenName":"John","familyName":"Doe"},"tags":["example","sample"],"content":"This will be unchanged"}`) - valueB, _ := ParseBinaryFromString(`{"title":"Hello!","phoneNumber":"+01-123-456-7890","author":{"familyName":null},"tags":["example"]}`) + valueA, _ := ParseBinaryJSONFromString(`{"title":"Goodbye!","author":{"givenName":"John","familyName":"Doe"},"tags":["example","sample"],"content":"This will be unchanged"}`) + valueB, _ := ParseBinaryJSONFromString(`{"title":"Hello!","phoneNumber":"+01-123-456-7890","author":{"familyName":null},"tags":["example"]}`) for i := 0; i < b.N; i++ { - _, _ = MergePatchBinary([]*BinaryJSON{&valueA, &valueB}) + _, _ = MergePatchBinaryJSON([]*BinaryJSON{&valueA, &valueB}) } } func BenchmarkMergeBinary(b *testing.B) { - valueA, _ := ParseBinaryFromString(`{"title":"Goodbye!","author":{"givenName":"John","familyName":"Doe"},"tags":["example","sample"],"content":"This will be unchanged"}`) - valueB, _ := ParseBinaryFromString(`{"title":"Hello!","phoneNumber":"+01-123-456-7890","author":{"familyName":null},"tags":["example"]}`) + valueA, _ := ParseBinaryJSONFromString(`{"title":"Goodbye!","author":{"givenName":"John","familyName":"Doe"},"tags":["example","sample"],"content":"This will be unchanged"}`) + valueB, _ := ParseBinaryJSONFromString(`{"title":"Hello!","phoneNumber":"+01-123-456-7890","author":{"familyName":null},"tags":["example"]}`) for i := 0; i < b.N; i++ { - _ = MergeBinary([]BinaryJSON{valueA, valueB}) + _ = MergeBinaryJSON([]BinaryJSON{valueA, valueB}) } } @@ -57,35 +57,35 @@ func TestBinaryCompare(t *testing.T) { result int }{ { - CreateBinary("a"), - CreateBinary("b"), + CreateBinaryJSON("a"), + CreateBinaryJSON("b"), -1, }, { - CreateBinary(Opaque{ + CreateBinaryJSON(Opaque{ TypeCode: 0, Buf: []byte{0, 1, 2, 3}, }), - CreateBinary(Opaque{ + CreateBinaryJSON(Opaque{ TypeCode: 0, Buf: []byte{0, 1, 2}, }), 1, }, { - CreateBinary(Opaque{ + CreateBinaryJSON(Opaque{ TypeCode: 0, Buf: []byte{0, 1, 2, 3}, }), - CreateBinary(Opaque{ + CreateBinaryJSON(Opaque{ TypeCode: 0, Buf: []byte{0, 2, 1}, }), -1, }, { - CreateBinary("test"), - CreateBinary(Opaque{ + CreateBinaryJSON("test"), + CreateBinaryJSON(Opaque{ TypeCode: 0, Buf: []byte{0, 2, 1}, }), @@ -100,6 +100,6 @@ func TestBinaryCompare(t *testing.T) { } for _, test := range tests { - require.Equal(t, test.result, CompareBinary(test.left, test.right), "%s should be %s %s", test.left.String(), compareMsg[test.result], test.right.String()) + require.Equal(t, test.result, CompareBinaryJSON(test.left, test.right), "%s should be %s %s", test.left.String(), compareMsg[test.result], test.right.String()) } } diff --git a/types/json/binary_test.go b/types/json_binary_test.go similarity index 80% rename from types/json/binary_test.go rename to types/json_binary_test.go index 76d75d29bd784..a7b5579815bd4 100644 --- a/types/json/binary_test.go +++ b/types/json_binary_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package json +package types import ( "fmt" @@ -23,6 +23,8 @@ import ( "github.com/stretchr/testify/require" ) +const jsonBenchStr = `{"a":[1,"2",{"aa":"bb"},4,null],"b":true,"c":null}` + func TestBinaryJSONMarshalUnmarshal(t *testing.T) { expectedList := []string{ `{"a": [1, "2", {"aa": "bb"}, 4, null], "b": true, "c": null}`, @@ -85,7 +87,7 @@ func TestBinaryJSONExtract(t *testing.T) { } for _, test := range tests { - var pathExprList = make([]PathExpression, 0) + var pathExprList = make([]JSONPathExpression, 0) for _, peStr := range test.pathExprStrings { pe, err := ParseJSONPathExpr(peStr) require.NoError(t, err) @@ -120,7 +122,7 @@ func TestBinaryJSONType(t *testing.T) { // we can't parse '9223372036854775808' to JSON::Uint64 now, // because go builtin JSON parser treats that as DOUBLE. - require.Equal(t, "UNSIGNED INTEGER", CreateBinary(uint64(1<<63)).Type()) + require.Equal(t, "UNSIGNED INTEGER", CreateBinaryJSON(uint64(1<<63)).Type()) } func TestBinaryJSONUnquote(t *testing.T) { @@ -167,7 +169,7 @@ func TestQuoteString(t *testing.T) { } for _, test := range tests { - require.Equal(t, test.quoted, quoteString(test.raw)) + require.Equal(t, test.quoted, quoteJSONString(test.raw)) } } @@ -178,34 +180,34 @@ func TestBinaryJSONModify(t *testing.T) { setValue string expected string success bool - mt ModifyType + mt JSONModifyType }{ - {`null`, "$", `{}`, `{}`, true, ModifySet}, - {`{}`, "$.a", `3`, `{"a": 3}`, true, ModifySet}, - {`{"a": 3}`, "$.a", `[]`, `{"a": []}`, true, ModifyReplace}, - {`{"a": 3}`, "$.b", `"3"`, `{"a": 3, "b": "3"}`, true, ModifySet}, - {`{"a": []}`, "$.a[0]", `3`, `{"a": [3]}`, true, ModifySet}, - {`{"a": [3]}`, "$.a[1]", `4`, `{"a": [3, 4]}`, true, ModifyInsert}, - {`{"a": [3]}`, "$[0]", `4`, `4`, true, ModifySet}, - {`{"a": [3]}`, "$[1]", `4`, `[{"a": [3]}, 4]`, true, ModifySet}, - {`{"b": true}`, "$.b", `false`, `{"b": false}`, true, ModifySet}, + {`null`, "$", `{}`, `{}`, true, JSONModifySet}, + {`{}`, "$.a", `3`, `{"a": 3}`, true, JSONModifySet}, + {`{"a": 3}`, "$.a", `[]`, `{"a": []}`, true, JSONModifyReplace}, + {`{"a": 3}`, "$.b", `"3"`, `{"a": 3, "b": "3"}`, true, JSONModifySet}, + {`{"a": []}`, "$.a[0]", `3`, `{"a": [3]}`, true, JSONModifySet}, + {`{"a": [3]}`, "$.a[1]", `4`, `{"a": [3, 4]}`, true, JSONModifyInsert}, + {`{"a": [3]}`, "$[0]", `4`, `4`, true, JSONModifySet}, + {`{"a": [3]}`, "$[1]", `4`, `[{"a": [3]}, 4]`, true, JSONModifySet}, + {`{"b": true}`, "$.b", `false`, `{"b": false}`, true, JSONModifySet}, // nothing changed because the path is empty and we want to insert. - {`{}`, "$", `1`, `{}`, true, ModifyInsert}, + {`{}`, "$", `1`, `{}`, true, JSONModifyInsert}, // nothing changed because the path without last leg doesn't exist. - {`{"a": [3, 4]}`, "$.b[1]", `3`, `{"a": [3, 4]}`, true, ModifySet}, + {`{"a": [3, 4]}`, "$.b[1]", `3`, `{"a": [3, 4]}`, true, JSONModifySet}, // nothing changed because the path without last leg doesn't exist. - {`{"a": [3, 4]}`, "$.a[2].b", `3`, `{"a": [3, 4]}`, true, ModifySet}, + {`{"a": [3, 4]}`, "$.a[2].b", `3`, `{"a": [3, 4]}`, true, JSONModifySet}, // nothing changed because we want to insert but the full path exists. - {`{"a": [3, 4]}`, "$.a[0]", `30`, `{"a": [3, 4]}`, true, ModifyInsert}, + {`{"a": [3, 4]}`, "$.a[0]", `30`, `{"a": [3, 4]}`, true, JSONModifyInsert}, // nothing changed because we want to replace but the full path doesn't exist. - {`{"a": [3, 4]}`, "$.a[2]", `30`, `{"a": [3, 4]}`, true, ModifyReplace}, + {`{"a": [3, 4]}`, "$.a[2]", `30`, `{"a": [3, 4]}`, true, JSONModifyReplace}, // bad path expression. - {"null", "$.*", "{}", "null", false, ModifySet}, - {"null", "$[*]", "{}", "null", false, ModifySet}, - {"null", "$**.a", "{}", "null", false, ModifySet}, - {"null", "$**[3]", "{}", "null", false, ModifySet}, + {"null", "$.*", "{}", "null", false, JSONModifySet}, + {"null", "$[*]", "{}", "null", false, JSONModifySet}, + {"null", "$**.a", "{}", "null", false, JSONModifySet}, + {"null", "$**[3]", "{}", "null", false, JSONModifySet}, } for _, test := range tests { @@ -215,7 +217,7 @@ func TestBinaryJSONModify(t *testing.T) { base := mustParseBinaryFromString(t, test.base) value := mustParseBinaryFromString(t, test.setValue) expected := mustParseBinaryFromString(t, test.expected) - obtain, err := base.Modify([]PathExpression{pathExpr}, []BinaryJSON{value}, test.mt) + obtain, err := base.Modify([]JSONPathExpression{pathExpr}, []BinaryJSON{value}, test.mt) if test.success { require.NoError(t, err) require.Equal(t, expected.String(), obtain.String()) @@ -251,7 +253,7 @@ func TestBinaryJSONRemove(t *testing.T) { base := mustParseBinaryFromString(t, test.base) expected := mustParseBinaryFromString(t, test.expected) - obtain, err := base.Remove([]PathExpression{pathExpr}) + obtain, err := base.Remove([]JSONPathExpression{pathExpr}) if test.success { require.NoError(t, err) require.Equal(t, expected.String(), obtain.String()) @@ -265,7 +267,7 @@ func TestCompareBinary(t *testing.T) { jNull := mustParseBinaryFromString(t, `null`) jBoolTrue := mustParseBinaryFromString(t, `true`) jBoolFalse := mustParseBinaryFromString(t, `false`) - jIntegerLarge := CreateBinary(uint64(1 << 63)) + jIntegerLarge := CreateBinaryJSON(uint64(1 << 63)) jIntegerSmall := mustParseBinaryFromString(t, `3`) jStringLarge := mustParseBinaryFromString(t, `"hello, world"`) jStringSmall := mustParseBinaryFromString(t, `"hello"`) @@ -287,39 +289,39 @@ func TestCompareBinary(t *testing.T) { {jArraySmall, jArrayLarge, -1}, {jArrayLarge, jBoolFalse, -1}, {jBoolFalse, jBoolTrue, -1}, - {CreateBinary(int64(922337203685477580)), CreateBinary(int64(922337203685477580)), 0}, - {CreateBinary(int64(922337203685477580)), CreateBinary(int64(922337203685477581)), -1}, - {CreateBinary(int64(922337203685477581)), CreateBinary(int64(922337203685477580)), 1}, + {CreateBinaryJSON(int64(922337203685477580)), CreateBinaryJSON(int64(922337203685477580)), 0}, + {CreateBinaryJSON(int64(922337203685477580)), CreateBinaryJSON(int64(922337203685477581)), -1}, + {CreateBinaryJSON(int64(922337203685477581)), CreateBinaryJSON(int64(922337203685477580)), 1}, - {CreateBinary(int64(-1)), CreateBinary(uint64(18446744073709551615)), -1}, - {CreateBinary(int64(922337203685477580)), CreateBinary(uint64(922337203685477581)), -1}, - {CreateBinary(int64(2)), CreateBinary(uint64(1)), 1}, - {CreateBinary(int64(math.MaxInt64)), CreateBinary(uint64(math.MaxInt64)), 0}, + {CreateBinaryJSON(int64(-1)), CreateBinaryJSON(uint64(18446744073709551615)), -1}, + {CreateBinaryJSON(int64(922337203685477580)), CreateBinaryJSON(uint64(922337203685477581)), -1}, + {CreateBinaryJSON(int64(2)), CreateBinaryJSON(uint64(1)), 1}, + {CreateBinaryJSON(int64(math.MaxInt64)), CreateBinaryJSON(uint64(math.MaxInt64)), 0}, - {CreateBinary(uint64(18446744073709551615)), CreateBinary(int64(-1)), 1}, - {CreateBinary(uint64(922337203685477581)), CreateBinary(int64(922337203685477580)), 1}, - {CreateBinary(uint64(1)), CreateBinary(int64(2)), -1}, - {CreateBinary(uint64(math.MaxInt64)), CreateBinary(int64(math.MaxInt64)), 0}, + {CreateBinaryJSON(uint64(18446744073709551615)), CreateBinaryJSON(int64(-1)), 1}, + {CreateBinaryJSON(uint64(922337203685477581)), CreateBinaryJSON(int64(922337203685477580)), 1}, + {CreateBinaryJSON(uint64(1)), CreateBinaryJSON(int64(2)), -1}, + {CreateBinaryJSON(uint64(math.MaxInt64)), CreateBinaryJSON(int64(math.MaxInt64)), 0}, - {CreateBinary(float64(9.0)), CreateBinary(int64(9)), 0}, - {CreateBinary(float64(8.9)), CreateBinary(int64(9)), -1}, - {CreateBinary(float64(9.1)), CreateBinary(int64(9)), 1}, + {CreateBinaryJSON(float64(9.0)), CreateBinaryJSON(int64(9)), 0}, + {CreateBinaryJSON(float64(8.9)), CreateBinaryJSON(int64(9)), -1}, + {CreateBinaryJSON(float64(9.1)), CreateBinaryJSON(int64(9)), 1}, - {CreateBinary(float64(9.0)), CreateBinary(uint64(9)), 0}, - {CreateBinary(float64(8.9)), CreateBinary(uint64(9)), -1}, - {CreateBinary(float64(9.1)), CreateBinary(uint64(9)), 1}, + {CreateBinaryJSON(float64(9.0)), CreateBinaryJSON(uint64(9)), 0}, + {CreateBinaryJSON(float64(8.9)), CreateBinaryJSON(uint64(9)), -1}, + {CreateBinaryJSON(float64(9.1)), CreateBinaryJSON(uint64(9)), 1}, - {CreateBinary(int64(9)), CreateBinary(float64(9.0)), 0}, - {CreateBinary(int64(9)), CreateBinary(float64(8.9)), 1}, - {CreateBinary(int64(9)), CreateBinary(float64(9.1)), -1}, + {CreateBinaryJSON(int64(9)), CreateBinaryJSON(float64(9.0)), 0}, + {CreateBinaryJSON(int64(9)), CreateBinaryJSON(float64(8.9)), 1}, + {CreateBinaryJSON(int64(9)), CreateBinaryJSON(float64(9.1)), -1}, - {CreateBinary(uint64(9)), CreateBinary(float64(9.0)), 0}, - {CreateBinary(uint64(9)), CreateBinary(float64(8.9)), 1}, - {CreateBinary(uint64(9)), CreateBinary(float64(9.1)), -1}, + {CreateBinaryJSON(uint64(9)), CreateBinaryJSON(float64(9.0)), 0}, + {CreateBinaryJSON(uint64(9)), CreateBinaryJSON(float64(8.9)), 1}, + {CreateBinaryJSON(uint64(9)), CreateBinaryJSON(float64(9.1)), -1}, } for _, test := range tests { - result := CompareBinary(test.left, test.right) + result := CompareBinaryJSON(test.left, test.right) comment := fmt.Sprintf("left: %v, right: %v, expect: %v, got: %v", test.left, test.right, test.result, result) require.Equal(t, test.result, result, comment) } @@ -347,22 +349,22 @@ func TestBinaryJSONMerge(t *testing.T) { for _, s := range test.suffixes { suffixes = append(suffixes, mustParseBinaryFromString(t, s)) } - result := MergeBinary(suffixes) - cmp := CompareBinary(result, mustParseBinaryFromString(t, test.expected)) + result := MergeBinaryJSON(suffixes) + cmp := CompareBinaryJSON(result, mustParseBinaryFromString(t, test.expected)) require.Equal(t, 0, cmp) } } func mustParseBinaryFromString(t *testing.T, s string) BinaryJSON { - result, err := ParseBinaryFromString(s) + result, err := ParseBinaryJSONFromString(s) require.NoError(t, err) return result } func BenchmarkBinaryMarshal(b *testing.B) { b.ReportAllocs() - b.SetBytes(int64(len(benchStr))) - bj, _ := ParseBinaryFromString(benchStr) + b.SetBytes(int64(len(jsonBenchStr))) + bj, _ := ParseBinaryJSONFromString(jsonBenchStr) for i := 0; i < b.N; i++ { _, _ = bj.MarshalJSON() } @@ -395,7 +397,7 @@ func TestBinaryJSONContains(t *testing.T) { for _, test := range tests { obj := mustParseBinaryFromString(t, test.input) target := mustParseBinaryFromString(t, test.target) - require.Equal(t, test.expected, ContainsBinary(obj, target)) + require.Equal(t, test.expected, ContainsBinaryJSON(obj, target)) } } @@ -423,7 +425,7 @@ func TestGetKeys(t *testing.T) { b.WriteByte('a') } b.WriteString("\": 1}") - parsedBJ, err := ParseBinaryFromString(b.String()) + parsedBJ, err := ParseBinaryJSONFromString(b.String()) require.Error(t, err) require.EqualError(t, err, "[types:8129]TiDB does not yet support JSON objects with the key length >= 65536") } @@ -449,33 +451,33 @@ func TestBinaryJSONDepth(t *testing.T) { } func TestParseBinaryFromString(t *testing.T) { - obj, err := ParseBinaryFromString("") + obj, err := ParseBinaryJSONFromString("") require.Error(t, err) require.Equal(t, "", obj.String()) require.Contains(t, err.Error(), "The document is empty") - obj, err = ParseBinaryFromString(`"a""`) + obj, err = ParseBinaryJSONFromString(`"a""`) require.Error(t, err) require.Equal(t, "", obj.String()) require.Contains(t, err.Error(), "The document root must not be followed by other values.") } func TestCreateBinary(t *testing.T) { - bj := CreateBinary(int64(1 << 62)) - require.Equal(t, TypeCodeInt64, bj.TypeCode) + bj := CreateBinaryJSON(int64(1 << 62)) + require.Equal(t, JSONTypeCodeInt64, bj.TypeCode) require.NotNil(t, bj.Value) - bj = CreateBinary(123456789.1234567) - require.Equal(t, TypeCodeFloat64, bj.TypeCode) + bj = CreateBinaryJSON(123456789.1234567) + require.Equal(t, JSONTypeCodeFloat64, bj.TypeCode) - bj = CreateBinary(0.00000001) - require.Equal(t, TypeCodeFloat64, bj.TypeCode) + bj = CreateBinaryJSON(0.00000001) + require.Equal(t, JSONTypeCodeFloat64, bj.TypeCode) - bj = CreateBinary(1e-20) - require.Equal(t, TypeCodeFloat64, bj.TypeCode) + bj = CreateBinaryJSON(1e-20) + require.Equal(t, JSONTypeCodeFloat64, bj.TypeCode) require.NotNil(t, bj.Value) - bj2 := CreateBinary(bj) + bj2 := CreateBinaryJSON(bj) require.Equal(t, bj.TypeCode, bj2.TypeCode) require.NotNil(t, bj2.Value) @@ -484,14 +486,14 @@ func TestCreateBinary(t *testing.T) { r := recover() require.Regexp(t, "^unknown type:", r) }() - bj = CreateBinary(int8(123)) + bj = CreateBinaryJSON(int8(123)) require.Equal(t, bj.TypeCode, bj.TypeCode) }() } func TestFunctions(t *testing.T) { testByte := []byte{'\\', 'b', 'f', 'n', 'r', 't', 'u', 'z', '0'} - testOutput, err := unquoteString(string(testByte)) + testOutput, err := unquoteJSONString(string(testByte)) require.Equal(t, "\bfnrtuz0", testOutput) require.NoError(t, err) @@ -556,7 +558,7 @@ func TestBinaryJSONExtractCallback(t *testing.T) { require.NoError(t, err) count := 0 - cb := func(fullPath PathExpression, bj BinaryJSON) (stop bool, err error) { + cb := func(fullPath JSONPathExpression, bj BinaryJSON) (stop bool, err error) { require.Less(t, count, len(test.expected)) if count < len(test.expected) { require.Equal(t, test.expected[count].path, fullPath.String()) @@ -566,7 +568,7 @@ func TestBinaryJSONExtractCallback(t *testing.T) { return false, nil } - fullPath := PathExpression{legs: make([]pathLeg, 0), flags: pathExpressionFlag(0)} + fullPath := JSONPathExpression{legs: make([]jsonPathLeg, 0), flags: jsonPathExpressionFlag(0)} _, err = test.bj.extractToCallback(pe, cb, fullPath) require.NoError(t, err) require.Equal(t, len(test.expected), count) @@ -618,7 +620,7 @@ func TestBinaryJSONWalk(t *testing.T) { for _, test := range tests { count := 0 - cb := func(fullPath PathExpression, bj BinaryJSON) (stop bool, err error) { + cb := func(fullPath JSONPathExpression, bj BinaryJSON) (stop bool, err error) { require.Less(t, count, len(test.expected)) if count < len(test.expected) { require.Equal(t, test.expected[count].path, fullPath.String()) @@ -630,7 +632,7 @@ func TestBinaryJSONWalk(t *testing.T) { var err error if len(test.paths) > 0 { - peList := make([]PathExpression, 0, len(test.paths)) + peList := make([]JSONPathExpression, 0, len(test.paths)) for _, path := range test.paths { pe, errPath := ParseJSONPathExpr(path) require.NoError(t, errPath) @@ -653,7 +655,7 @@ func TestBinaryJSONOpaque(t *testing.T) { }{ { BinaryJSON{ - TypeCode: TypeCodeOpaque, + TypeCode: JSONTypeCodeOpaque, Value: []byte{233, 1, '9'}, }, Opaque{ @@ -664,7 +666,7 @@ func TestBinaryJSONOpaque(t *testing.T) { }, { BinaryJSON{ - TypeCode: TypeCodeOpaque, + TypeCode: JSONTypeCodeOpaque, Value: append([]byte{233, 0x80, 0x01}, make([]byte, 128)...), }, Opaque{ diff --git a/types/json/constants.go b/types/json_constants.go similarity index 74% rename from types/json/constants.go rename to types/json_constants.go index 6cf356157d72c..6a6cdafaa762a 100644 --- a/types/json/constants.go +++ b/types/json_constants.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package json +package types import ( "encoding/binary" @@ -22,47 +22,47 @@ import ( "github.com/pingcap/tidb/util/dbterror" ) -// TypeCode indicates JSON type. -type TypeCode = byte +// JSONTypeCode indicates JSON type. +type JSONTypeCode = byte const ( - // TypeCodeObject indicates the JSON is an object. - TypeCodeObject TypeCode = 0x01 - // TypeCodeArray indicates the JSON is an array. - TypeCodeArray TypeCode = 0x03 - // TypeCodeLiteral indicates the JSON is a literal. - TypeCodeLiteral TypeCode = 0x04 - // TypeCodeInt64 indicates the JSON is a signed integer. - TypeCodeInt64 TypeCode = 0x09 - // TypeCodeUint64 indicates the JSON is a unsigned integer. - TypeCodeUint64 TypeCode = 0x0a - // TypeCodeFloat64 indicates the JSON is a double float number. - TypeCodeFloat64 TypeCode = 0x0b - // TypeCodeString indicates the JSON is a string. - TypeCodeString TypeCode = 0x0c - // TypeCodeOpaque indicates the JSON is a opaque - TypeCodeOpaque TypeCode = 0x0d + // JSONTypeCodeObject indicates the JSON is an object. + JSONTypeCodeObject JSONTypeCode = 0x01 + // JSONTypeCodeArray indicates the JSON is an array. + JSONTypeCodeArray JSONTypeCode = 0x03 + // JSONTypeCodeLiteral indicates the JSON is a literal. + JSONTypeCodeLiteral JSONTypeCode = 0x04 + // JSONTypeCodeInt64 indicates the JSON is a signed integer. + JSONTypeCodeInt64 JSONTypeCode = 0x09 + // JSONTypeCodeUint64 indicates the JSON is a unsigned integer. + JSONTypeCodeUint64 JSONTypeCode = 0x0a + // JSONTypeCodeFloat64 indicates the JSON is a double float number. + JSONTypeCodeFloat64 JSONTypeCode = 0x0b + // JSONTypeCodeString indicates the JSON is a string. + JSONTypeCodeString JSONTypeCode = 0x0c + // JSONTypeCodeOpaque indicates the JSON is a opaque + JSONTypeCodeOpaque JSONTypeCode = 0x0d ) const ( - // LiteralNil represents JSON null. - LiteralNil byte = 0x00 - // LiteralTrue represents JSON true. - LiteralTrue byte = 0x01 - // LiteralFalse represents JSON false. - LiteralFalse byte = 0x02 + // JSONLiteralNil represents JSON null. + JSONLiteralNil byte = 0x00 + // JSONLiteralTrue represents JSON true. + JSONLiteralTrue byte = 0x01 + // JSONLiteralFalse represents JSON false. + JSONLiteralFalse byte = 0x02 ) const unknownTypeCodeErrorMsg = "unknown type code: %d" const unknownTypeErrorMsg = "unknown type: %s" -// safeSet holds the value true if the ASCII character with the given array +// jsonSafeSet holds the value true if the ASCII character with the given array // position can be represented inside a JSON string without any further // escaping. // // All values are true except for the ASCII control characters (0-31), the // double quote ("), and the backslash character ("\"). -var safeSet = [utf8.RuneSelf]bool{ +var jsonSafeSet = [utf8.RuneSelf]bool{ ' ': true, '!': true, '"': false, @@ -162,8 +162,8 @@ var safeSet = [utf8.RuneSelf]bool{ } var ( - hexChars = "0123456789abcdef" - endian = binary.LittleEndian + jsonHexChars = "0123456789abcdef" + jsonEndian = binary.LittleEndian ) const ( @@ -194,17 +194,17 @@ var jsonTypePrecedences = map[string]int{ "NULL": -12, } -// ModifyType is for modify a JSON. There are three valid values: -// ModifyInsert, ModifyReplace and ModifySet. -type ModifyType byte +// JSONModifyType is for modify a JSON. There are three valid values: +// JSONModifyInsert, JSONModifyReplace and JSONModifySet. +type JSONModifyType byte const ( - // ModifyInsert is for insert a new element into a JSON. - ModifyInsert ModifyType = 0x01 - // ModifyReplace is for replace an old elemList from a JSON. - ModifyReplace ModifyType = 0x02 - // ModifySet = ModifyInsert | ModifyReplace - ModifySet ModifyType = 0x03 + // JSONModifyInsert is for insert a new element into a JSON. + JSONModifyInsert JSONModifyType = 0x01 + // JSONModifyReplace is for replace an old elemList from a JSON. + JSONModifyReplace JSONModifyType = 0x02 + // JSONModifySet = JSONModifyInsert | JSONModifyReplace + JSONModifySet JSONModifyType = 0x03 ) var ( @@ -234,7 +234,7 @@ var ( // See: https://dev.mysql.com/doc/refman/5.7/en/json-search-functions.html#function_json-contains-path const ( // 'all': 1 if all paths exist within the document, 0 otherwise. - ContainsPathAll = "all" + JSONContainsPathAll = "all" // 'one': 1 if at least one path exists within the document, 0 otherwise. - ContainsPathOne = "one" + JSONContainsPathOne = "one" ) diff --git a/types/json/path_expr.go b/types/json_path_expr.go similarity index 53% rename from types/json/path_expr.go rename to types/json_path_expr.go index e8b304c67a283..bed9cba95f831 100644 --- a/types/json/path_expr.go +++ b/types/json_path_expr.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package json +package types import ( "encoding/json" @@ -28,10 +28,10 @@ import ( /* From MySQL 5.7, JSON path expression grammar: - pathExpression ::= scope (pathLeg)* + pathExpression ::= scope (jsonPathLeg)* scope ::= [ columnReference ] '$' columnReference ::= // omit... - pathLeg ::= member | arrayLocation | '**' + jsonPathLeg ::= member | arrayLocation | '**' member ::= '.' (keyName | '*') arrayLocation ::= '[' (non-negative-integer | '*') ']' keyName ::= ECMAScript-identifier | ECMAScript-string-literal @@ -50,123 +50,123 @@ import ( select json_extract('{"a": "b", "c": [1, "2"]}', '$.*') -> ["b", [1, "2"]] */ -type pathLegType byte +type jsonPathLegType byte const ( - // pathLegKey indicates the path leg with '.key'. - pathLegKey pathLegType = 0x01 - // pathLegIndex indicates the path leg with form '[number]'. - pathLegIndex pathLegType = 0x02 - // pathLegDoubleAsterisk indicates the path leg with form '**'. - pathLegDoubleAsterisk pathLegType = 0x03 + // jsonPathLegKey indicates the path leg with '.key'. + jsonPathLegKey jsonPathLegType = 0x01 + // jsonPathLegIndex indicates the path leg with form '[number]'. + jsonPathLegIndex jsonPathLegType = 0x02 + // jsonPathLegDoubleAsterisk indicates the path leg with form '**'. + jsonPathLegDoubleAsterisk jsonPathLegType = 0x03 ) -// pathLeg is only used by PathExpression. -type pathLeg struct { - typ pathLegType - arrayIndex int // if typ is pathLegIndex, the value should be parsed into here. - dotKey string // if typ is pathLegKey, the key should be parsed into here. +// jsonPathLeg is only used by JSONPathExpression. +type jsonPathLeg struct { + typ jsonPathLegType + arrayIndex int // if typ is jsonPathLegIndex, the value should be parsed into here. + dotKey string // if typ is jsonPathLegKey, the key should be parsed into here. } // arrayIndexAsterisk is for parsing `*` into a number. // we need this number represent "all". const arrayIndexAsterisk = -1 -// pathExpressionFlag holds attributes of PathExpression -type pathExpressionFlag byte +// jsonPathExpressionFlag holds attributes of JSONPathExpression +type jsonPathExpressionFlag byte const ( - pathExpressionContainsAsterisk pathExpressionFlag = 0x01 - pathExpressionContainsDoubleAsterisk pathExpressionFlag = 0x02 + jsonPathExpressionContainsAsterisk jsonPathExpressionFlag = 0x01 + jsonPathExpressionContainsDoubleAsterisk jsonPathExpressionFlag = 0x02 ) // containsAnyAsterisk returns true if pef contains any asterisk. -func (pef pathExpressionFlag) containsAnyAsterisk() bool { - pef &= pathExpressionContainsAsterisk | pathExpressionContainsDoubleAsterisk +func (pef jsonPathExpressionFlag) containsAnyAsterisk() bool { + pef &= jsonPathExpressionContainsAsterisk | jsonPathExpressionContainsDoubleAsterisk return byte(pef) != 0 } -// PathExpression is for JSON path expression. -type PathExpression struct { - legs []pathLeg - flags pathExpressionFlag +// JSONPathExpression is for JSON path expression. +type JSONPathExpression struct { + legs []jsonPathLeg + flags jsonPathExpressionFlag } -var peCache PathExpressionCache +var peCache JSONPathExpressionCache -type pathExpressionKey string +type jsonPathExpressionKey string -func (key pathExpressionKey) Hash() []byte { +func (key jsonPathExpressionKey) Hash() []byte { return hack.Slice(string(key)) } -// PathExpressionCache is a cache for PathExpression. -type PathExpressionCache struct { +// JSONPathExpressionCache is a cache for JSONPathExpression. +type JSONPathExpressionCache struct { mu sync.Mutex cache *kvcache.SimpleLRUCache } -// popOneLeg returns a pathLeg, and a child PathExpression without that leg. -func (pe PathExpression) popOneLeg() (pathLeg, PathExpression) { - newPe := PathExpression{ +// popOneLeg returns a jsonPathLeg, and a child JSONPathExpression without that leg. +func (pe JSONPathExpression) popOneLeg() (jsonPathLeg, JSONPathExpression) { + newPe := JSONPathExpression{ legs: pe.legs[1:], flags: 0, } for _, leg := range newPe.legs { - if leg.typ == pathLegIndex && leg.arrayIndex == -1 { - newPe.flags |= pathExpressionContainsAsterisk - } else if leg.typ == pathLegKey && leg.dotKey == "*" { - newPe.flags |= pathExpressionContainsAsterisk - } else if leg.typ == pathLegDoubleAsterisk { - newPe.flags |= pathExpressionContainsDoubleAsterisk + if leg.typ == jsonPathLegIndex && leg.arrayIndex == -1 { + newPe.flags |= jsonPathExpressionContainsAsterisk + } else if leg.typ == jsonPathLegKey && leg.dotKey == "*" { + newPe.flags |= jsonPathExpressionContainsAsterisk + } else if leg.typ == jsonPathLegDoubleAsterisk { + newPe.flags |= jsonPathExpressionContainsDoubleAsterisk } } return pe.legs[0], newPe } -// popOneLastLeg returns the parent PathExpression and the last pathLeg -func (pe PathExpression) popOneLastLeg() (PathExpression, pathLeg) { +// popOneLastLeg returns the parent JSONPathExpression and the last jsonPathLeg +func (pe JSONPathExpression) popOneLastLeg() (JSONPathExpression, jsonPathLeg) { lastLegIdx := len(pe.legs) - 1 lastLeg := pe.legs[lastLegIdx] // It is used only in modification, it has been checked that there is no asterisks. - return PathExpression{legs: pe.legs[:lastLegIdx]}, lastLeg + return JSONPathExpression{legs: pe.legs[:lastLegIdx]}, lastLeg } // pushBackOneIndexLeg pushback one leg of INDEX type -func (pe PathExpression) pushBackOneIndexLeg(index int) PathExpression { - newPe := PathExpression{ - legs: append(pe.legs, pathLeg{typ: pathLegIndex, arrayIndex: index}), +func (pe JSONPathExpression) pushBackOneIndexLeg(index int) JSONPathExpression { + newPe := JSONPathExpression{ + legs: append(pe.legs, jsonPathLeg{typ: jsonPathLegIndex, arrayIndex: index}), flags: pe.flags, } if index == -1 { - newPe.flags |= pathExpressionContainsAsterisk + newPe.flags |= jsonPathExpressionContainsAsterisk } return newPe } // pushBackOneKeyLeg pushback one leg of KEY type -func (pe PathExpression) pushBackOneKeyLeg(key string) PathExpression { - newPe := PathExpression{ - legs: append(pe.legs, pathLeg{typ: pathLegKey, dotKey: key}), +func (pe JSONPathExpression) pushBackOneKeyLeg(key string) JSONPathExpression { + newPe := JSONPathExpression{ + legs: append(pe.legs, jsonPathLeg{typ: jsonPathLegKey, dotKey: key}), flags: pe.flags, } if key == "*" { - newPe.flags |= pathExpressionContainsAsterisk + newPe.flags |= jsonPathExpressionContainsAsterisk } return newPe } // ContainsAnyAsterisk returns true if pe contains any asterisk. -func (pe PathExpression) ContainsAnyAsterisk() bool { +func (pe JSONPathExpression) ContainsAnyAsterisk() bool { return pe.flags.containsAnyAsterisk() } -type stream struct { +type jsonPathStream struct { pathExpr string pos int } -func (s *stream) skipWhiteSpace() { +func (s *jsonPathStream) skipWhiteSpace() { for ; s.pos < len(s.pathExpr); s.pos++ { if !unicode.IsSpace(rune(s.pathExpr[s.pos])) { break @@ -174,25 +174,25 @@ func (s *stream) skipWhiteSpace() { } } -func (s *stream) read() byte { +func (s *jsonPathStream) read() byte { b := s.pathExpr[s.pos] s.pos++ return b } -func (s *stream) peek() byte { +func (s *jsonPathStream) peek() byte { return s.pathExpr[s.pos] } -func (s *stream) skip(i int) { +func (s *jsonPathStream) skip(i int) { s.pos += i } -func (s *stream) exhausted() bool { +func (s *jsonPathStream) exhausted() bool { return s.pos >= len(s.pathExpr) } -func (s *stream) readWhile(f func(byte) bool) (str string, metEnd bool) { +func (s *jsonPathStream) readWhile(f func(byte) bool) (str string, metEnd bool) { start := s.pos for ; !s.exhausted(); s.skip(1) { if !f(s.peek()) { @@ -202,46 +202,46 @@ func (s *stream) readWhile(f func(byte) bool) (str string, metEnd bool) { return s.pathExpr[start:s.pos], true } -func parseJSONPathExpr(pathExpr string) (pe PathExpression, err error) { - s := &stream{pathExpr: pathExpr, pos: 0} +func parseJSONPathExpr(pathExpr string) (pe JSONPathExpression, err error) { + s := &jsonPathStream{pathExpr: pathExpr, pos: 0} s.skipWhiteSpace() if s.exhausted() || s.read() != '$' { - return PathExpression{}, ErrInvalidJSONPath.GenWithStackByArgs(1) + return JSONPathExpression{}, ErrInvalidJSONPath.GenWithStackByArgs(1) } s.skipWhiteSpace() - pe.legs = make([]pathLeg, 0, 16) - pe.flags = pathExpressionFlag(0) + pe.legs = make([]jsonPathLeg, 0, 16) + pe.flags = jsonPathExpressionFlag(0) var ok bool for !s.exhausted() { switch s.peek() { case '.': - ok = parseMember(s, &pe) + ok = parseJSONPathMember(s, &pe) case '[': - ok = parseArray(s, &pe) + ok = parseJSONPathArray(s, &pe) case '*': - ok = parseWildcard(s, &pe) + ok = parseJSONPathWildcard(s, &pe) default: ok = false } if !ok { - return PathExpression{}, ErrInvalidJSONPath.GenWithStackByArgs(s.pos) + return JSONPathExpression{}, ErrInvalidJSONPath.GenWithStackByArgs(s.pos) } s.skipWhiteSpace() } - if len(pe.legs) > 0 && pe.legs[len(pe.legs)-1].typ == pathLegDoubleAsterisk { - return PathExpression{}, ErrInvalidJSONPath.GenWithStackByArgs(s.pos) + if len(pe.legs) > 0 && pe.legs[len(pe.legs)-1].typ == jsonPathLegDoubleAsterisk { + return JSONPathExpression{}, ErrInvalidJSONPath.GenWithStackByArgs(s.pos) } return } -func parseWildcard(s *stream, p *PathExpression) bool { +func parseJSONPathWildcard(s *jsonPathStream, p *JSONPathExpression) bool { s.skip(1) if s.exhausted() || s.read() != '*' { return false @@ -250,12 +250,12 @@ func parseWildcard(s *stream, p *PathExpression) bool { return false } - p.flags |= pathExpressionContainsDoubleAsterisk - p.legs = append(p.legs, pathLeg{typ: pathLegDoubleAsterisk}) + p.flags |= jsonPathExpressionContainsDoubleAsterisk + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegDoubleAsterisk}) return true } -func parseArray(s *stream, p *PathExpression) bool { +func parseJSONPathArray(s *jsonPathStream, p *JSONPathExpression) bool { s.skip(1) s.skipWhiteSpace() if s.exhausted() { @@ -264,8 +264,8 @@ func parseArray(s *stream, p *PathExpression) bool { if s.peek() == '*' { s.skip(1) - p.flags |= pathExpressionContainsAsterisk - p.legs = append(p.legs, pathLeg{typ: pathLegIndex, arrayIndex: arrayIndexAsterisk}) + p.flags |= jsonPathExpressionContainsAsterisk + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegIndex, arrayIndex: arrayIndexAsterisk}) } else { // FIXME: only support an integer index for now. Need to support [last], [1 to 2]... in the future. str, meetEnd := s.readWhile(func(b byte) bool { @@ -278,7 +278,7 @@ func parseArray(s *stream, p *PathExpression) bool { if err != nil || index > math.MaxUint32 { return false } - p.legs = append(p.legs, pathLeg{typ: pathLegIndex, arrayIndex: index}) + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegIndex, arrayIndex: index}) } s.skipWhiteSpace() @@ -289,7 +289,7 @@ func parseArray(s *stream, p *PathExpression) bool { return true } -func parseMember(s *stream, p *PathExpression) bool { +func parseJSONPathMember(s *jsonPathStream, p *JSONPathExpression) bool { var err error s.skip(1) s.skipWhiteSpace() @@ -299,8 +299,8 @@ func parseMember(s *stream, p *PathExpression) bool { if s.peek() == '*' { s.skip(1) - p.flags |= pathExpressionContainsAsterisk - p.legs = append(p.legs, pathLeg{typ: pathLegKey, dotKey: "*"}) + p.flags |= jsonPathExpressionContainsAsterisk + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegKey, dotKey: "*"}) } else { var dotKey string var wasQuoted bool @@ -329,12 +329,12 @@ func parseMember(s *stream, p *PathExpression) bool { if !json.Valid(hack.Slice(dotKey)) { return false } - dotKey, err = unquoteString(dotKey[1 : len(dotKey)-1]) + dotKey, err = unquoteJSONString(dotKey[1 : len(dotKey)-1]) if err != nil || (!wasQuoted && !isEcmascriptIdentifier(dotKey)) { return false } - p.legs = append(p.legs, pathLeg{typ: pathLegKey, dotKey: dotKey}) + p.legs = append(p.legs, jsonPathLeg{typ: jsonPathLegKey, dotKey: dotKey}) } return true } @@ -355,33 +355,33 @@ func isEcmascriptIdentifier(s string) bool { return true } -// ParseJSONPathExpr parses a JSON path expression. Returns a PathExpression +// ParseJSONPathExpr parses a JSON path expression. Returns a JSONPathExpression // object which can be used in JSON_EXTRACT, JSON_SET and so on. -func ParseJSONPathExpr(pathExpr string) (PathExpression, error) { +func ParseJSONPathExpr(pathExpr string) (JSONPathExpression, error) { peCache.mu.Lock() - val, ok := peCache.cache.Get(pathExpressionKey(pathExpr)) + val, ok := peCache.cache.Get(jsonPathExpressionKey(pathExpr)) if ok { peCache.mu.Unlock() - return val.(PathExpression), nil + return val.(JSONPathExpression), nil } peCache.mu.Unlock() pathExpression, err := parseJSONPathExpr(pathExpr) if err == nil { peCache.mu.Lock() - peCache.cache.Put(pathExpressionKey(pathExpr), kvcache.Value(pathExpression)) + peCache.cache.Put(jsonPathExpressionKey(pathExpr), kvcache.Value(pathExpression)) peCache.mu.Unlock() } return pathExpression, err } -func (pe PathExpression) String() string { +func (pe JSONPathExpression) String() string { var s strings.Builder s.WriteString("$") for _, leg := range pe.legs { switch leg.typ { - case pathLegIndex: + case jsonPathLegIndex: if leg.arrayIndex == -1 { s.WriteString("[*]") } else { @@ -389,14 +389,14 @@ func (pe PathExpression) String() string { s.WriteString(strconv.Itoa(leg.arrayIndex)) s.WriteString("]") } - case pathLegKey: + case jsonPathLegKey: s.WriteString(".") if leg.dotKey == "*" { s.WriteString(leg.dotKey) } else { - s.WriteString(quoteString(leg.dotKey)) + s.WriteString(quoteJSONString(leg.dotKey)) } - case pathLegDoubleAsterisk: + case jsonPathLegDoubleAsterisk: s.WriteString("**") } } diff --git a/types/json/path_expr_test.go b/types/json_path_expr_test.go similarity index 99% rename from types/json/path_expr_test.go rename to types/json_path_expr_test.go index fb863d48050d3..2de75ba8bd5d5 100644 --- a/types/json/path_expr_test.go +++ b/types/json_path_expr_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package json +package types import ( "testing" diff --git a/util/chunk/BUILD.bazel b/util/chunk/BUILD.bazel index 8520d475cb780..9f351a9b67c72 100644 --- a/util/chunk/BUILD.bazel +++ b/util/chunk/BUILD.bazel @@ -24,7 +24,6 @@ go_library( "//parser/mysql", "//parser/terror", "//types", - "//types/json", "//util/checksum", "//util/disk", "//util/encrypt", @@ -64,7 +63,6 @@ go_test( "//sessionctx/stmtctx", "//testkit/testsetup", "//types", - "//types/json", "//util/collate", "//util/mathutil", "//util/memory", diff --git a/util/chunk/chunk.go b/util/chunk/chunk.go index 7270ab3d16e3c..d04cafe70a5d9 100644 --- a/util/chunk/chunk.go +++ b/util/chunk/chunk.go @@ -19,7 +19,6 @@ import ( "github.com/pingcap/errors" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/mathutil" ) @@ -552,7 +551,7 @@ func (c *Chunk) AppendSet(colIdx int, set types.Set) { } // AppendJSON appends a JSON value to the chunk. -func (c *Chunk) AppendJSON(colIdx int, j json.BinaryJSON) { +func (c *Chunk) AppendJSON(colIdx int, j types.BinaryJSON) { c.appendSel(colIdx) c.columns[colIdx].AppendJSON(j) } diff --git a/util/chunk/chunk_test.go b/util/chunk/chunk_test.go index 413974acc30b6..df7d3728a196d 100644 --- a/util/chunk/chunk_test.go +++ b/util/chunk/chunk_test.go @@ -26,7 +26,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/mathutil" "github.com/stretchr/testify/require" ) @@ -43,7 +42,7 @@ func TestAppendRow(t *testing.T) { chk.AppendString(2, str) chk.AppendBytes(3, []byte(str)) chk.AppendMyDecimal(4, types.NewDecFromStringForTest(str)) - chk.AppendJSON(5, json.CreateBinary(str)) + chk.AppendJSON(5, types.CreateBinaryJSON(str)) } require.Equal(t, numCols, chk.NumCols()) require.Equal(t, numRows, chk.NumRows()) @@ -145,7 +144,7 @@ func TestAppendChunk(t *testing.T) { fieldTypes = append(fieldTypes, types.NewFieldType(mysql.TypeVarchar)) fieldTypes = append(fieldTypes, types.NewFieldType(mysql.TypeJSON)) - jsonObj, err := json.ParseBinaryFromString("{\"k1\":\"v1\"}") + jsonObj, err := types.ParseBinaryJSONFromString("{\"k1\":\"v1\"}") require.NoError(t, err) src := NewChunkWithCapacity(fieldTypes, 32) @@ -193,7 +192,7 @@ func TestAppendChunk(t *testing.T) { require.Equal(t, 0, len(col.elemBuf)) for i := 0; i < 12; i += 2 { jsonElem := dst.GetRow(i).GetJSON(2) - require.Zero(t, json.CompareBinary(jsonElem, jsonObj)) + require.Zero(t, types.CompareBinaryJSON(jsonElem, jsonObj)) } } @@ -203,7 +202,7 @@ func TestTruncateTo(t *testing.T) { fieldTypes = append(fieldTypes, types.NewFieldType(mysql.TypeVarchar)) fieldTypes = append(fieldTypes, types.NewFieldType(mysql.TypeJSON)) - jsonObj, err := json.ParseBinaryFromString("{\"k1\":\"v1\"}") + jsonObj, err := types.ParseBinaryJSONFromString("{\"k1\":\"v1\"}") require.NoError(t, err) src := NewChunkWithCapacity(fieldTypes, 32) @@ -254,7 +253,7 @@ func TestTruncateTo(t *testing.T) { for i := 0; i < 12; i += 2 { row := src.GetRow(i) jsonElem := row.GetJSON(2) - require.Zero(t, json.CompareBinary(jsonElem, jsonObj)) + require.Zero(t, types.CompareBinaryJSON(jsonElem, jsonObj)) } chk := NewChunkWithCapacity(fieldTypes[:1], 1) @@ -434,7 +433,7 @@ func TestCompare(t *testing.T) { case mysql.TypeBit: chunk.AppendBytes(i, []byte{0}) case mysql.TypeJSON: - chunk.AppendJSON(i, json.CreateBinary(int64(0))) + chunk.AppendJSON(i, types.CreateBinaryJSON(int64(0))) default: require.FailNow(t, "type not handled", allTypes[i].GetType()) } @@ -467,7 +466,7 @@ func TestCompare(t *testing.T) { case mysql.TypeBit: chunk.AppendBytes(i, []byte{1}) case mysql.TypeJSON: - chunk.AppendJSON(i, json.CreateBinary(int64(1))) + chunk.AppendJSON(i, types.CreateBinaryJSON(int64(1))) default: require.FailNow(t, "type not handled", allTypes[i].GetType()) } @@ -522,7 +521,7 @@ func TestCopyTo(t *testing.T) { case mysql.TypeBit: chunk.AppendBytes(i, []byte{byte(k)}) case mysql.TypeJSON: - chunk.AppendJSON(i, json.CreateBinary(int64(k))) + chunk.AppendJSON(i, types.CreateBinaryJSON(int64(k))) default: require.FailNow(t, "type not handled", allTypes[i].GetType()) } @@ -583,7 +582,7 @@ func TestChunkMemoryUsage(t *testing.T) { // empty chunk with initial capactiy require.Equal(t, int64(expectedUsage), chk.MemoryUsage()) - jsonObj, err := json.ParseBinaryFromString("1") + jsonObj, err := types.ParseBinaryJSONFromString("1") require.NoError(t, err) timeObj := types.NewTime(types.FromGoTime(time.Now()), mysql.TypeDatetime, 0) @@ -1013,7 +1012,7 @@ func TestAppendRows(t *testing.T) { chk.AppendString(2, str) chk.AppendBytes(3, []byte(str)) chk.AppendMyDecimal(4, types.NewDecFromStringForTest(str)) - chk.AppendJSON(5, json.CreateBinary(str)) + chk.AppendJSON(5, types.CreateBinaryJSON(str)) } require.Equal(t, numCols, chk.NumCols()) require.Equal(t, numRows, chk.NumRows()) diff --git a/util/chunk/codec_test.go b/util/chunk/codec_test.go index 565d9eae69543..1e5644b3fda28 100644 --- a/util/chunk/codec_test.go +++ b/util/chunk/codec_test.go @@ -20,7 +20,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/stretchr/testify/require" ) @@ -44,7 +43,7 @@ func TestCodec(t *testing.T) { oldChk.AppendString(2, str) oldChk.AppendString(3, str) oldChk.AppendMyDecimal(4, types.NewDecFromStringForTest(str)) - oldChk.AppendJSON(5, json.CreateBinary(str)) + oldChk.AppendJSON(5, types.CreateBinaryJSON(str)) } codec := NewCodec(colTypes) @@ -178,7 +177,7 @@ func BenchmarkDecodeToChunkWithVariableType(b *testing.B) { chk.AppendString(2, str) chk.AppendString(3, str) chk.AppendMyDecimal(4, types.NewDecFromStringForTest(str)) - chk.AppendJSON(5, json.CreateBinary(str)) + chk.AppendJSON(5, types.CreateBinaryJSON(str)) } codec := &Codec{colTypes} buffer := codec.Encode(chk) diff --git a/util/chunk/column.go b/util/chunk/column.go index 0a48a1d6f97f7..61610087c9b48 100644 --- a/util/chunk/column.go +++ b/util/chunk/column.go @@ -22,7 +22,6 @@ import ( "unsafe" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/hack" ) @@ -47,7 +46,7 @@ func (c *Column) appendNameValue(name string, val uint64) { } // AppendJSON appends a BinaryJSON value into this Column. -func (c *Column) AppendJSON(j json.BinaryJSON) { +func (c *Column) AppendJSON(j types.BinaryJSON) { c.data = append(c.data, j.TypeCode) c.data = append(c.data, j.Value...) c.finishAppendVar() @@ -579,9 +578,9 @@ func (c *Column) GetString(rowID int) string { } // GetJSON returns the JSON in the specific row. -func (c *Column) GetJSON(rowID int) json.BinaryJSON { +func (c *Column) GetJSON(rowID int) types.BinaryJSON { start := c.offsets[rowID] - return json.BinaryJSON{TypeCode: c.data[start], Value: c.data[start+1 : c.offsets[rowID+1]]} + return types.BinaryJSON{TypeCode: c.data[start], Value: c.data[start+1 : c.offsets[rowID+1]]} } // GetBytes returns the byte slice in the specific row. diff --git a/util/chunk/column_test.go b/util/chunk/column_test.go index df2481d5a1297..20f83791d185d 100644 --- a/util/chunk/column_test.go +++ b/util/chunk/column_test.go @@ -23,7 +23,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/stretchr/testify/require" ) @@ -332,7 +331,7 @@ func TestJSONColumn(t *testing.T) { chk := NewChunkWithCapacity([]*types.FieldType{types.NewFieldType(mysql.TypeJSON)}, 1024) col := chk.Column(0) for i := 0; i < 1024; i++ { - j := new(json.BinaryJSON) + j := new(types.BinaryJSON) err := j.UnmarshalJSON([]byte(fmt.Sprintf(`{"%v":%v}`, i, i))) require.NoError(t, err) col.AppendJSON(*j) diff --git a/util/chunk/compare.go b/util/chunk/compare.go index 257e0ee8cf5c0..546f73f8f1a1b 100644 --- a/util/chunk/compare.go +++ b/util/chunk/compare.go @@ -20,7 +20,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" ) // CompareFunc is a function to compare the two values in Row, the two columns must have the same type. @@ -166,7 +165,7 @@ func cmpJSON(l Row, lCol int, r Row, rCol int) int { return cmpNull(lNull, rNull) } lJ, rJ := l.GetJSON(lCol), r.GetJSON(rCol) - return json.CompareBinary(lJ, rJ) + return types.CompareBinaryJSON(lJ, rJ) } // Compare compares the value with ad. @@ -211,7 +210,7 @@ func Compare(row Row, colIdx int, ad *types.Datum) int { return types.CompareUint64(l, r) case types.KindMysqlJSON: l, r := row.GetJSON(colIdx), ad.GetMysqlJSON() - return json.CompareBinary(l, r) + return types.CompareBinaryJSON(l, r) case types.KindMysqlTime: l, r := row.GetTime(colIdx), ad.GetMysqlTime() return l.Compare(r) diff --git a/util/chunk/disk_test.go b/util/chunk/disk_test.go index 4e7f2f1e8a86d..1217e86f31944 100644 --- a/util/chunk/disk_test.go +++ b/util/chunk/disk_test.go @@ -30,7 +30,6 @@ import ( "github.com/pingcap/tidb/config" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/mathutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -55,7 +54,7 @@ func initChunks(numChk, numRow int) ([]*Chunk, []*types.FieldType) { chk.AppendNull(2) chk.AppendInt64(3, data) if chkIdx%2 == 0 { - chk.AppendJSON(4, json.CreateBinary(fmt.Sprint(data))) + chk.AppendJSON(4, types.CreateBinaryJSON(fmt.Sprint(data))) } else { chk.AppendNull(4) } diff --git a/util/chunk/list_test.go b/util/chunk/list_test.go index 7f7df8cd775c8..607b16c0d6ff5 100644 --- a/util/chunk/list_test.go +++ b/util/chunk/list_test.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/mathutil" "github.com/stretchr/testify/require" ) @@ -90,7 +89,7 @@ func TestListMemoryUsage(t *testing.T) { fieldTypes = append(fieldTypes, types.NewFieldType(mysql.TypeDatetime)) fieldTypes = append(fieldTypes, types.NewFieldType(mysql.TypeDuration)) - jsonObj, err := json.ParseBinaryFromString("1") + jsonObj, err := types.ParseBinaryJSONFromString("1") require.NoError(t, err) timeObj := types.NewTime(types.FromGoTime(time.Now()), mysql.TypeDatetime, 0) durationObj := types.Duration{Duration: math.MaxInt64, Fsp: 0} diff --git a/util/chunk/mutrow.go b/util/chunk/mutrow.go index 5995f2f01fa1e..da274fa7931ad 100644 --- a/util/chunk/mutrow.go +++ b/util/chunk/mutrow.go @@ -21,7 +21,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/hack" ) @@ -113,7 +112,7 @@ func zeroValForType(tp *types.FieldType) interface{} { case mysql.TypeEnum: return types.Enum{} case mysql.TypeJSON: - return json.CreateBinary(nil) + return types.CreateBinaryJSON(nil) default: return nil } @@ -151,7 +150,7 @@ func makeMutRowColumn(in interface{}) *Column { col := newMutRowFixedLenColumn(sizeTime) *(*types.Time)(unsafe.Pointer(&col.data[0])) = x return col - case json.BinaryJSON: + case types.BinaryJSON: col := newMutRowVarLenColumn(len(x.Value) + 1) col.data[0] = x.TypeCode copy(col.data[1:], x.Value) @@ -277,7 +276,7 @@ func (mr MutRow) SetValue(colIdx int, val interface{}) { setMutRowNameValue(col, x.Name, x.Value) case types.Set: setMutRowNameValue(col, x.Name, x.Value) - case json.BinaryJSON: + case types.BinaryJSON: setMutRowJSON(col, x) } col.nullBitmap[0] = 1 @@ -350,7 +349,7 @@ func setMutRowNameValue(col *Column, name string, val uint64) { col.offsets[1] = int64(dataLen) } -func setMutRowJSON(col *Column, j json.BinaryJSON) { +func setMutRowJSON(col *Column, j types.BinaryJSON) { dataLen := len(j.Value) + 1 if len(col.data) >= dataLen { col.data = col.data[:dataLen] diff --git a/util/chunk/mutrow_test.go b/util/chunk/mutrow_test.go index 532206cf42782..ef9e962f4fb96 100644 --- a/util/chunk/mutrow_test.go +++ b/util/chunk/mutrow_test.go @@ -21,7 +21,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/collate" "github.com/stretchr/testify/require" ) @@ -70,7 +69,7 @@ func TestMutRow(t *testing.T) { require.True(t, row.IsNull(0)) require.False(t, row.IsNull(1)) - j, err := json.ParseBinaryFromString("true") + j, err := types.ParseBinaryJSONFromString("true") time := types.NewTime(types.FromDate(2000, 1, 1, 1, 0, 0, 0), mysql.TypeDatetime, types.MaxFsp) require.NoError(t, err) mutRow = MutRowFromValues(j, time) diff --git a/util/chunk/row.go b/util/chunk/row.go index 5ed5e15479f3f..96aa92acb65fb 100644 --- a/util/chunk/row.go +++ b/util/chunk/row.go @@ -19,7 +19,6 @@ import ( "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" ) // Row represents a row of data, can be used to access values. @@ -108,7 +107,7 @@ func (r Row) GetMyDecimal(colIdx int) *types.MyDecimal { } // GetJSON returns the JSON value with the colIdx. -func (r Row) GetJSON(colIdx int) json.BinaryJSON { +func (r Row) GetJSON(colIdx int) types.BinaryJSON { return r.c.columns[colIdx].GetJSON(r.idx) } diff --git a/util/codec/BUILD.bazel b/util/codec/BUILD.bazel index eabf83ec1fc4f..17d57bcbe22f5 100644 --- a/util/codec/BUILD.bazel +++ b/util/codec/BUILD.bazel @@ -16,7 +16,6 @@ go_library( "//parser/terror", "//sessionctx/stmtctx", "//types", - "//types/json", "//util/chunk", "//util/collate", "//util/hack", @@ -46,7 +45,6 @@ go_test( "//sessionctx/stmtctx", "//testkit/testsetup", "//types", - "//types/json", "//util/benchdaily", "//util/chunk", "//util/collate", diff --git a/util/codec/codec.go b/util/codec/codec.go index 046809cbb0c89..a57fd3857628f 100644 --- a/util/codec/codec.go +++ b/util/codec/codec.go @@ -28,7 +28,6 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/pingcap/tidb/util/hack" @@ -853,11 +852,11 @@ func DecodeOne(b []byte) (remain []byte, d types.Datum, err error) { } case jsonFlag: var size int - size, err = json.PeekBytesAsJSON(b) + size, err = types.PeekBytesAsJSON(b) if err != nil { return b, d, err } - j := json.BinaryJSON{TypeCode: b[0], Value: b[1:size]} + j := types.BinaryJSON{TypeCode: b[0], Value: b[1:size]} d.SetMysqlJSON(j) b = b[size:] case NilFlag: @@ -982,7 +981,7 @@ func peek(b []byte) (length int, err error) { case uvarintFlag: l, err = peekUvarint(b) case jsonFlag: - l, err = json.PeekBytesAsJSON(b) + l, err = types.PeekBytesAsJSON(b) default: return 0, errors.Errorf("invalid encoded key flag %v", flag) } @@ -1149,11 +1148,11 @@ func (decoder *Decoder) DecodeOne(b []byte, colIdx int, ft *types.FieldType) (re chk.AppendDuration(colIdx, v) case jsonFlag: var size int - size, err = json.PeekBytesAsJSON(b) + size, err = types.PeekBytesAsJSON(b) if err != nil { return nil, errors.Trace(err) } - chk.AppendJSON(colIdx, json.BinaryJSON{TypeCode: b[0], Value: b[1:size]}) + chk.AppendJSON(colIdx, types.BinaryJSON{TypeCode: b[0], Value: b[1:size]}) b = b[size:] case NilFlag: chk.AppendNull(colIdx) diff --git a/util/codec/codec_test.go b/util/codec/codec_test.go index 0d74b2a189364..7d2741ba1ed71 100644 --- a/util/codec/codec_test.go +++ b/util/codec/codec_test.go @@ -28,7 +28,6 @@ import ( "github.com/pingcap/tidb/parser/terror" "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/collate" "github.com/stretchr/testify/require" @@ -802,7 +801,7 @@ func TestJSON(t *testing.T) { originalDatums := make([]types.Datum, 0, len(tbl)) for _, jsonDatum := range tbl { var d types.Datum - j, err := json.ParseBinaryFromString(jsonDatum) + j, err := types.ParseBinaryJSONFromString(jsonDatum) require.NoError(t, err) d.SetMysqlJSON(j) originalDatums = append(originalDatums, d) @@ -869,12 +868,12 @@ func TestCut(t *testing.T) { types.MakeDatums(types.NewDecFromInt(0), types.NewDecFromFloatForTest(-1.3)), }, { - types.MakeDatums(json.CreateBinary("abc")), - types.MakeDatums(json.CreateBinary("abc")), + types.MakeDatums(types.CreateBinaryJSON("abc")), + types.MakeDatums(types.CreateBinaryJSON("abc")), }, { - types.MakeDatums(json.CreateBinary(json.Opaque{TypeCode: mysql.TypeString, Buf: []byte("abc")})), - types.MakeDatums(json.CreateBinary(json.Opaque{TypeCode: mysql.TypeString, Buf: []byte("abc")})), + types.MakeDatums(types.CreateBinaryJSON(types.Opaque{TypeCode: mysql.TypeString, Buf: []byte("abc")})), + types.MakeDatums(types.CreateBinaryJSON(types.Opaque{TypeCode: mysql.TypeString, Buf: []byte("abc")})), }, } sc := &stmtctx.StatementContext{TimeZone: time.Local} @@ -1052,7 +1051,7 @@ func datumsForTest(sc *stmtctx.StatementContext) ([]types.Datum, []*types.FieldT {types.Set{Name: "a", Value: 1}, _tp2}, {types.Set{Name: "f", Value: 32}, _tp3}, {types.BinaryLiteral{100}, _tp4}, - {json.CreateBinary("abc"), types.NewFieldType(mysql.TypeJSON)}, + {types.CreateBinaryJSON("abc"), types.NewFieldType(mysql.TypeJSON)}, {int64(1), types.NewFieldType(mysql.TypeYear)}, } diff --git a/util/rowcodec/BUILD.bazel b/util/rowcodec/BUILD.bazel index 6ca9a957c9c32..cbb8ec5438bbf 100644 --- a/util/rowcodec/BUILD.bazel +++ b/util/rowcodec/BUILD.bazel @@ -18,7 +18,6 @@ go_library( "//parser/types", "//sessionctx/stmtctx", "//types", - "//types/json", "//util/chunk", "//util/codec", "@com_github_pingcap_errors//:errors", @@ -42,7 +41,6 @@ go_test( "//tablecodec", "//testkit/testsetup", "//types", - "//types/json", "//util/benchdaily", "//util/chunk", "//util/codec", diff --git a/util/rowcodec/decoder.go b/util/rowcodec/decoder.go index b8b0da8ff8ad7..85a8d3aca7408 100644 --- a/util/rowcodec/decoder.go +++ b/util/rowcodec/decoder.go @@ -24,7 +24,6 @@ import ( "github.com/pingcap/tidb/parser/model" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" ) @@ -169,7 +168,7 @@ func (decoder *DatumMapDecoder) decodeColDatum(col *ColInfo, colData []byte) (ty byteSize := (col.Ft.GetFlen() + 7) >> 3 d.SetMysqlBit(types.NewBinaryLiteralFromUint(decodeUint(colData), byteSize)) case mysql.TypeJSON: - var j json.BinaryJSON + var j types.BinaryJSON j.TypeCode = colData[0] j.Value = colData[1:] d.SetMysqlJSON(j) @@ -344,7 +343,7 @@ func (decoder *ChunkDecoder) decodeColToChunk(colIdx int, col *ColInfo, colData byteSize := (col.Ft.GetFlen() + 7) >> 3 chk.AppendBytes(colIdx, types.NewBinaryLiteralFromUint(decodeUint(colData), byteSize)) case mysql.TypeJSON: - var j json.BinaryJSON + var j types.BinaryJSON j.TypeCode = colData[0] j.Value = colData[1:] chk.AppendJSON(colIdx, j) diff --git a/util/rowcodec/rowcodec_test.go b/util/rowcodec/rowcodec_test.go index 8772a50eb3d5d..8ec7f7b5b114a 100644 --- a/util/rowcodec/rowcodec_test.go +++ b/util/rowcodec/rowcodec_test.go @@ -25,7 +25,6 @@ import ( "github.com/pingcap/tidb/sessionctx/stmtctx" "github.com/pingcap/tidb/tablecodec" "github.com/pingcap/tidb/types" - "github.com/pingcap/tidb/types/json" "github.com/pingcap/tidb/util/chunk" "github.com/pingcap/tidb/util/codec" "github.com/pingcap/tidb/util/collate" @@ -280,7 +279,7 @@ func TestDecodeDecimalFspNotMatch(t *testing.T) { func TestTypesNewRowCodec(t *testing.T) { getJSONDatum := func(value string) types.Datum { - j, err := json.ParseBinaryFromString(value) + j, err := types.ParseBinaryJSONFromString(value) require.NoError(t, err) var d types.Datum d.SetMysqlJSON(j)