summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2017-02-06 06:47:48 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2017-02-06 06:47:48 +0400
commitabf7582112645ef8decc549eb662a07072b5cd32 (patch)
tree1082c1f2c8e32120cee647e0cd0374bd67c37b37
parente51b015fc354ec40c8430d4f4ea6346bc9a8e07b (diff)
downloadmariadb-git-abf7582112645ef8decc549eb662a07072b5cd32.tar.gz
MDEV-11557 port MySQL-5.7 JSON tests to MariaDB.
Fixes for issues found.
-rw-r--r--include/json_lib.h7
-rw-r--r--mysql-test/r/func_json.result85
-rw-r--r--mysql-test/suite/json/r/json_no_table.result309
-rw-r--r--mysql-test/t/func_json.test20
-rw-r--r--sql/item_create.cc72
-rw-r--r--sql/item_jsonfunc.cc226
-rw-r--r--sql/item_jsonfunc.h26
-rw-r--r--strings/json_lib.c110
8 files changed, 637 insertions, 218 deletions
diff --git a/include/json_lib.h b/include/json_lib.h
index ddba571ac59..cdfcffad38a 100644
--- a/include/json_lib.h
+++ b/include/json_lib.h
@@ -409,7 +409,12 @@ int json_get_path_start(json_engine_t *je, CHARSET_INFO *i_cs,
int json_get_path_next(json_engine_t *je, json_path_t *p);
-int json_path_compare(const json_path_t *a, const json_path_t *b);
+int json_path_parts_compare(
+ const json_path_step_t *a, const json_path_step_t *a_end,
+ const json_path_step_t *b, const json_path_step_t *b_end,
+ enum json_value_types vt);
+int json_path_compare(const json_path_t *a, const json_path_t *b,
+ enum json_value_types vt);
#ifdef __cplusplus
diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result
index 67a5dd20883..bfee73c2eef 100644
--- a/mysql-test/r/func_json.result
+++ b/mysql-test/r/func_json.result
@@ -57,7 +57,7 @@ json_array_append('["a", "b"]', '$', FALSE)
["a", "b", false]
select json_array_append('{"k1":1, "k2":["a", "b"]}', '$.k2', 2);
json_array_append('{"k1":1, "k2":["a", "b"]}', '$.k2', 2)
-{"k1":1, "k2":["a", "b", 2]}
+{"k1": 1, "k2": ["a", "b", 2]}
select json_array_append('["a", ["b", "c"], "d"]', '$[0]', 2);
json_array_append('["a", ["b", "c"], "d"]', '$[0]', 2)
[["a", 2], ["b", "c"], "d"]
@@ -190,10 +190,10 @@ json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY")
NULL
select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2");
json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2")
-["asd", [2,3]]
+["asd", [2, 3]]
select json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2");
json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2")
-[5, [2,3]]
+[5, [2, 3]]
select json_extract('{"key0":true, "key1":"qwe"}', "$.key1");
json_extract('{"key0":true, "key1":"qwe"}', "$.key1")
"qwe"
@@ -205,7 +205,7 @@ json_extract('[10, 20, [30, 40]]', '$[2][*]')
[30, 40]
select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]');
json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]')
-[{"a":3}, 30, 40]
+[{"a": 3}, 30, 40]
select json_extract('1', '$');
json_extract('1', '$')
1
@@ -220,29 +220,29 @@ json_extract( '[{"a": [3, 4]}, {"b": 2}]', '$[0].a', '$[1].a')
[[3, 4]]
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word');
json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word')
-{"a":1, "b":{"c":1, "k1":"word"}, "d":[1, 2]}
+{"a": 1, "b": {"c": 1, "k1": "word"}, "d": [1, 2]}
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3);
json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3)
-{"a":1, "b":{"c":1}, "d":[1, 2, 3]}
+{"a": 1, "b": {"c": 1}, "d": [1, 2, 3]}
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2);
json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.a[2]', 2)
-{"a":[1, 2], "b":{"c":1}, "d":[1, 2]}
+{"a": [1, 2], "b": {"c": 1}, "d": [1, 2]}
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word');
json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.c', 'word')
-{"a":1, "b":{"c":1}, "d":[1, 2]}
+{"a": 1, "b": {"c": 1}, "d": [1, 2]}
select json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]');
json_set('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]')
-{ "a": 10, "b": [2, 3], "c":"[true, false]"}
+{"a": 10, "b": [2, 3], "c": "[true, false]"}
select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]');
json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.c', '[true, false]')
-{ "a": 10, "b": [2, 3]}
+{"a": 10, "b": [2, 3]}
select json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]');
json_replace('{ "a": 1, "b": [2, 3]}', '$.a', 10, '$.b', '[true, false]')
-{ "a": 10, "b": "[true, false]"}
+{"a": 10, "b": "[true, false]"}
set @j = '["a", ["b", "c"], "d"]';
select json_remove(@j, '$[0]');
json_remove(@j, '$[0]')
-[ ["b", "c"], "d"]
+[["b", "c"], "d"]
select json_remove(@j, '$[1]');
json_remove(@j, '$[1]')
["a", "d"]
@@ -323,7 +323,7 @@ Warnings:
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_merge' at position 1
select json_merge('{"a":"b"}','{"c":"d"}');
json_merge('{"a":"b"}','{"c":"d"}')
-{"a":"b", "c":"d"}
+{"a": "b", "c": "d"}
SELECT JSON_MERGE('[1, 2]', '{"id": 47}');
JSON_MERGE('[1, 2]', '{"id": 47}')
[1, 2, {"id": 47}]
@@ -485,15 +485,13 @@ json_set('{"a":12}', '$[0]', 100)
100
select json_set('{"a":12}', '$[0].a', 100);
json_set('{"a":12}', '$[0].a', 100)
-{"a":100}
+{"a": 100}
select json_set('{"a":12}', '$[0][0].a', 100);
json_set('{"a":12}', '$[0][0].a', 100)
-{"a":100}
+{"a": 100}
select json_set('{"a":12}', '$[0][1].a', 100);
json_set('{"a":12}', '$[0][1].a', 100)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
+{"a": 12}
select json_value('{"\\"key1":123}', '$."\\"key1"');
json_value('{"\\"key1":123}', '$."\\"key1"')
123
@@ -503,3 +501,54 @@ json_value('{"\\"key1\\"":123}', '$."\\"key1\\""')
select json_value('{"key 1":123}', '$."key 1"');
json_value('{"key 1":123}', '$."key 1"')
123
+select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]");
+json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]")
+1
+select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]");
+json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]")
+0
+select json_extract( '[1]', '$[0][0]' );
+json_extract( '[1]', '$[0][0]' )
+1
+select json_extract( '[1]', '$[1][0]' );
+json_extract( '[1]', '$[1][0]' )
+NULL
+select json_extract( '[1]', '$**[0]' );
+json_extract( '[1]', '$**[0]' )
+[1]
+select json_extract( '[1]', '$**[0][0]' );
+json_extract( '[1]', '$**[0][0]' )
+[1]
+select json_insert('1', '$[0]', 4);
+json_insert('1', '$[0]', 4)
+1
+select json_replace('1', '$[0]', 4);
+json_replace('1', '$[0]', 4)
+4
+select json_set('1', '$[0]', 4);
+json_set('1', '$[0]', 4)
+4
+select json_set('1', '$[1]', 4);
+json_set('1', '$[1]', 4)
+[1, 4]
+select json_replace('1', '$[1]', 4);
+json_replace('1', '$[1]', 4)
+1
+SELECT json_insert('[]', '$[0][0]', 100);
+json_insert('[]', '$[0][0]', 100)
+[]
+SELECT json_insert('1', '$[0][0]', 100);
+json_insert('1', '$[0][0]', 100)
+1
+SELECT json_replace('1', '$[0][0]', 100);
+json_replace('1', '$[0][0]', 100)
+100
+SELECT json_replace('[]', '$[0][0]', 100);
+json_replace('[]', '$[0][0]', 100)
+[]
+SELECT json_set('[]', '$[0][0]', 100);
+json_set('[]', '$[0][0]', 100)
+[]
+SELECT json_set('[]', '$[0][0][0]', 100);
+json_set('[]', '$[0][0][0]', 100)
+[]
diff --git a/mysql-test/suite/json/r/json_no_table.result b/mysql-test/suite/json/r/json_no_table.result
index 3660a37814c..3201d0fc432 100644
--- a/mysql-test/suite/json/r/json_no_table.result
+++ b/mysql-test/suite/json/r/json_no_table.result
@@ -710,19 +710,19 @@ Warnings:
Warning 4044 Wildcards in JSON path not allowed in argument 3 to function 'json_remove'
select json_remove( '[ 1, 2, 3 ]', '$[0]' );
json_remove( '[ 1, 2, 3 ]', '$[0]' )
-[ 2, 3 ]
+[2, 3]
select json_remove( '[ 1, 2, 3 ]', '$[1]' );
json_remove( '[ 1, 2, 3 ]', '$[1]' )
-[ 1, 3 ]
+[1, 3]
select json_remove( '[ 1, 2, 3 ]', '$[2]' );
json_remove( '[ 1, 2, 3 ]', '$[2]' )
-[ 1, 2]
+[1, 2]
select json_remove( '[ 1, 2, 3 ]', '$[3]' );
json_remove( '[ 1, 2, 3 ]', '$[3]' )
-[ 1, 2, 3 ]
+[1, 2, 3]
select json_remove( '[ 1, { "a": true, "b": false, "c": null }, 5 ]', '$[1]' );
json_remove( '[ 1, { "a": true, "b": false, "c": null }, 5 ]', '$[1]' )
-[ 1, 5 ]
+[1, 5]
error ER_INVALID_JSON_PATH_WILDCARD
select json_remove( '[ { "a": { "a": true } } ]', '$**.a' );
json_remove( '[ { "a": { "a": true } } ]', '$**.a' )
@@ -731,7 +731,7 @@ Warnings:
Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_remove'
select json_remove( '[ { "a": true }, { "b": false }, { "c": null }, { "a": null } ]', '$[0].a', '$[2].c' );
json_remove( '[ { "a": true }, { "b": false }, { "c": null }, { "a": null } ]', '$[0].a', '$[2].c' )
-[ { }, { "b": false }, { }, { "a": null } ]
+[{}, {"b": false}, {}, {"a": null}]
error ER_INVALID_JSON_PATH_WILDCARD
select json_remove( '[ { "a": true }, { "b": [ { "c": { "a": true } } ] }, { "c": null }, { "a": null } ]', '$**.a' );
json_remove( '[ { "a": true }, { "b": [ { "c": { "a": true } } ] }, { "c": null }, { "a": null } ]', '$**.a' )
@@ -751,7 +751,7 @@ JSON_REMOVE
'{"a" : "foo", "b" : [true, {"c" : 123}]}',
'$.b[ 1 ]'
)
-{"a" : "foo", "b" : [true, {"c" : 123}]}
+{"a": "foo", "b": [true]}
SELECT JSON_REMOVE
(
'{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
@@ -762,9 +762,7 @@ JSON_REMOVE
'{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
'$.b[ 1 ].c'
)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_remove'
+{"a": "foo", "b": [true, {"c": 456}]}
SELECT JSON_REMOVE
(
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
@@ -775,9 +773,7 @@ JSON_REMOVE
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c'
)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_remove'
+{"a": "foo", "b": [true, {}]}
SELECT JSON_REMOVE
(
'{ "a" : "foo", "b" : [ true, { "c" : 123, "d" : 456 } ] }',
@@ -788,9 +784,7 @@ JSON_REMOVE
'{ "a" : "foo", "b" : [ true, { "c" : 123, "d" : 456 } ] }',
'$.b[ 1 ].e'
)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_remove'
+{"a": "foo", "b": [true, {"c": 123, "d": 456}]}
# ----------------------------------------------------------------------
# Test of JSON_MERGE function.
# ----------------------------------------------------------------------
@@ -823,7 +817,9 @@ NULL
error ER_INVALID_JSON_TEXT_IN_PARAM
select json_merge( '[1, 2]', '[3, 4' );
json_merge( '[1, 2]', '[3, 4' )
-[1, 2, 3, 4
+NULL
+Warnings:
+Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_merge'
error ER_INVALID_JSON_TEXT_IN_PARAM
select json_merge( '[1, 2', '[3, 4]' );
json_merge( '[1, 2', '[3, 4]' )
@@ -841,55 +837,55 @@ json_merge( '[1, 2]', '3' )
[1, 2, 3]
select json_merge( '1', '{ "a": 2 }' );
json_merge( '1', '{ "a": 2 }' )
-[1, { "a": 2 }]
+[1, {"a": 2}]
select json_merge( '{ "a": 2 }', '1' );
json_merge( '{ "a": 2 }', '1' )
-[{ "a": 2 }, 1]
+[{"a": 2}, 1]
select json_merge( '[1, 2]', '[3, 4]' );
json_merge( '[1, 2]', '[3, 4]' )
[1, 2, 3, 4]
select json_merge( '{ "a": 2 }', '{ "b": 3}' );
json_merge( '{ "a": 2 }', '{ "b": 3}' )
-{ "a": 2 , "b": 3}
+{"a": 2, "b": 3}
select json_merge( '[1, 2]', '{ "a": 2 }' );
json_merge( '[1, 2]', '{ "a": 2 }' )
-[1, 2, { "a": 2 }]
+[1, 2, {"a": 2}]
select json_merge( '{ "a": 2 }', '[1, 2]' );
json_merge( '{ "a": 2 }', '[1, 2]' )
-[{ "a": 2 }, 1, 2]
+[{"a": 2}, 1, 2]
select json_merge( '{"a": 1, "b": 2 }', '{"b": 3, "d": 4 }' );
json_merge( '{"a": 1, "b": 2 }', '{"b": 3, "d": 4 }' )
-{"a": 1, "b": 2 , "b": 3, "d": 4 }
+{"a": 1, "b": 2, "b": 3, "d": 4}
select json_merge( '{"a": 1, "b": 2 }', '{"b": [3, 4], "d": 4 }' );
json_merge( '{"a": 1, "b": 2 }', '{"b": [3, 4], "d": 4 }' )
-{"a": 1, "b": 2 , "b": [3, 4], "d": 4 }
+{"a": 1, "b": 2, "b": [3, 4], "d": 4}
select json_merge( '{"a": 1, "b": [2, 3] }', '{"b": 4, "d": 4 }' );
json_merge( '{"a": 1, "b": [2, 3] }', '{"b": 4, "d": 4 }' )
-{"a": 1, "b": [2, 3] , "b": 4, "d": 4 }
+{"a": 1, "b": [2, 3], "b": 4, "d": 4}
select json_merge( '{"a": 1, "b": 2 }', '{"b": {"e": 7, "f": 8}, "d": 4 }' );
json_merge( '{"a": 1, "b": 2 }', '{"b": {"e": 7, "f": 8}, "d": 4 }' )
-{"a": 1, "b": 2 , "b": {"e": 7, "f": 8}, "d": 4 }
+{"a": 1, "b": 2, "b": {"e": 7, "f": 8}, "d": 4}
select json_merge( '{"b": {"e": 7, "f": 8}, "d": 4 }', '{"a": 1, "b": 2 }' );
json_merge( '{"b": {"e": 7, "f": 8}, "d": 4 }', '{"a": 1, "b": 2 }' )
-{"b": {"e": 7, "f": 8}, "d": 4 , "a": 1, "b": 2 }
+{"b": {"e": 7, "f": 8}, "d": 4, "a": 1, "b": 2}
select json_merge( '{"a": 1, "b": [2, 9] }', '{"b": [10, 11], "d": 4 }' );
json_merge( '{"a": 1, "b": [2, 9] }', '{"b": [10, 11], "d": 4 }' )
-{"a": 1, "b": [2, 9] , "b": [10, 11], "d": 4 }
+{"a": 1, "b": [2, 9], "b": [10, 11], "d": 4}
select json_merge( '{"a": 1, "b": [2, 9] }', '{"b": {"e": 7, "f": 8}, "d": 4 }' );
json_merge( '{"a": 1, "b": [2, 9] }', '{"b": {"e": 7, "f": 8}, "d": 4 }' )
-{"a": 1, "b": [2, 9] , "b": {"e": 7, "f": 8}, "d": 4 }
+{"a": 1, "b": [2, 9], "b": {"e": 7, "f": 8}, "d": 4}
select json_merge( '{"b": {"e": 7, "f": 8}, "d": 4 }', '{"a": 1, "b": [2, 9] }' );
json_merge( '{"b": {"e": 7, "f": 8}, "d": 4 }', '{"a": 1, "b": [2, 9] }' )
-{"b": {"e": 7, "f": 8}, "d": 4 , "a": 1, "b": [2, 9] }
+{"b": {"e": 7, "f": 8}, "d": 4, "a": 1, "b": [2, 9]}
select json_merge( '{"b": {"e": 7, "f": 8}, "d": 4 }', '{ "a": 1, "b": {"e": 20, "g": 21 } }' );
json_merge( '{"b": {"e": 7, "f": 8}, "d": 4 }', '{ "a": 1, "b": {"e": 20, "g": 21 } }' )
-{"b": {"e": 7, "f": 8}, "d": 4 , "a": 1, "b": {"e": 20, "g": 21 } }
+{"b": {"e": 7, "f": 8}, "d": 4, "a": 1, "b": {"e": 20, "g": 21}}
select json_merge( '1', '2', '3' );
json_merge( '1', '2', '3' )
[1, 2, 3]
select json_merge( '[1, 2 ]', '3', '[4, 5]' );
json_merge( '[1, 2 ]', '3', '[4, 5]' )
-[1, 2 , 3, 4, 5]
+[1, 2, 3, 4, 5]
select json_merge
(
'{ "a": true, "b": { "c": 3, "d": 4 }, "e": [ 1, 2 ] }',
@@ -902,7 +898,7 @@ json_merge
'{ "d": false, "b": { "g": 3, "d": 5 }, "f": [ 1, 2 ] }',
'{ "m": true, "b": { "h": 8, "d": 4 }, "e": [ 3, 4 ] }'
)
-{ "a": true, "b": { "c": 3, "d": 4 }, "e": [ 1, 2 ] , "d": false, "b": { "g": 3, "d": 5 }, "f": [ 1, 2 ] , "m": true, "b": { "h": 8, "d": 4 }, "e": [ 3, 4 ] }
+{"a": true, "b": {"c": 3, "d": 4}, "e": [1, 2], "d": false, "b": {"g": 3, "d": 5}, "f": [1, 2], "m": true, "b": {"h": 8, "d": 4}, "e": [3, 4]}
SELECT JSON_MERGE
(
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
@@ -913,7 +909,7 @@ JSON_MERGE
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'[ 5, 6]'
)
-[{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }, 5, 6]
+[{"a": "foo", "b": [true, {"c": 123}]}, 5, 6]
SELECT JSON_MERGE
(
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
@@ -924,7 +920,7 @@ JSON_MERGE
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'{ "b": [ false, 34 ] }'
)
-{ "a" : "foo", "b" : [ true, { "c" : 123 } ] , "b": [ false, 34 ] }
+{"a": "foo", "b": [true, {"c": 123}], "b": [false, 34]}
SELECT JSON_MERGE
(
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
@@ -935,7 +931,7 @@ JSON_MERGE
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'{ "b": "bar" }'
)
-{ "a" : "foo", "b" : [ true, { "c" : 123 } ] , "b": "bar" }
+{"a": "foo", "b": [true, {"c": 123}], "b": "bar"}
SELECT JSON_MERGE
(
'{ "a" : { "b" : 1 } }',
@@ -946,7 +942,7 @@ JSON_MERGE
'{ "a" : { "b" : 1 } }',
'{ "a" : { "c" : 1 } }'
)
-{ "a" : { "b" : 1 } , "a" : { "c" : 1 } }
+{"a": {"b": 1}, "a": {"c": 1}}
# ----------------------------------------------------------------------
# Test of JSON_TYPE function.
# ----------------------------------------------------------------------
@@ -1296,16 +1292,16 @@ json_extract( '{ "a": 1}', '$.a' )
1
select json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[0]' );
json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[0]' )
-[ 3, 2 ]
+[3, 2]
select json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[0][1]' );
json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[0][1]' )
2
select json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[1]' );
json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[1]' )
-[ { "c" : "d" }, 1 ]
+[{"c": "d"}, 1]
select json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[1][0]' );
json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[1][0]' )
-{ "c" : "d" }
+{"c": "d"}
select json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[1][0].c' );
json_extract( '{ "a": [ [ 3, 2 ], [ { "c" : "d" }, 1 ] ], "b": { "c" : 6 }, "one potato": 7, "b.c" : 8 }', '$.a[1][0].c' )
"d"
@@ -1359,13 +1355,13 @@ SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }',
'$.b[ 1 ].c');
JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }',
'$.b[ 1 ].c')
-NULL
+"123"
# returns a JSON value containing just the number 123
SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c');
JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c')
-NULL
+123
# raises an error because the document is not valid
error ER_INVALID_JSON_TEXT_IN_PARAM
SELECT JSON_EXTRACT('{ "a" : [ }',
@@ -1390,13 +1386,13 @@ SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c[ 0 ]');
JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c[ 0 ]')
-NULL
+123
# returns a JSON value containing the object because of auto-wrapping
SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : {"not array": 4} } ] }',
'$.b[ 1 ].c[ 0 ]');
JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : {"not array": 4} } ] }',
'$.b[ 1 ].c[ 0 ]')
-NULL
+{"not array": 4}
# returns null because the path, although valid, does not identify a value
SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c[ 1 ]');
@@ -1408,7 +1404,7 @@ SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
'$.b[ 1 ].c');
JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
'$.b[ 1 ].c')
-NULL
+123
# returns a JSON array [ "foo", true ]
SELECT JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
'$.a', '$.b[0]');
@@ -1423,48 +1419,48 @@ JSON_EXTRACT('{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
[true]
select json_extract( '[1]', '$[0][0]' );
json_extract( '[1]', '$[0][0]' )
-NULL
+1
select json_extract( '[1]', '$**[0]' );
json_extract( '[1]', '$**[0]' )
[1]
select json_extract( '{ "a": 1 }', '$.a[0]' );
json_extract( '{ "a": 1 }', '$.a[0]' )
-NULL
+1
select json_extract( '{ "a": 1 }', '$**[0]' );
json_extract( '{ "a": 1 }', '$**[0]' )
-NULL
+[{"a": 1}, 1]
select json_extract( '{ "a": 1 }', '$[0].a' );
json_extract( '{ "a": 1 }', '$[0].a' )
-NULL
+1
select json_extract( '{ "a": 1 }', '$**.a' );
json_extract( '{ "a": 1 }', '$**.a' )
[1]
select json_extract( '{ "a": 1 }', '$[0].a[0]' );
json_extract( '{ "a": 1 }', '$[0].a[0]' )
-NULL
+1
select json_extract( '{ "a": 1 }', '$**[0]' );
json_extract( '{ "a": 1 }', '$**[0]' )
-NULL
+[{"a": 1}, 1]
select json_extract( '{ "a": 1 }', '$[0].a' );
json_extract( '{ "a": 1 }', '$[0].a' )
-NULL
+1
select json_extract( '{ "a": 1 }', '$**.a' );
json_extract( '{ "a": 1 }', '$**.a' )
[1]
select json_extract( '{ "a": 1 }', '$[0][0].a' );
json_extract( '{ "a": 1 }', '$[0][0].a' )
-NULL
+1
select json_extract( '{ "a": 1 }', '$[0][0][0].a' );
json_extract( '{ "a": 1 }', '$[0][0][0].a' )
-NULL
+1
SELECT JSON_EXTRACT('[1, [[{"x": [{"a":{"b":{"c":42}}}]}]]]', '$**.a.*');
JSON_EXTRACT('[1, [[{"x": [{"a":{"b":{"c":42}}}]}]]]', '$**.a.*')
-[{"c":42}]
+[{"c": 42}]
SELECT JSON_EXTRACT('[1, [[{"x": [{"a":{"b":{"c":42}}}]}]]]',
'$[1][0][0].x[0].a.*');
JSON_EXTRACT('[1, [[{"x": [{"a":{"b":{"c":42}}}]}]]]',
'$[1][0][0].x[0].a.*')
-[{"c":42}]
+[{"c": 42}]
SELECT JSON_EXTRACT
(
'{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }',
@@ -1475,7 +1471,7 @@ JSON_EXTRACT
'{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }',
'$.b[ 1 ].c'
)
-NULL
+"123"
SELECT JSON_EXTRACT
(
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
@@ -1486,7 +1482,7 @@ JSON_EXTRACT
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c'
)
-NULL
+123
error ER_INVALID_JSON_TEXT_IN_PARAM
SELECT JSON_EXTRACT
(
@@ -1525,7 +1521,7 @@ JSON_EXTRACT
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
'$.b[ 1 ].c[ 0 ]'
)
-NULL
+123
SELECT JSON_EXTRACT
(
'{ "a" : "foo", "b" : [ true, { "c" : 123 } ] }',
@@ -1547,7 +1543,7 @@ JSON_EXTRACT
'{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
'$.b[ 1 ].c'
)
-NULL
+123
SELECT JSON_EXTRACT
(
'{ "a" : "foo", "b" : [ true, { "c" : 123, "c" : 456 } ] }',
@@ -1587,13 +1583,13 @@ jdoc
[1]
select json_extract( '[ { "a": [3,4] }, { "b": 2 } ]', '$[0].a' ) jdoc;
jdoc
-[3,4]
+[3, 4]
select json_extract( '[ { "a": [3,4] }, { "b": 2 } ]', '$[*].a' ) jdoc;
jdoc
-[[3,4]]
+[[3, 4]]
select json_extract( '[ { "a": [3,4] }, { "b": 2 } ]', '$[0].a', '$[1].a' ) jdoc;
jdoc
-[[3,4]]
+[[3, 4]]
# ----------------------------------------------------------------------
# Test of JSON_ARRAY_APPEND function.
# ----------------------------------------------------------------------
@@ -1605,7 +1601,7 @@ json_array_append('[1,2,3]', NULL, cast(1 as json))
NULL
select json_array_append('[1,2,3]', '$', NULL);
json_array_append('[1,2,3]', '$', NULL)
-[1,2,3, null]
+[1, 2, 3, null]
select json_array_append(NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_array_append'
select json_array_append(NULL, NULL);
@@ -1641,14 +1637,14 @@ SELECT JSON_ARRAY_APPEND('{"a" : "foo","b": [1, 2, 3], "c": ["apple", "pear"]}',
JSON_ARRAY_APPEND('{"a" : "foo","b": [1, 2, 3], "c": ["apple", "pear"]}',
'$.b', cast(4 as json),
'$.c', cast('"grape"' as json))
-{"a" : "foo","b": [1, 2, 3, 4], "c": ["apple", "pear", "grape"]}
+{"a": "foo", "b": [1, 2, 3, 4], "c": ["apple", "pear", "grape"]}
SELECT JSON_ARRAY_APPEND('{"a" : "foo","b": [1, 2, 3], "c": ["apple", "pear"]}',
'$.b', 4,
'$.c', 'grape');
JSON_ARRAY_APPEND('{"a" : "foo","b": [1, 2, 3], "c": ["apple", "pear"]}',
'$.b', 4,
'$.c', 'grape')
-{"a" : "foo","b": [1, 2, 3, 4], "c": ["apple", "pear", "grape"]}
+{"a": "foo", "b": [1, 2, 3, 4], "c": ["apple", "pear", "grape"]}
error ER_INVALID_JSON_PATH_WILDCARD
select json_array_append( '[[], [], []]', '$[*]', 3, '$[*]', 4);
json_array_append( '[[], [], []]', '$[*]', 3, '$[*]', 4)
@@ -1673,7 +1669,7 @@ JSON_ARRAY_APPEND
'$.b', 4,
'$.c', "grape"
)
-{ "a" : "foo", "b" : ["bar", 4], "c" : ["wibble", "grape"] }
+{"a": "foo", "b": ["bar", 4], "c": ["wibble", "grape"]}
SELECT JSON_ARRAY_APPEND
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ], "c" : [ "apple", "pear" ] }',
@@ -1686,13 +1682,13 @@ JSON_ARRAY_APPEND
'$.b', 4,
'$.c', "grape"
)
-{ "a" : "foo", "b" : [ 1, 2, 3 , 4], "c" : [ "apple", "pear" , "grape"] }
+{"a": "foo", "b": [1, 2, 3, 4], "c": ["apple", "pear", "grape"]}
# ----------------------------------------------------------------------
# Bug#21373874 ASSERTION `PARENT' FAILED
# ----------------------------------------------------------------------
select json_array_append('{"a":1}', '$[0]', 100);
json_array_append('{"a":1}', '$[0]', 100)
-[{"a":1}, 100]
+[{"a": 1}, 100]
select json_array_append('3', '$[0]', 100);
json_array_append('3', '$[0]', 100)
[3, 100]
@@ -1710,7 +1706,7 @@ json_insert('[1,2,3]', NULL, cast(1 as json))
NULL
select json_insert('[1,2,3]', '$[3]', NULL);
json_insert('[1,2,3]', '$[3]', NULL)
-[1,2,3, null]
+[1, 2, 3, null]
select json_insert(NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_insert'
select json_insert(NULL, NULL);
@@ -1719,25 +1715,25 @@ select json_insert(NULL, NULL, NULL, NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_insert'
select json_insert('[1,2,3]', '$[2]', 4);
json_insert('[1,2,3]', '$[2]', 4)
-[1,2,3]
+[1, 2, 3]
select json_insert('[1,2,3]', '$[3]', 4);
json_insert('[1,2,3]', '$[3]', 4)
-[1,2,3, 4]
+[1, 2, 3, 4]
select json_insert('[1,2,3]', '$[10]', 4);
json_insert('[1,2,3]', '$[10]', 4)
-[1,2,3, 4]
+[1, 2, 3, 4]
select json_insert('{"c":4}', '$.c', 4);
json_insert('{"c":4}', '$.c', 4)
-{"c":4}
+{"c": 4}
select json_insert('{"c":4}', '$.a', 4);
json_insert('{"c":4}', '$.a', 4)
-{"c":4, "a":4}
+{"c": 4, "a": 4}
select json_insert('1', '$', 4);
json_insert('1', '$', 4)
1
select json_insert('1', '$[0]', 4);
json_insert('1', '$[0]', 4)
-[1, 4]
+1
select json_insert('1', '$[1]', 4);
json_insert('1', '$[1]', 4)
[1, 4]
@@ -1746,13 +1742,13 @@ json_insert('1', '$[10]', '4', '$[11]', 5)
[1, "4", 5]
select json_insert('[1,2,3]', '$[2][0]', 4);
json_insert('[1,2,3]', '$[2][0]', 4)
-[1,2,[3, 4]]
+[1, 2, 3]
select json_insert('[1,2,3]', '$[2][2]', 4);
json_insert('[1,2,3]', '$[2][2]', 4)
-[1,2,[3, 4]]
+[1, 2, [3, 4]]
select json_insert('{"a": 3}', '$.a[0]', 4);
json_insert('{"a": 3}', '$.a[0]', 4)
-{"a": [3, 4]}
+{"a": 3}
select json_insert('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5');
json_insert('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5')
{"a": [3, 4, "5"]}
@@ -1833,19 +1829,19 @@ json_insert(cast('{"a": 3}' as json), '$[1]', 6)
[{"a": 3}, 6]
SELECT JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.a', true);
JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.a', true)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] }
+{"a": "foo", "b": [1, 2, 3]}
SELECT JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.c', 123);
JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.c', 123)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":123}
+{"a": "foo", "b": [1, 2, 3], "c": 123}
SELECT JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.c', '123');
JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.c', '123')
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":"123"}
+{"a": "foo", "b": [1, 2, 3], "c": "123"}
SELECT JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.a[1]', true);
JSON_INSERT('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', '$.a[1]', true)
-{ "a" : ["foo", true], "b" : [ 1, 2, 3 ] }
+{"a": ["foo", true], "b": [1, 2, 3]}
SELECT JSON_INSERT('{ "a" : "foo"}', '$.b', true, '$.b', false);
JSON_INSERT('{ "a" : "foo"}', '$.b', true, '$.b', false)
-{ "a" : "foo", "b":true}
+{"a": "foo", "b": true}
SELECT JSON_INSERT
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -1858,7 +1854,7 @@ JSON_INSERT
'$.a',
true
)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] }
+{"a": "foo", "b": [1, 2, 3]}
SELECT JSON_INSERT
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -1871,7 +1867,7 @@ JSON_INSERT
'$.c',
123
)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":123}
+{"a": "foo", "b": [1, 2, 3], "c": 123}
SELECT JSON_INSERT
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -1884,7 +1880,7 @@ JSON_INSERT
'$.c',
'123'
)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":"123"}
+{"a": "foo", "b": [1, 2, 3], "c": "123"}
SELECT JSON_INSERT
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -1897,7 +1893,7 @@ JSON_INSERT
'$.a[1]',
true
)
-{ "a" : ["foo", true], "b" : [ 1, 2, 3 ] }
+{"a": ["foo", true], "b": [1, 2, 3]}
SELECT JSON_INSERT
(
'{ "a" : "foo"}',
@@ -1910,7 +1906,7 @@ JSON_INSERT
'$.b', true,
'$.b', false
)
-{ "a" : "foo", "b":true}
+{"a": "foo", "b": true}
# ----------------------------------------------------------------------
# Test of JSON_ARRAY_INSERT function.
# ----------------------------------------------------------------------
@@ -1922,7 +1918,7 @@ json_array_insert('[1,2,3]', NULL, 1)
NULL
select json_array_insert('[1,2,3]', '$[3]', NULL);
json_array_insert('[1,2,3]', '$[3]', NULL)
-[1,2,3, null]
+[1, 2, 3, null]
select json_array_insert(NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_array_insert'
select json_array_insert(NULL, NULL);
@@ -1949,10 +1945,10 @@ json_array_insert( 'true', '$[1]', false )
true
select json_array_insert( '{ "a": true }', '$.a[0]', false );
json_array_insert( '{ "a": true }', '$.a[0]', false )
-{ "a": true }
+{"a": true}
select json_array_insert( '{ "a": true }', '$.a[1]', false );
json_array_insert( '{ "a": true }', '$.a[1]', false )
-{ "a": true }
+{"a": true}
select json_array_insert( '[]', '$[0]', false );
json_array_insert( '[]', '$[0]', false )
[false]
@@ -1970,19 +1966,19 @@ json_array_insert( '[true]', '$[2]', false )
[true, false]
select json_array_insert( '{ "a": [] }', '$.a[0]', false );
json_array_insert( '{ "a": [] }', '$.a[0]', false )
-{ "a": [false] }
+{"a": [false]}
select json_array_insert( '{ "a": [] }', '$.a[1]', false );
json_array_insert( '{ "a": [] }', '$.a[1]', false )
-{ "a": [false] }
+{"a": [false]}
select json_array_insert( '{ "a": [true] }', '$.a[0]', false );
json_array_insert( '{ "a": [true] }', '$.a[0]', false )
-{ "a": [false, true] }
+{"a": [false, true]}
select json_array_insert( '{ "a": [true] }', '$.a[1]', false );
json_array_insert( '{ "a": [true] }', '$.a[1]', false )
-{ "a": [true, false] }
+{"a": [true, false]}
select json_array_insert( '{ "a": [true] }', '$.a[2]', false );
json_array_insert( '{ "a": [true] }', '$.a[2]', false )
-{ "a": [true, false] }
+{"a": [true, false]}
select json_array_insert( '[1, 2, 3, 4]', '$[0]', false );
json_array_insert( '[1, 2, 3, 4]', '$[0]', false )
[false, 1, 2, 3, 4]
@@ -2003,34 +1999,34 @@ json_array_insert( '[1, 2, 3, 4]', '$[5]', false )
[1, 2, 3, 4, false]
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[0]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[0]', false )
-{ "a": [false, 1, 2, 3, 4] }
+{"a": [false, 1, 2, 3, 4]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[1]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[1]', false )
-{ "a": [1, false, 2, 3, 4] }
+{"a": [1, false, 2, 3, 4]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[2]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[2]', false )
-{ "a": [1, 2, false, 3, 4] }
+{"a": [1, 2, false, 3, 4]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[3]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[3]', false )
-{ "a": [1, 2, 3, false, 4] }
+{"a": [1, 2, 3, false, 4]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[4]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[4]', false )
-{ "a": [1, 2, 3, 4, false] }
+{"a": [1, 2, 3, 4, false]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[5]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.a[5]', false )
-{ "a": [1, 2, 3, 4, false] }
+{"a": [1, 2, 3, 4, false]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.b[0]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.b[0]', false )
-{ "a": [1, 2, 3, 4] }
+{"a": [1, 2, 3, 4]}
select json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.b[1]', false );
json_array_insert( '{ "a": [1, 2, 3, 4] }', '$.b[1]', false )
-{ "a": [1, 2, 3, 4] }
+{"a": [1, 2, 3, 4]}
select json_array_insert( '"a"', '$[0]', true );
json_array_insert( '"a"', '$[0]', true )
"a"
select json_array_insert( '[ "a" ]', '$[0][0]', true );
json_array_insert( '[ "a" ]', '$[0][0]', true )
-[ "a" ]
+["a"]
select json_array_insert( '"a"', '$[1]', true );
json_array_insert( '"a"', '$[1]', true )
"a"
@@ -2054,12 +2050,12 @@ Warnings:
Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
select json_array_insert( '[ 1, 2, 3 ]', '$[1]', true, '$[1]', false );
json_array_insert( '[ 1, 2, 3 ]', '$[1]', true, '$[1]', false )
-[ 1, false, true, 2, 3 ]
+[1, false, true, 2, 3]
select json_array_insert( '[ 1, 2, 3 ]', '$[1]',
cast( '[ "a", "b", "c", "d" ]' as json ), '$[1][2]', false );
json_array_insert( '[ 1, 2, 3 ]', '$[1]',
cast( '[ "a", "b", "c", "d" ]' as json ), '$[1][2]', false )
-[ 1, [ "a", "b", false, "c", "d" ], 2, 3 ]
+[1, ["a", "b", false, "c", "d"], 2, 3]
error ER_INVALID_JSON_TEXT_IN_PARAM
SELECT JSON_ARRAY_INSERT(JSON_EXTRACT('[1', '$'), '$[0]', 1);
JSON_ARRAY_INSERT(JSON_EXTRACT('[1', '$'), '$[0]', 1)
@@ -2069,7 +2065,7 @@ Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_extract
error ER_INVALID_JSON_TEXT_IN_PARAM
select json_array_insert( '[ 1, 2, 3 ]', '$[1]', json_extract( '[', '$' ) );
json_array_insert( '[ 1, 2, 3 ]', '$[1]', json_extract( '[', '$' ) )
-[ 1, null, 2, 3 ]
+[1, null, 2, 3]
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_extract'
# ----------------------------------------------------------------------
@@ -2083,7 +2079,7 @@ json_set('[1,2,3]', NULL, cast(1 as json))
NULL
select json_set('[1,2,3]', '$[3]', NULL);
json_set('[1,2,3]', '$[3]', NULL)
-[1,2,3, null]
+[1, 2, 3, null]
select json_set(NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_set'
select json_set(NULL, NULL);
@@ -2093,24 +2089,25 @@ ERROR 42000: Incorrect parameter count in the call to native function 'json_set'
error ER_INVALID_JSON_TEXT_IN_PARAM
SELECT JSON_SET('{}', '$.name', JSON_EXTRACT('', '$'));
JSON_SET('{}', '$.name', JSON_EXTRACT('', '$'))
-{, "name":null}
+NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_extract'
+Warning 4038 Syntax error in JSON text in argument 1 to function 'json_set' at position 2
select json_set('[1,2,3]', '$[2]', 4);
json_set('[1,2,3]', '$[2]', 4)
-[1,2,4]
+[1, 2, 4]
select json_set('[1,2,3]', '$[3]', 4);
json_set('[1,2,3]', '$[3]', 4)
-[1,2,3, 4]
+[1, 2, 3, 4]
select json_set('[1,2,3]', '$[10]', 4);
json_set('[1,2,3]', '$[10]', 4)
-[1,2,3, 4]
+[1, 2, 3, 4]
select json_set('{"c":4}', '$.c', 5);
json_set('{"c":4}', '$.c', 5)
-{"c":5}
+{"c": 5}
select json_set('{"c":4}', '$.a', 5);
json_set('{"c":4}', '$.a', 5)
-{"c":4, "a":5}
+{"c": 4, "a": 5}
select json_set('1', '$', 4);
json_set('1', '$', 4)
4
@@ -2125,10 +2122,10 @@ json_set('1', '$[10]', '4', '$[11]', 5)
[1, "4", 5]
select json_set('[1,2,3]', '$[2][0]', 4);
json_set('[1,2,3]', '$[2][0]', 4)
-[1,2,4]
+[1, 2, 4]
select json_set('[1,2,3]', '$[2][2]', 4);
json_set('[1,2,3]', '$[2][2]', 4)
-[1,2,[3, 4]]
+[1, 2, [3, 4]]
select json_set('{"a": 3}', '$.a[0]', 4);
json_set('{"a": 3}', '$.a[0]', 4)
{"a": 4}
@@ -2147,26 +2144,26 @@ JSON_OBJECT());
JSON_SET('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a',
JSON_OBJECT())
-{ "a" : {}, "b" : [ 1, 2, 3 ] }
+{"a": {}, "b": [1, 2, 3]}
SELECT JSON_SET('{ "a" : "foo"}', '$.a',
JSON_OBJECT( 'b', false ), '$.a.c', true);
JSON_SET('{ "a" : "foo"}', '$.a',
JSON_OBJECT( 'b', false ), '$.a.c', true)
-{ "a" : {"b": false, "c":true}}
+{"a": {"b": false, "c": true}}
select json_set('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a',
cast('{}' as json));
json_set('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a',
cast('{}' as json))
-{ "a" : {}, "b" : [ 1, 2, 3 ] }
+{"a": {}, "b": [1, 2, 3]}
select json_set('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.c',
cast('[true, false]' as json));
json_set('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.c',
cast('[true, false]' as json))
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":[true, false]}
+{"a": "foo", "b": [1, 2, 3], "c": [true, false]}
select json_set('1', '$[3]', 2);
json_set('1', '$[3]', 2)
[1, 2]
@@ -2174,7 +2171,7 @@ select json_set('{ "a" : "foo"}', '$.a',
cast('{"b": false}' as json), '$.a.c', true);
json_set('{ "a" : "foo"}', '$.a',
cast('{"b": false}' as json), '$.a.c', true)
-{ "a" : {"b": false, "c":true}}
+{"a": {"b": false, "c": true}}
SELECT JSON_SET
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -2187,7 +2184,7 @@ JSON_SET
'$.a',
JSON_OBJECT()
)
-{ "a" : {}, "b" : [ 1, 2, 3 ] }
+{"a": {}, "b": [1, 2, 3]}
SELECT JSON_SET
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -2200,7 +2197,7 @@ JSON_SET
'$.c',
JSON_ARRAY( true, false )
)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":[true, false]}
+{"a": "foo", "b": [1, 2, 3], "c": [true, false]}
SELECT JSON_SET
(
'{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
@@ -2213,7 +2210,7 @@ JSON_SET
'$.c',
JSON_ARRAY( CAST( 'true' AS JSON ), CAST( 'false' AS JSON ) )
)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] , "c":[true, false]}
+{"a": "foo", "b": [1, 2, 3], "c": [true, false]}
SELECT JSON_SET
(
'1',
@@ -2239,7 +2236,7 @@ JSON_SET
'$.a', JSON_OBJECT( 'b', false ),
'$.a.c', true
)
-{ "a" : {"b": false, "c":true}}
+{"a": {"b": false, "c": true}}
# ----------------------------------------------------------------------
# Test of JSON_REPLACE function.
# ----------------------------------------------------------------------
@@ -2251,7 +2248,7 @@ json_replace('[1,2,3]', NULL, cast(1 as json))
NULL
select json_replace('[1,2,3]', '$[2]', NULL);
json_replace('[1,2,3]', '$[2]', NULL)
-[1,2,null]
+[1, 2, null]
select json_replace(NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_replace'
select json_replace(NULL, NULL);
@@ -2260,19 +2257,19 @@ select json_replace(NULL, NULL, NULL, NULL);
ERROR 42000: Incorrect parameter count in the call to native function 'json_replace'
select json_replace('[1,2,3]', '$[2]', 4);
json_replace('[1,2,3]', '$[2]', 4)
-[1,2,4]
+[1, 2, 4]
select json_replace('[1,2,3]', '$[3]', 4);
json_replace('[1,2,3]', '$[3]', 4)
-[1,2,3]
+[1, 2, 3]
select json_replace('[1,2,3]', '$[10]', 4);
json_replace('[1,2,3]', '$[10]', 4)
-[1,2,3]
+[1, 2, 3]
select json_replace('{"c":4}', '$.c', 5);
json_replace('{"c":4}', '$.c', 5)
-{"c":5}
+{"c": 5}
select json_replace('{"c":4}', '$.a', 5);
json_replace('{"c":4}', '$.a', 5)
-{"c":4}
+{"c": 4}
select json_replace('1', '$', 4);
json_replace('1', '$', 4)
4
@@ -2287,10 +2284,10 @@ json_replace('1', '$[10]', '4', '$[11]', 5)
1
select json_replace('[1,2,3]', '$[2][0]', 4);
json_replace('[1,2,3]', '$[2][0]', 4)
-[1,2,4]
+[1, 2, 4]
select json_replace('[1,2,3]', '$[2][2]', 4);
json_replace('[1,2,3]', '$[2][2]', 4)
-[1,2,3]
+[1, 2, 3]
select json_replace('{"a": 3}', '$.a[0]', 4);
json_replace('{"a": 3}', '$.a[0]', 4)
{"a": 4}
@@ -2303,21 +2300,21 @@ true);
JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.c',
true)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] }
+{"a": "foo", "b": [1, 2, 3]}
SELECT JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a[0]',
true);
JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a[0]',
true)
-{ "a" : true, "b" : [ 1, 2, 3 ] }
+{"a": true, "b": [1, 2, 3]}
SELECT JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.b[5]',
true);
JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.b[5]',
true)
-{ "a" : "foo", "b" : [ 1, 2, 3 ] }
+{"a": "foo", "b": [1, 2, 3]}
# ----------------------------------------------------------------------
# Test of JSON_ARRAY function.
# ----------------------------------------------------------------------
@@ -3231,38 +3228,38 @@ prepare json_stmt5 FROM 'select json_array_append( ''{ "keyA": [1, 2], "keyB": [
set @mypath = '$.keyA';
execute json_stmt5 USING @mypath;
json_array_append( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2, 5], "keyB": [3, 4] }
+{"keyA": [1, 2, 5], "keyB": [3, 4]}
set @mypath = '$.keyB';
execute json_stmt5 USING @mypath;
json_array_append( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2], "keyB": [3, 4, 5] }
+{"keyA": [1, 2], "keyB": [3, 4, 5]}
prepare json_stmt6 FROM 'select json_insert( ''{ "keyA": [1, 2], "keyB": [3, 4] }'', ?, 5 )';
set @mypath = '$.keyA[2]';
execute json_stmt6 USING @mypath;
json_insert( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2, 5], "keyB": [3, 4] }
+{"keyA": [1, 2, 5], "keyB": [3, 4]}
set @mypath = '$.keyB[2]';
execute json_stmt6 USING @mypath;
json_insert( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2], "keyB": [3, 4, 5] }
+{"keyA": [1, 2], "keyB": [3, 4, 5]}
prepare json_stmt7 FROM 'select json_set( ''{ "keyA": [1, 2], "keyB": [3, 4] }'', ?, 5 )';
set @mypath = '$.keyA[2]';
execute json_stmt7 USING @mypath;
json_set( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2, 5], "keyB": [3, 4] }
+{"keyA": [1, 2, 5], "keyB": [3, 4]}
set @mypath = '$.keyB[2]';
execute json_stmt7 USING @mypath;
json_set( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2], "keyB": [3, 4, 5] }
+{"keyA": [1, 2], "keyB": [3, 4, 5]}
prepare json_stmt8 FROM 'select json_replace( ''{ "keyA": [1, 2], "keyB": [3, 4] }'', ?, 5 )';
set @mypath = '$.keyA[1]';
execute json_stmt8 USING @mypath;
json_replace( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 5], "keyB": [3, 4] }
+{"keyA": [1, 5], "keyB": [3, 4]}
set @mypath = '$.keyB[1]';
execute json_stmt8 USING @mypath;
json_replace( '{ "keyA": [1, 2], "keyB": [3, 4] }', ?, 5 )
-{ "keyA": [1, 2], "keyB": [3, 5] }
+{"keyA": [1, 2], "keyB": [3, 5]}
prepare json_stmt9 FROM 'select json_search( ''{ "keyA": [ "foot" ], "keyB": [ "food" ] }'', ''all'', ''foo%'', null, ? )';
set @mypath = '$.keyA';
execute json_stmt9 USING @mypath;
@@ -3276,11 +3273,11 @@ prepare json_stmt10 FROM 'select json_remove( ''{ "keyA": [ "foot" ], "keyB": [
set @mypath = '$.keyA';
execute json_stmt10 USING @mypath;
json_remove( '{ "keyA": [ "foot" ], "keyB": [ "food" ] }', ? )
-{ "keyB": [ "food" ] }
+{"keyB": ["food"]}
set @mypath = '$.keyB';
execute json_stmt10 USING @mypath;
json_remove( '{ "keyA": [ "foot" ], "keyB": [ "food" ] }', ? )
-{ "keyA": [ "foot" ]}
+{"keyA": ["foot"]}
prepare json_stmt11 FROM 'select json_contains_path( ''{ "keyA": true }'', ?, ''$.keyA'', ''$.keyB'' )';
set @mypath = 'one';
execute json_stmt11 USING @mypath;
@@ -3502,14 +3499,10 @@ JSON_SET('[]', '$[0]', 100)
[100]
SELECT JSON_SET('[]', '$[0][0]', 100);
JSON_SET('[]', '$[0][0]', 100)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
+[]
SELECT JSON_SET('[]', '$[0][0][0]', 100);
JSON_SET('[]', '$[0][0][0]', 100)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
+[]
SELECT JSON_SET('[1]', '$', 100);
JSON_SET('[1]', '$', 100)
100
@@ -3566,14 +3559,10 @@ JSON_REPLACE('[]', '$[0]', 100)
[]
SELECT JSON_REPLACE('[]', '$[0][0]', 100);
JSON_REPLACE('[]', '$[0][0]', 100)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_update'
+[]
SELECT JSON_REPLACE('[]', '$[0][0][0]', 100);
JSON_REPLACE('[]', '$[0][0][0]', 100)
-NULL
-Warnings:
-Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_update'
+[]
SELECT JSON_REPLACE('[1]', '$', 100);
JSON_REPLACE('[1]', '$', 100)
100
diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test
index 546b5db77e3..2ed5282abc0 100644
--- a/mysql-test/t/func_json.test
+++ b/mysql-test/t/func_json.test
@@ -200,3 +200,23 @@ select json_set('{"a":12}', '$[0][1].a', 100);
select json_value('{"\\"key1":123}', '$."\\"key1"');
select json_value('{"\\"key1\\"":123}', '$."\\"key1\\""');
select json_value('{"key 1":123}', '$."key 1"');
+
+select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[2]");
+select json_contains_path('{"a":[{"c":[1,{"a":[0,1,2]},3]}], "b":[1,2,3]}', 'one', "$**.a[3]");
+
+select json_extract( '[1]', '$[0][0]' );
+select json_extract( '[1]', '$[1][0]' );
+select json_extract( '[1]', '$**[0]' );
+select json_extract( '[1]', '$**[0][0]' );
+
+select json_insert('1', '$[0]', 4);
+select json_replace('1', '$[0]', 4);
+select json_set('1', '$[0]', 4);
+select json_set('1', '$[1]', 4);
+select json_replace('1', '$[1]', 4);
+SELECT json_insert('[]', '$[0][0]', 100);
+SELECT json_insert('1', '$[0][0]', 100);
+SELECT json_replace('1', '$[0][0]', 100);
+SELECT json_replace('[]', '$[0][0]', 100);
+SELECT json_set('[]', '$[0][0]', 100);
+SELECT json_set('[]', '$[0][0][0]', 100);
diff --git a/sql/item_create.cc b/sql/item_create.cc
index add8da67810..d2be36e105f 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -1762,6 +1762,46 @@ protected:
};
+class Create_func_json_compact : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_json_compact s_singleton;
+
+protected:
+ Create_func_json_compact() {}
+ virtual ~Create_func_json_compact() {}
+};
+
+
+class Create_func_json_loose : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_json_loose s_singleton;
+
+protected:
+ Create_func_json_loose() {}
+ virtual ~Create_func_json_loose() {}
+};
+
+
+class Create_func_json_detailed : public Create_func_arg2
+{
+public:
+ virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_json_detailed s_singleton;
+
+protected:
+ Create_func_json_detailed() {}
+ virtual ~Create_func_json_detailed() {}
+};
+
+
+
class Create_func_json_type : public Create_func_arg1
{
public:
@@ -5003,6 +5043,35 @@ Create_func_json_exists::create_2_arg(THD *thd, Item *arg1, Item *arg2)
}
+Create_func_json_detailed Create_func_json_detailed::s_singleton;
+
+Item*
+Create_func_json_detailed::create_2_arg(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_json_format(thd, arg1, arg2);
+}
+
+
+Create_func_json_loose Create_func_json_loose::s_singleton;
+
+Item*
+Create_func_json_loose::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_json_format(thd, arg1,
+ Item_func_json_format::LOOSE);
+}
+
+
+Create_func_json_compact Create_func_json_compact::s_singleton;
+
+Item*
+Create_func_json_compact::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_json_format(thd, arg1,
+ Item_func_json_format::COMPACT);
+}
+
+
Create_func_json_valid Create_func_json_valid::s_singleton;
Item*
@@ -6728,14 +6797,17 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("JSON_ARRAY") }, BUILDER(Create_func_json_array)},
{ { C_STRING_WITH_LEN("JSON_ARRAY_APPEND") }, BUILDER(Create_func_json_array_append)},
{ { C_STRING_WITH_LEN("JSON_ARRAY_INSERT") }, BUILDER(Create_func_json_array_insert)},
+ { { C_STRING_WITH_LEN("JSON_COMPACT") }, BUILDER(Create_func_json_compact)},
{ { C_STRING_WITH_LEN("JSON_CONTAINS") }, BUILDER(Create_func_json_contains)},
{ { C_STRING_WITH_LEN("JSON_CONTAINS_PATH") }, BUILDER(Create_func_json_contains_path)},
{ { C_STRING_WITH_LEN("JSON_DEPTH") }, BUILDER(Create_func_json_depth)},
+ { { C_STRING_WITH_LEN("JSON_DETAILED") }, BUILDER(Create_func_json_detailed)},
{ { C_STRING_WITH_LEN("JSON_EXISTS") }, BUILDER(Create_func_json_exists)},
{ { C_STRING_WITH_LEN("JSON_EXTRACT") }, BUILDER(Create_func_json_extract)},
{ { C_STRING_WITH_LEN("JSON_INSERT") }, BUILDER(Create_func_json_insert)},
{ { C_STRING_WITH_LEN("JSON_KEYS") }, BUILDER(Create_func_json_keys)},
{ { C_STRING_WITH_LEN("JSON_LENGTH") }, BUILDER(Create_func_json_length)},
+ { { C_STRING_WITH_LEN("JSON_LOOSE") }, BUILDER(Create_func_json_loose)},
{ { C_STRING_WITH_LEN("JSON_MERGE") }, BUILDER(Create_func_json_merge)},
{ { C_STRING_WITH_LEN("JSON_QUERY") }, BUILDER(Create_func_json_query)},
{ { C_STRING_WITH_LEN("JSON_QUOTE") }, BUILDER(Create_func_json_quote)},
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index d1f82bc94da..73b0e6b0870 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -113,6 +113,100 @@ static int st_append_escaped(String *s, const String *a)
}
+static int json_nice(json_engine_t *je, String *nice_js,
+ Item_func_json_format::formats mode)
+{
+ int depth= 0;
+ const char *comma, *colon;
+ uint comma_len, colon_len;
+ int first_value= 1;
+
+ DBUG_ASSERT(je->s.cs == nice_js->charset());
+
+ if (mode == Item_func_json_format::LOOSE)
+ {
+ comma= ", ";
+ comma_len= 2;
+ colon= "\": ";
+ colon_len= 3;
+ }
+ else
+ {
+ comma= ",";
+ comma_len= 1;
+ colon= "\":";
+ colon_len= 2;
+ }
+
+ do
+ {
+ switch (je->state)
+ {
+ case JST_KEY:
+ {
+ const uchar *key_start= je->s.c_str;
+ const uchar *key_end;
+
+ while (json_read_keyname_chr(je) == 0)
+ key_end= je->s.c_str;
+
+ if (je->s.error)
+ goto error;
+
+ if (!first_value)
+ nice_js->append(comma, comma_len);
+
+ nice_js->append("\"", 1);
+ append_simple(nice_js, key_start, key_end - key_start);
+ nice_js->append(colon, colon_len);
+ }
+ /* now we have key value to handle, so no 'break'. */
+ DBUG_ASSERT(je->state == JST_VALUE);
+ goto handle_value;
+
+ case JST_VALUE:
+ if (!first_value)
+ nice_js->append(comma, comma_len);
+
+handle_value:
+ if (json_read_value(je))
+ goto error;
+ if (json_value_scalar(je))
+ {
+ if (append_simple(nice_js, je->value_begin,
+ je->value_end - je->value_begin))
+ goto error;
+
+ first_value= 0;
+ }
+ else
+ {
+ nice_js->append((je->value_type == JSON_VALUE_OBJECT) ? "{" : "[", 1);
+ first_value= 1;
+ depth++;
+ }
+
+ break;
+
+ case JST_OBJ_END:
+ case JST_ARRAY_END:
+ depth--;
+ nice_js->append((je->state == JST_OBJ_END) ? "}": "]", 1);
+ first_value= 0;
+ break;
+
+ default:
+ break;
+ };
+ } while (json_scan_next(je) == 0);
+
+ return je->s.error;
+
+error:
+ return 1;
+}
+
+
#define report_json_error(js, je, n_param) \
report_json_error_ex(js, je, func_name(), n_param, \
Sql_condition::WARN_LEVEL_WARN)
@@ -554,11 +648,11 @@ void Item_func_json_extract::fix_length_and_dec()
static bool path_exact(const json_path_with_flags *paths_list, int n_paths,
- const json_path_t *p)
+ const json_path_t *p, enum json_value_types vt)
{
for (; n_paths > 0; n_paths--, paths_list++)
{
- if (json_path_compare(&paths_list->p, p) == 0)
+ if (json_path_compare(&paths_list->p, p, vt) == 0)
return TRUE;
}
return FALSE;
@@ -566,11 +660,11 @@ static bool path_exact(const json_path_with_flags *paths_list, int n_paths,
static bool path_ok(const json_path_with_flags *paths_list, int n_paths,
- const json_path_t *p)
+ const json_path_t *p, enum json_value_types vt)
{
for (; n_paths > 0; n_paths--, paths_list++)
{
- if (json_path_compare(&paths_list->p, p) >= 0)
+ if (json_path_compare(&paths_list->p, p, vt) >= 0)
return TRUE;
}
return FALSE;
@@ -624,7 +718,7 @@ String *Item_func_json_extract::val_str(String *str)
while (json_get_path_next(&je, &p) == 0)
{
- if (!path_exact(paths, arg_count-1, &p))
+ if (!path_exact(paths, arg_count-1, &p, je.value_type))
continue;
value= je.value_begin;
@@ -661,10 +755,18 @@ String *Item_func_json_extract::val_str(String *str)
goto return_null;
}
- if (possible_multiple_values && str->append("]"))
+ if (possible_multiple_values && str->append("]", 1))
goto error; /* Out of memory. */
- return str;
+ js= str;
+ json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
+ (const uchar *) js->ptr() + js->length());
+ tmp_js.length(0);
+ tmp_js.set_charset(js->charset());
+ if (json_nice(&je, &tmp_js, Item_func_json_format::LOOSE))
+ goto error;
+
+ return &tmp_js;
error:
report_json_error(js, &je, 0);
@@ -1153,7 +1255,7 @@ longlong Item_func_json_contains_path::val_int()
json_path_with_flags *c_path= paths;
for (; n_path > 0; n_path--, c_path++)
{
- if (json_path_compare(&c_path->p, &p) >= 0)
+ if (json_path_compare(&c_path->p, &p, je.value_type) >= 0)
{
if (mode_one)
{
@@ -1424,7 +1526,14 @@ String *Item_func_json_array_append::val_str(String *str)
}
}
- return js;
+ json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
+ (const uchar *) js->ptr() + js->length());
+ str->length(0);
+ str->set_charset(js->charset());
+ if (json_nice(&je, str, Item_func_json_format::LOOSE))
+ goto js_error;
+
+ return str;
js_error:
report_json_error(js, &je, 0);
@@ -1558,7 +1667,14 @@ String *Item_func_json_array_insert::val_str(String *str)
}
}
- return js;
+ json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
+ (const uchar *) js->ptr() + js->length());
+ str->length(0);
+ str->set_charset(js->charset());
+ if (json_nice(&je, str, Item_func_json_format::LOOSE))
+ goto js_error;
+
+ return str;
js_error:
report_json_error(js, &je, 0);
@@ -1690,8 +1806,15 @@ String *Item_func_json_merge::val_str(String *str)
}
}
+ json_scan_start(&je1, js1->charset(),(const uchar *) js1->ptr(),
+ (const uchar *) js1->ptr() + js1->length());
+ str->length(0);
+ str->set_charset(js1->charset());
+ if (json_nice(&je1, str, Item_func_json_format::LOOSE))
+ goto error_return;
+
null_value= 0;
- return js1;
+ return str;
error_return:
if (je1.s.error)
@@ -1970,6 +2093,7 @@ String *Item_func_json_insert::val_str(String *str)
{
if (je.s.error)
goto js_error;
+ continue;
}
if (json_read_value(&je))
@@ -1986,7 +2110,16 @@ String *Item_func_json_insert::val_str(String *str)
int do_array_autowrap;
if (mode_insert)
- do_array_autowrap= !mode_replace || lp->n_item;
+ {
+ if (mode_replace)
+ do_array_autowrap= lp->n_item > 0;
+ else
+ {
+ if (lp->n_item == 0)
+ continue;
+ do_array_autowrap= 1;
+ }
+ }
else
{
if (lp->n_item)
@@ -2124,7 +2257,14 @@ continue_point:
}
}
- return js;
+ json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
+ (const uchar *) js->ptr() + js->length());
+ str->length(0);
+ str->set_charset(js->charset());
+ if (json_nice(&je, str, Item_func_json_format::LOOSE))
+ goto js_error;
+
+ return str;
js_error:
report_json_error(js, &je, 0);
@@ -2300,7 +2440,14 @@ v_found:
}
}
- return js;
+ json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
+ (const uchar *) js->ptr() + js->length());
+ str->length(0);
+ str->set_charset(js->charset());
+ if (json_nice(&je, str, Item_func_json_format::LOOSE))
+ goto js_error;
+
+ return str;
js_error:
report_json_error(js, &je, 0);
@@ -2540,7 +2687,7 @@ String *Item_func_json_search::val_str(String *str)
{
if (json_value_scalar(&je))
{
- if ((arg_count < 5 || path_ok(paths, arg_count - 4, &p)) &&
+ if ((arg_count < 5 || path_ok(paths, arg_count - 4, &p, je.value_type)) &&
compare_json_value_wild(&je, s_str) != 0)
{
++n_path_found;
@@ -2609,3 +2756,52 @@ String *Item_json_typecast::val_str(String *str)
return vs;
}
+
+const char *Item_func_json_format::func_name() const
+{
+ switch (fmt)
+ {
+ case COMPACT:
+ return "json_compact";
+ case LOOSE:
+ return "json_loose";
+ case DETAILED:
+ return "json_detailed";
+ default:
+ DBUG_ASSERT(0);
+ };
+
+ return "";
+}
+
+
+void Item_func_json_format::fix_length_and_dec()
+{
+ decimals= 0;
+ max_length= args[0]->max_length;
+}
+
+
+String *Item_func_json_format::val_str(String *str)
+{
+ String *js= args[0]->val_str(&tmp_js);
+ json_engine_t je;
+ if ((null_value= args[0]->null_value))
+ return 0;
+
+ json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
+ (const uchar *) js->ptr()+js->length());
+
+ str->length(0);
+ str->set_charset(js->charset());
+ if (json_nice(&je, str, fmt))
+ {
+ null_value= 1;
+ report_json_error(js, &je, 0);
+ return 0;
+ }
+
+ return str;
+}
+
+
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index 2ce94985a00..941123041d2 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -427,4 +427,30 @@ public:
};
+class Item_func_json_format: public Item_str_func
+{
+public:
+ enum formats
+ {
+ NONE,
+ COMPACT,
+ LOOSE,
+ DETAILED
+ };
+protected:
+ formats fmt;
+ String tmp_js;
+public:
+ Item_func_json_format(THD *thd, Item *js, formats format):
+ Item_str_func(thd, js), fmt(format) {}
+ Item_func_json_format(THD *thd, Item *js, Item *tabsize):
+ Item_str_func(thd, js, tabsize), fmt(DETAILED) {}
+ const char *func_name() const;
+ void fix_length_and_dec();
+ String *val_str(String *str);
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_json_format>(thd, mem_root, this); }
+};
+
+
#endif /* ITEM_JSONFUNC_INCLUDED */
diff --git a/strings/json_lib.c b/strings/json_lib.c
index 20dc1b3d718..cc3a8adf0aa 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -1001,6 +1001,7 @@ enum json_path_states {
PS_LAX, /* Parse the 'lax' keyword. */
PS_PT, /* New path's step begins. */
PS_AR, /* Parse array step. */
+ PS_SAR, /* space after the '['. */
PS_AWD, /* Array wildcard. */
PS_Z, /* '0' (as an array item number). */
PS_INT, /* Parse integer (as an array item number). */
@@ -1041,7 +1042,10 @@ static int json_path_transitions[N_PATH_STATES][N_PATH_CLASSES]=
JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
/* AR */ { JE_EOS, JE_SYN, PS_AWD, JE_SYN, PS_PT, JE_SYN, PS_Z,
- PS_INT, JE_SYN, JE_SYN, PS_AR, JE_SYN, JE_SYN, JE_SYN,
+ PS_INT, JE_SYN, JE_SYN, PS_SAR, JE_SYN, JE_SYN, JE_SYN,
+ JE_NOT_JSON_CHR, JE_BAD_CHR},
+/* SAR */ { JE_EOS, JE_SYN, PS_AWD, JE_SYN, PS_PT, JE_SYN, PS_Z,
+ PS_INT, JE_SYN, JE_SYN, PS_SAR, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
/* AWD */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, JE_SYN,
JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
@@ -1722,45 +1726,103 @@ int json_get_path_next(json_engine_t *je, json_path_t *p)
}
-int json_path_compare(const json_path_t *a, const json_path_t *b)
+int json_path_parts_compare(
+ const json_path_step_t *a, const json_path_step_t *a_end,
+ const json_path_step_t *b, const json_path_step_t *b_end,
+ enum json_value_types vt)
{
- const json_path_step_t *sa= a->steps + 1;
- const json_path_step_t *sb= b->steps + 1;
-
- if (a->last_step - sa > b->last_step - sb)
- return -2;
+ int res, res2;
- while (sa <= a->last_step)
+ while (a <= a_end)
{
- if (sb > b->last_step)
+ if (b > b_end)
+ {
+ while (vt != JSON_VALUE_ARRAY &&
+ (a->type & JSON_PATH_ARRAY_WILD) == JSON_PATH_ARRAY &&
+ a->n_item == 0)
+ {
+ if (++a > a_end)
+ return 0;
+ }
return -2;
+ }
+
+ DBUG_ASSERT((b->type & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD)) == 0);
+
- if (!((sa->type & sb->type) & JSON_PATH_KEY_OR_ARRAY))
- goto step_failed;
-
- if (sa->type & JSON_PATH_ARRAY)
+ if (a->type & JSON_PATH_ARRAY)
{
- if (!(sa->type & JSON_PATH_WILD) && sa->n_item != sb->n_item)
+ if (b->type & JSON_PATH_ARRAY)
+ {
+ if ((a->type & JSON_PATH_WILD) || a->n_item == b->n_item)
+ goto step_fits;
goto step_failed;
+ }
+ if (a->n_item == 0)
+ goto step_fits_autowrap;
+ goto step_failed;
}
else /* JSON_PATH_KEY */
{
- if (!(sa->type & JSON_PATH_WILD) &&
- (sa->key_end - sa->key != sb->key_end - sb->key ||
- memcmp(sa->key, sb->key, sa->key_end - sa->key) != 0))
+ if (!(b->type & JSON_PATH_KEY))
+ goto step_failed;
+
+ if (!(a->type & JSON_PATH_WILD) &&
+ (a->key_end - a->key != b->key_end - b->key ||
+ memcmp(a->key, b->key, a->key_end - a->key) != 0))
goto step_failed;
- }
- sb++;
- sa++;
- continue;
+ goto step_fits;
+ }
step_failed:
- if (!(sa->type & JSON_PATH_DOUBLE_WILD))
+ if (!(a->type & JSON_PATH_DOUBLE_WILD))
return -1;
- sb++;
+ b++;
+ continue;
+
+step_fits:
+ b++;
+ if (!(a->type & JSON_PATH_DOUBLE_WILD))
+ {
+ a++;
+ continue;
+ }
+
+ /* Double wild handling needs recursions. */
+ res= json_path_parts_compare(a+1, a_end, b, b_end, vt);
+ if (res == 0)
+ return 0;
+
+ res2= json_path_parts_compare(a, a_end, b, b_end, vt);
+
+ return (res2 >= 0) ? res2 : res;
+
+step_fits_autowrap:
+ if (!(a->type & JSON_PATH_DOUBLE_WILD))
+ {
+ a++;
+ continue;
+ }
+
+ /* Double wild handling needs recursions. */
+ res= json_path_parts_compare(a+1, a_end, b+1, b_end, vt);
+ if (res == 0)
+ return 0;
+
+ res2= json_path_parts_compare(a, a_end, b+1, b_end, vt);
+
+ return (res2 >= 0) ? res2 : res;
+
}
- return sb <= b->last_step;
+ return b <= b_end;
}
+int json_path_compare(const json_path_t *a, const json_path_t *b,
+ enum json_value_types vt)
+{
+ return json_path_parts_compare(a->steps+1, a->last_step,
+ b->steps+1, b->last_step, vt);
+}
+