diff --git a/expression/builtin_json.go b/expression/builtin_json.go index 0d7844ec02..444a03bc24 100644 --- a/expression/builtin_json.go +++ b/expression/builtin_json.go @@ -1268,7 +1268,7 @@ func (b *builtinJSONKeysSig) evalJSON(row chunk.Row) (res json.BinaryJSON, isNul return res, isNull, err } if res.TypeCode != json.TypeCodeObject { - return res, true, json.ErrInvalidJSONData + return res, true, nil } return res.GetKeys(), false, nil } @@ -1288,9 +1288,6 @@ func (b *builtinJSONKeys2ArgsSig) evalJSON(row chunk.Row) (res json.BinaryJSON, if isNull || err != nil { return res, isNull, err } - if res.TypeCode != json.TypeCodeObject { - return res, true, json.ErrInvalidJSONData - } path, isNull, err := b.args[1].EvalString(b.ctx, row) if isNull || err != nil { diff --git a/expression/builtin_json_test.go b/expression/builtin_json_test.go index dd5bda1c1d..ff61d7899b 100644 --- a/expression/builtin_json_test.go +++ b/expression/builtin_json_test.go @@ -579,6 +579,7 @@ func (s *testEvaluatorSuite) TestJSONKeys(c *C) { expected interface{} success bool }{ + // Tests nil arguments {[]interface{}{nil}, nil, true}, {[]interface{}{nil, "$.c"}, nil, true}, @@ -586,12 +587,12 @@ func (s *testEvaluatorSuite) TestJSONKeys(c *C) { {[]interface{}{nil, nil}, nil, true}, // Tests with other type - {[]interface{}{`1`}, nil, false}, - {[]interface{}{`"str"`}, nil, false}, - {[]interface{}{`true`}, nil, false}, - {[]interface{}{`null`}, nil, false}, - {[]interface{}{`[1, 2]`}, nil, false}, - {[]interface{}{`["1", "2"]`}, nil, false}, + {[]interface{}{`1`}, nil, true}, + {[]interface{}{`"str"`}, nil, true}, + {[]interface{}{`true`}, nil, true}, + {[]interface{}{`null`}, nil, true}, + {[]interface{}{`[1, 2]`}, nil, true}, + {[]interface{}{`["1", "2"]`}, nil, true}, // Tests without path expression {[]interface{}{`{}`}, `[]`, true}, diff --git a/expression/builtin_json_vec.go b/expression/builtin_json_vec.go index 893f4c1118..430d16ecaf 100644 --- a/expression/builtin_json_vec.go +++ b/expression/builtin_json_vec.go @@ -152,7 +152,8 @@ func (b *builtinJSONKeysSig) vecEvalJSON(input *chunk.Chunk, result *chunk.Colum j = buf.GetJSON(i) if j.TypeCode != json.TypeCodeObject { - return json.ErrInvalidJSONData + result.AppendNull() + continue } result.AppendJSON(j.GetKeys()) } @@ -522,10 +523,6 @@ func (b *builtinJSONKeys2ArgsSig) vecEvalJSON(input *chunk.Chunk, result *chunk. continue } - jsonItem := jsonBuf.GetJSON(i) - if jsonItem.TypeCode != json.TypeCodeObject { - return json.ErrInvalidJSONData - } pathExpr, err := json.ParseJSONPathExpr(pathBuf.GetString(i)) if err != nil { return err @@ -534,6 +531,12 @@ func (b *builtinJSONKeys2ArgsSig) vecEvalJSON(input *chunk.Chunk, result *chunk. return json.ErrInvalidJSONPathWildcard } + jsonItem := jsonBuf.GetJSON(i) + if jsonItem.TypeCode != json.TypeCodeObject { + result.AppendNull() + continue + } + res, exists := jsonItem.Extract([]json.PathExpression{pathExpr}) if !exists || res.TypeCode != json.TypeCodeObject { result.AppendNull() diff --git a/expression/integration_test.go b/expression/integration_test.go index 551640867d..21bf93d1ca 100755 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -4058,13 +4058,13 @@ func (s *testIntegrationSuite) TestFuncJSON(c *C) { r.Check(testkit.Rows("1 0 1 0")) r = tk.MustQuery(`select - + json_keys('[]'), json_keys('{}'), json_keys('{"a": 1, "b": 2}'), json_keys('{"a": {"c": 3}, "b": 2}'), json_keys('{"a": {"c": 3}, "b": 2}', "$.a") `) - r.Check(testkit.Rows(`[] ["a", "b"] ["a", "b"] ["c"]`)) + r.Check(testkit.Rows(` [] ["a", "b"] ["a", "b"] ["c"]`)) r = tk.MustQuery(`select json_length('1'),