summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRucha Deodhar <rucha.deodhar@mariadb.com>2022-03-05 01:03:49 +0530
committerRucha Deodhar <rucha.deodhar@mariadb.com>2022-04-15 01:02:44 +0530
commitc781cefd8afc0fa5840456c96f5a0c37cac2edfa (patch)
treedb5008c4f763e4d954f7f9fefa0270f6bc3effbd
parentabe971219456b1f41923c06ff715fd4efeb02850 (diff)
downloadmariadb-git-c781cefd8afc0fa5840456c96f5a0c37cac2edfa.tar.gz
MDEV-27911: Implement range notation for json path
Range can be thought about in similar manner as wildcard (*) where more than one elements are processed. To implement range notation, extended json parser to parse the 'to' keyword and added JSON_PATH_ARRAY_RANGE for path type. If there is 'to' keyword then use JSON_PATH_ARRAY range for path type along with existing type. This new integer to store the end index of range is n_item_end. When there is 'to' keyword, store the integer in n_item_end else store in n_item.
-rw-r--r--include/json_lib.h4
-rw-r--r--mysql-test/main/func_json.result189
-rw-r--r--mysql-test/main/func_json.test161
-rw-r--r--mysql-test/suite/json/r/json_no_table.result56
-rw-r--r--sql/item_jsonfunc.cc6
-rw-r--r--sql/json_table.cc3
-rw-r--r--sql/share/errmsg-utf8.txt2
-rw-r--r--strings/json_lib.c147
8 files changed, 480 insertions, 88 deletions
diff --git a/include/json_lib.h b/include/json_lib.h
index 41ab88b06ce..1f12487d7e8 100644
--- a/include/json_lib.h
+++ b/include/json_lib.h
@@ -84,7 +84,8 @@ enum json_path_step_types
JSON_PATH_KEY_DOUBLEWILD= 1+8,
JSON_PATH_ARRAY_WILD= 2+4,
JSON_PATH_ARRAY_DOUBLEWILD= 2+8,
- JSON_PATH_NEGATIVE_INDEX= 16
+ JSON_PATH_NEGATIVE_INDEX= 16,
+ JSON_PATH_ARRAY_RANGE= 32
};
@@ -95,6 +96,7 @@ typedef struct st_json_path_step_t
const uchar *key; /* Pointer to the beginning of the key. */
const uchar *key_end; /* Pointer to the end of the key. */
int n_item; /* Item number in an array. No meaning for the key step. */
+ int n_item_end; /* Last index of the range. */
} json_path_step_t;
diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result
index 18a700607ab..1707c59bf19 100644
--- a/mysql-test/main/func_json.result
+++ b/mysql-test/main/func_json.result
@@ -2029,5 +2029,194 @@ SELECT JSON_VALUE(@json,'$.x[0]');
JSON_VALUE(@json,'$.x[0]')
0
#
+# MDEV-27911: Implement range notation for json path
+#
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_EXISTS(@json, '$[3][3][-2 to last]');
+JSON_EXISTS(@json, '$[3][3][-2 to last]')
+1
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_SEARCH(@json, 'one', '12', NULL, '$[3][0 to 3]');
+JSON_SEARCH(@json, 'one', '12', NULL, '$[3][0 to 3]')
+NULL
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [12, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20]
+ ]';
+SELECT JSON_VALUE(@json, '$[0][1 to 2].key1');
+JSON_VALUE(@json, '$[0][1 to 2].key1')
+value1
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, [13, 14], {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_QUERY(@json, '$.A[-2][-3 to -1]');
+JSON_QUERY(@json, '$.A[-2][-3 to -1]')
+[13, 14]
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_EXTRACT(@json, '$[0 to 3][2]');
+JSON_EXTRACT(@json, '$[0 to 3][2]')
+[3, 6, [9, {"key2": 2}, 11], [14]]
+SELECT JSON_EXTRACT(@json, '$[3][3][last-1 to last]');
+JSON_EXTRACT(@json, '$[3][3][last-1 to last]')
+["string1", [16, {"key1": [1, 2, 3, [4, 5, 6]]}, 18]]
+SELECT JSON_EXTRACT(@json, '$[3][3][-2 to -1]');
+JSON_EXTRACT(@json, '$[3][3][-2 to -1]')
+["string1", [16, {"key1": [1, 2, 3, [4, 5, 6]]}, 18]]
+# Checking errors
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_CONTAINS_PATH(@json,'one', '$[3][0 to 3]');
+JSON_CONTAINS_PATH(@json,'one', '$[3][0 to 3]')
+1
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_CONTAINS(@json, '$[3][0 to 3]');
+JSON_CONTAINS(@json, '$[3][0 to 3]')
+NULL
+Warnings:
+Warning 4038 Syntax error in JSON text in argument 2 to function 'json_contains' at position 1
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, 13, {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_ARRAY_INSERT(@json, '$.A[0 to last-1]', 5);
+JSON_ARRAY_INSERT(@json, '$.A[0 to last-1]', 5)
+NULL
+Warnings:
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_array_insert'
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, 13, {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_ARRAY_APPEND(@json, '$.A[*]', 7);
+JSON_ARRAY_APPEND(@json, '$.A[*]', 7)
+NULL
+Warnings:
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_array_append'
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [12, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20]
+ ]';
+SELECT JSON_SET(@json, '$[0][1 to 2].key1', 1);
+JSON_SET(@json, '$[0][1 to 2].key1', 1)
+NULL
+Warnings:
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_set'
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_REPLACE(@json, '$[1][last-2 to last]', 4);
+JSON_REPLACE(@json, '$[1][last-2 to last]', 4)
+NULL
+Warnings:
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_replace'
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_REMOVE(@json, '$[1][-6 to last-2]');
+JSON_REMOVE(@json, '$[1][-6 to last-2]')
+NULL
+Warnings:
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_remove'
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, [13, 14], {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_KEYS(@json, '$.A[8][1 to 3]');
+JSON_KEYS(@json, '$.A[8][1 to 3]')
+NULL
+Warnings:
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_keys'
+#
# End of 10.9 Test
#
diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test
index 34a4b30b0ab..2a06313e5c7 100644
--- a/mysql-test/main/func_json.test
+++ b/mysql-test/main/func_json.test
@@ -1316,6 +1316,167 @@ SELECT JSON_VALUE(@json,'$.x[last-0]');
SELECT JSON_VALUE(@json,'$.x[-0]');
SELECT JSON_VALUE(@json,'$.x[0]');
+
+--echo #
+--echo # MDEV-27911: Implement range notation for json path
+--echo #
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_EXISTS(@json, '$[3][3][-2 to last]');
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_SEARCH(@json, 'one', '12', NULL, '$[3][0 to 3]');
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [12, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20]
+ ]';
+SELECT JSON_VALUE(@json, '$[0][1 to 2].key1');
+
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, [13, 14], {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_QUERY(@json, '$.A[-2][-3 to -1]');
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_EXTRACT(@json, '$[0 to 3][2]');
+SELECT JSON_EXTRACT(@json, '$[3][3][last-1 to last]');
+SELECT JSON_EXTRACT(@json, '$[3][3][-2 to -1]');
+
+--echo # Checking errors
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_CONTAINS_PATH(@json,'one', '$[3][0 to 3]');
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_CONTAINS(@json, '$[3][0 to 3]');
+
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, 13, {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_ARRAY_INSERT(@json, '$.A[0 to last-1]', 5);
+
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, 13, {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_ARRAY_APPEND(@json, '$.A[*]', 7);
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [12, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20]
+ ]';
+SELECT JSON_SET(@json, '$[0][1 to 2].key1', 1);
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_REPLACE(@json, '$[1][last-2 to last]', 4);
+
+SET @json= '[
+ [1, {"key1": "value1"}, 3],
+ [false, 5, 6],
+ [7, 8, [9, {"key2": 2}, 11]],
+ [15, 1.34, [14], ["string1", [16, {"key1":[1,2,3,[4,5,6]]}, 18]]],
+ [19, 20],
+ 21, 22
+ ]';
+SELECT JSON_REMOVE(@json, '$[1][-6 to last-2]');
+
+SET @json='{
+ "A": [0,
+ [1, 2, 3],
+ [4, 5, 6],
+ "seven",
+ 0.8,
+ true,
+ false,
+ "eleven",
+ [12, [13, 14], {"key1":"value1"},[15]],
+ true],
+ "B": {"C": 1},
+ "D": 2
+ }';
+SELECT JSON_KEYS(@json, '$.A[8][1 to 3]');
+
--echo #
--echo # End of 10.9 Test
--echo #
diff --git a/mysql-test/suite/json/r/json_no_table.result b/mysql-test/suite/json/r/json_no_table.result
index 6784fe6da32..e9af1fc68c8 100644
--- a/mysql-test/suite/json/r/json_no_table.result
+++ b/mysql-test/suite/json/r/json_no_table.result
@@ -402,7 +402,7 @@ select json_length( 'true', '$.*' );
json_length( 'true', '$.*' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_length'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_length'
# wildcards not allowed in path expressions for this function
error ER_INVALID_JSON_PATH_WILDCARD
@@ -410,7 +410,7 @@ select json_length( 'true', '$.foo**.bar' );
json_length( 'true', '$.foo**.bar' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_length'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_length'
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[0]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[0]' )
1
@@ -691,25 +691,25 @@ select json_remove( '[ 1, 2, 3 ]', '$[*]' );
json_remove( '[ 1, 2, 3 ]', '$[*]' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_remove'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_remove'
error ER_INVALID_JSON_PATH_WILDCARD
select json_remove( '[ 1, 2, 3 ]', '$**[2]' );
json_remove( '[ 1, 2, 3 ]', '$**[2]' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_remove'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_remove'
error ER_INVALID_JSON_PATH_WILDCARD
select json_remove( '[ 1, 2, 3 ]', '$[2]', '$[*]' );
json_remove( '[ 1, 2, 3 ]', '$[2]', '$[*]' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 3 to function 'json_remove'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 3 to function 'json_remove'
error ER_INVALID_JSON_PATH_WILDCARD
select json_remove( '[ 1, 2, 3 ]', '$[2]', '$**[2]' );
json_remove( '[ 1, 2, 3 ]', '$[2]', '$**[2]' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 3 to function 'json_remove'
+Warning 4044 Wildcards or range 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]
@@ -730,7 +730,7 @@ select json_remove( '[ { "a": { "a": true } } ]', '$**.a' );
json_remove( '[ { "a": { "a": true } } ]', '$**.a' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_remove'
+Warning 4044 Wildcards or range 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}]
@@ -739,7 +739,7 @@ select json_remove( '[ { "a": true }, { "b": [ { "c": { "a": true } } ] }, { "c
json_remove( '[ { "a": true }, { "b": [ { "c": { "a": true } } ] }, { "c": null }, { "a": null } ]', '$**.a' )
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_remove'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_remove'
select json_remove( '{"id": 123, "name": "systemQA", "array": [1, 2, 3]}', '$[0]' );
json_remove( '{"id": 123, "name": "systemQA", "array": [1, 2, 3]}', '$[0]' )
{"id": 123, "name": "systemQA", "array": [1, 2, 3]}
@@ -1210,7 +1210,7 @@ select json_keys('{"a": 1, "b": {"e": "foo", "b": 3}}', '$.*.b');
json_keys('{"a": 1, "b": {"e": "foo", "b": 3}}', '$.*.b')
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_keys'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_keys'
# returns [ "a", "b" ]
SELECT JSON_KEYS('{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }');
JSON_KEYS('{ "a" : "foo", "b" : [ true, { "c" : "123" } ] }')
@@ -1637,7 +1637,7 @@ select json_array_append(json_compact('{"a": {"b": [3]}}'), '$**[0]', 6);
json_array_append(json_compact('{"a": {"b": [3]}}'), '$**[0]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_array_append'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_array_append'
# Auto-wrapping, since because the paths identify scalars.
# should return {"a": "foo", "b": ["bar", 4], "c": ["wibble", "grape"]}
SELECT JSON_ARRAY_APPEND('{"a": "foo", "b": "bar", "c": "wibble"}',
@@ -1668,13 +1668,13 @@ select json_array_append( '[[], [], []]', '$[*]', 3, '$[*]', 4);
json_array_append( '[[], [], []]', '$[*]', 3, '$[*]', 4)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_array_append'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_array_append'
error ER_INVALID_JSON_PATH_WILDCARD
select json_array_append( '[[], "not array", []]', '$[*]', 3, '$[*]', 4);
json_array_append( '[[], "not array", []]', '$[*]', 3, '$[*]', 4)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_array_append'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_array_append'
SELECT JSON_ARRAY_APPEND
(
'{ "a" : "foo", "b" : "bar", "c" : "wibble" }',
@@ -1775,73 +1775,73 @@ select json_insert(json_compact('{"a": [1], "b": 2}'), '$.*[1]', 6);
json_insert(json_compact('{"a": [1], "b": 2}'), '$.*[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('{"a": 1, "b": 2}'), '$.*[1]', 6);
json_insert(json_compact('{"a": 1, "b": 2}'), '$.*[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('{"a": {"b": 3}}'), '$.a.*[1]', 6);
json_insert(json_compact('{"a": {"b": 3}}'), '$.a.*[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('{"a": {"b": [3]}}'), '$.a.*[1]', 6);
json_insert(json_compact('{"a": {"b": [3]}}'), '$.a.*[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('{"a": {"b": 3}}'), '$**[1]', 6);
json_insert(json_compact('{"a": {"b": 3}}'), '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('{"a": {"b": [3]}}'), '$**[1]', 6);
json_insert(json_compact('{"a": {"b": [3]}}'), '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('[1]'), '$[*][1]', 6);
json_insert(json_compact('[1]'), '$[*][1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('[1]'), '$**[1]', 6);
json_insert(json_compact('[1]'), '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('[1, [2], 3]'), '$[*][1]', 6);
json_insert(json_compact('[1, [2], 3]'), '$[*][1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('[1, [2], 3]'), '$**[1]', 6);
json_insert(json_compact('[1, [2], 3]'), '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('[[1]]'), '$[*][1]', 6);
json_insert(json_compact('[[1]]'), '$[*][1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert(json_compact('[[1]]'), '$**[1]', 6);
json_insert(json_compact('[[1]]'), '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
select json_insert(json_compact('{"a": 3}'), '$[1]', 6);
json_insert(json_compact('{"a": 3}'), '$[1]', 6)
[{"a": 3}, 6]
@@ -2053,19 +2053,19 @@ select json_insert('[]', '$.a.*[1]', 6);
json_insert('[]', '$.a.*[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert('[]', '$**[1]', 6);
json_insert('[]', '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_insert'
error ER_INVALID_JSON_PATH_WILDCARD
select json_insert('[]', '$[*][1]', 6);
json_insert('[]', '$[*][1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_insert'
+Warning 4044 Wildcards or range 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]
@@ -2154,7 +2154,7 @@ select json_set(json_compact('{"a": {"b": [3]}}'), '$**[1]', 6);
json_set(json_compact('{"a": {"b": [3]}}'), '$**[1]', 6)
NULL
Warnings:
-Warning 4044 Wildcards in JSON path not allowed in argument 2 to function 'json_set'
+Warning 4044 Wildcards or range in JSON path not allowed in argument 2 to function 'json_set'
SELECT JSON_SET('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a',
JSON_OBJECT());
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index e7d4e247999..d2d4fc087c9 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -374,7 +374,8 @@ static int path_setup_nwc(json_path_t *p, CHARSET_INFO *i_cs,
{
if (!json_path_setup(p, i_cs, str, end))
{
- if ((p->types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD)) == 0)
+ if ((p->types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD |
+ JSON_PATH_ARRAY_RANGE)) == 0)
return 0;
p->s.error= NO_WILDCARD_ALLOWED;
}
@@ -862,7 +863,8 @@ String *Item_func_json_extract::read_json(String *str,
}
possible_multiple_values= arg_count > 2 ||
- (paths[0].p.types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD));
+ (paths[0].p.types_used & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD |
+ JSON_PATH_ARRAY_RANGE));
*type= possible_multiple_values ? JSON_VALUE_ARRAY : JSON_VALUE_NULL;
diff --git a/sql/json_table.cc b/sql/json_table.cc
index e48646ace3c..e2f90aa2a9a 100644
--- a/sql/json_table.cc
+++ b/sql/json_table.cc
@@ -561,7 +561,8 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
more matches for it in json and report an error if so.
*/
if (jc->m_path.types_used &
- (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD) &&
+ (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD |
+ JSON_PATH_ARRAY_RANGE) &&
(json_scan_next(&je) ||
!json_find_path(&je, &jc->m_path, &cur_step,
array_counters)))
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 652b0e548ee..5a4ee62e53f 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -8420,7 +8420,7 @@ ER_JSON_PATH_DEPTH
eng "Limit of %d on JSON path depth is reached in argument %d to function '%s' at position %d"
spa "El límite de %d en profundidad de ruta JSON se ha alcanzado en argumento %d a función '%s' en la posición %d"
ER_JSON_PATH_NO_WILDCARD
- eng "Wildcards in JSON path not allowed in argument %d to function '%s'"
+ eng "Wildcards or range in JSON path not allowed in argument %d to function '%s'"
spa "Comodines en ruta JSON no permitidos en argumento %d a función '%s'"
ER_JSON_PATH_ARRAY
eng "JSON path should end with an array identifier in argument %d to function '%s'"
diff --git a/strings/json_lib.c b/strings/json_lib.c
index 602a57cc03b..70a155ec696 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -983,6 +983,7 @@ enum json_path_chr_classes {
P_USD, /* $ */
P_ASTER, /* * */
P_LSQRB, /* [ */
+ P_T, /* t (for to) */
P_RSQRB, /* ] */
P_POINT, /* . */
P_NEG, /* hyphen (for negative index in path) */
@@ -1013,12 +1014,12 @@ static enum json_path_chr_classes json_path_chr_map[128] = {
P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC,
P_ETC, P_ETC, P_ETC, P_ETC, P_L, P_ETC, P_ETC, P_ETC,
- P_ETC, P_ETC, P_S, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC,
+ P_ETC, P_ETC, P_S, P_ETC, P_T, P_ETC, P_ETC, P_ETC,
P_ETC, P_ETC, P_ETC, P_LSQRB, P_BKSL, P_RSQRB, P_ETC, P_ETC,
P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC,
P_ETC, P_ETC, P_ETC, P_ETC, P_L, P_ETC, P_ETC, P_ETC,
- P_ETC, P_ETC, P_S, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC,
+ P_ETC, P_ETC, P_S, P_ETC, P_T, P_ETC, P_ETC, P_ETC,
P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC, P_ETC
};
@@ -1042,6 +1043,7 @@ enum json_path_states {
PS_KEYX, /* Key started with quote ("). */
PS_KNMX, /* Parse quoted key name. */
PS_LAST, /* Parse 'last' keyword */
+ PS_T, /* Parse 'to' keyword. */
N_PATH_STATES, /* Below are states that aren't in the transitions table. */
PS_SCT, /* Parse the 'strict' keyword. */
PS_EKY, /* '.' after the keyname so next step is the key. */
@@ -1057,71 +1059,75 @@ enum json_path_states {
static int json_path_transitions[N_PATH_STATES][N_PATH_CLASSES]=
{
/*
- EOS $, * [ ] . - 0
- 1..9 L S SPACE \ " ETC
+ EOS $, * [ to ] . -
+ 0 1..9 L S SPACE \ " ETC
ERR BAD
*/
-/* GO */ { JE_EOS, PS_PT, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
- JE_SYN, PS_LAX, PS_SCT, PS_GO, JE_SYN, JE_SYN, JE_SYN,
+/* GO */ { JE_EOS, PS_PT, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+ JE_SYN, JE_SYN, PS_LAX, PS_SCT, PS_GO, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
/* LAX */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
- JE_SYN, PS_LAX, JE_SYN, PS_GO, JE_SYN, JE_SYN, JE_SYN,
+ JE_SYN, JE_SYN, PS_LAX, JE_SYN, PS_GO, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* PT */ { PS_OK, JE_SYN, PS_AST, PS_AR, JE_SYN, PS_KEY, JE_SYN, JE_SYN, JE_SYN,
- JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+/* PT */ { PS_OK, JE_SYN, PS_AST, PS_AR, JE_SYN, JE_SYN, PS_KEY, JE_SYN,
+ JE_SYN, JE_SYN, 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, JE_SYN, JE_SYN, PS_NEG,PS_Z,
- PS_INT, PS_LAST, JE_SYN, PS_SAR, JE_SYN, JE_SYN, JE_SYN,
+/* AR */ { JE_EOS, JE_SYN, PS_AWD, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_NEG,
+ PS_Z, PS_INT, PS_LAST, 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,JE_SYN, PS_Z,
- PS_INT, PS_LAST, JE_SYN, PS_SAR, JE_SYN, JE_SYN, JE_SYN,
+/* SAR */ { JE_EOS, JE_SYN, PS_AWD, JE_SYN, JE_SYN, PS_PT, JE_SYN, JE_SYN,
+ PS_Z, PS_INT, PS_LAST, 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, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
+/* AWD */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, JE_SYN,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* NEG */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_INT,
- PS_INT, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+/* NEG */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+ PS_INT, PS_INT, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* Z */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN,JE_SYN, JE_SYN,
- JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
+/* Z */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, JE_SYN,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* INT */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN,JE_SYN, PS_INT,
- PS_INT, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
+/* INT */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, JE_SYN,
+ PS_INT, PS_INT, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* AS */ { 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,
+/* AS */ { JE_EOS, JE_SYN, JE_SYN, JE_SYN, PS_T, PS_PT, JE_SYN, PS_NEG,
+ JE_SYN, PS_INT, PS_LAST, PS_AS, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* KEY */ { JE_EOS, PS_KNM, PS_KWD, JE_SYN, PS_KNM, JE_SYN,JE_SYN, PS_KNM,
- PS_KNM, PS_KNM, PS_KNM, PS_KNM, JE_SYN, PS_KEYX, PS_KNM,
+/* KEY */ { JE_EOS, PS_KNM, PS_KWD, JE_SYN, PS_KNM, PS_KNM, JE_SYN, JE_SYN,
+ PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_KNM, JE_SYN, PS_KEYX, PS_KNM,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* KNM */ { PS_KOK, PS_KNM, PS_AST, PS_EAR, PS_KNM, PS_EKY, JE_SYN,PS_KNM,
- PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_ESC, PS_KNM, PS_KNM,
+/* KNM */ { PS_KOK, PS_KNM, PS_AST, PS_EAR, PS_KNM, PS_KNM, PS_EKY, JE_SYN,
+ PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_KNM, PS_ESC, PS_KNM, PS_KNM,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* KWD */ { PS_OK, JE_SYN, JE_SYN, PS_AR, JE_SYN, PS_EKY, JE_SYN,JE_SYN,
- JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+/* KWD */ { PS_OK, JE_SYN, JE_SYN, PS_AR, JE_SYN, JE_SYN, PS_EKY, JE_SYN,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* AST */ { JE_SYN, JE_SYN, PS_DWD, JE_SYN, JE_SYN, JE_SYN, JE_SYN,JE_SYN,
- JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+/* AST */ { JE_SYN, JE_SYN, PS_DWD, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* DWD */ { JE_SYN, JE_SYN, PS_AST, PS_AR, JE_SYN, PS_KEY,JE_SYN, JE_SYN, JE_SYN,
- JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
+/* DWD */ { JE_SYN, JE_SYN, PS_AST, PS_AR, JE_SYN, JE_SYN, PS_KEY, JE_SYN,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* KEYX*/ { JE_EOS, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, JE_SYN,PS_KNMX,
- PS_KNMX,PS_KNMX, PS_KNMX, PS_KNMX, PS_ESCX, PS_EKYX, PS_KNMX,
+/* KEYX*/ { JE_EOS, PS_KNMX, PS_KNMX, PS_KNMX, JE_SYN, PS_KNMX, PS_KNMX, JE_SYN,
+ PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_ESCX, PS_EKYX, PS_KNMX,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* KNMX */{ JE_EOS, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, JE_SYN,PS_KNMX,
- PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX,PS_ESCX, PS_EKYX, PS_KNMX,
+/* KNMX */{ JE_EOS, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, JE_SYN,
+ PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_KNMX, PS_ESCX, PS_EKYX, PS_KNMX,
JE_NOT_JSON_CHR, JE_BAD_CHR},
-/* LAST */{ JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, PS_NEG, JE_SYN,
- JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
- JE_SYN, JE_BAD_CHR}
+/* LAST */{ JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, PS_NEG,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
+ JE_SYN, JE_BAD_CHR},
+/* T */ { JE_SYN, JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_PT, JE_SYN, PS_NEG,
+ JE_SYN, JE_SYN, JE_SYN, JE_SYN, PS_AS, JE_SYN, JE_SYN, JE_SYN,
+ JE_SYN, JE_BAD_CHR},
};
int json_path_setup(json_path_t *p,
CHARSET_INFO *i_cs, const uchar *str, const uchar *end)
{
- int c_len, t_next, state= PS_GO, is_negative_index= 0, is_last= 0, prev_value=0;
+ int c_len, t_next, state= PS_GO, is_negative_index= 0, is_last= 0,
+ prev_value=0, is_to= 0, *cur_val;
enum json_path_step_types double_wildcard= JSON_PATH_KEY_NULL;
json_string_setup(&p->s, i_cs, str, end);
@@ -1161,19 +1167,21 @@ int json_path_setup(json_path_t *p,
p->types_used|= JSON_PATH_WILD;
continue;
case PS_INT:
+ cur_val= is_to ? &(p->last_step->n_item_end) :
+ &(p->last_step->n_item);
if (is_last)
{
prev_value*= 10;
prev_value-= p->s.c_next - '0';
- p->last_step->n_item= -1 + prev_value;
+ *cur_val= -1 + prev_value;
}
else
{
- p->last_step->n_item*= 10;
+ (*cur_val)*= 10;
if (is_negative_index)
- p->last_step->n_item-= p->s.c_next - '0';
+ *cur_val-= p->s.c_next - '0';
else
- p->last_step->n_item+= p->s.c_next - '0';
+ *cur_val+= p->s.c_next - '0';
}
continue;
case PS_EKYX:
@@ -1186,7 +1194,10 @@ int json_path_setup(json_path_t *p,
/* fall through */
case PS_KEY:
p->last_step++;
+ is_to= 0;
+ prev_value= 0;
is_negative_index= 0;
+ is_last= 0;
if (p->last_step - p->steps >= JSON_DEPTH_LIMIT)
return p->s.error= JE_DEPTH;
p->types_used|= p->last_step->type= JSON_PATH_KEY | double_wildcard;
@@ -1202,13 +1213,14 @@ int json_path_setup(json_path_t *p,
case PS_AR:
p->last_step++;
is_last= 0;
+ is_to= 0;
+ prev_value= 0;
+ is_negative_index= 0;
if (p->last_step - p->steps >= JSON_DEPTH_LIMIT)
return p->s.error= JE_DEPTH;
p->types_used|= p->last_step->type= JSON_PATH_ARRAY | double_wildcard;
double_wildcard= JSON_PATH_KEY_NULL;
p->last_step->n_item= 0;
- prev_value= 0;
- is_negative_index= 0;
continue;
case PS_ESC:
if (json_handle_esc(&p->s))
@@ -1230,15 +1242,27 @@ int json_path_setup(json_path_t *p,
case PS_NEG:
p->types_used|= JSON_PATH_NEGATIVE_INDEX;
is_negative_index= 1;
- if (is_last)
- p->last_step->n_item= 0;
continue;
case PS_LAST:
if ((p->s.error= skip_string_verbatim(&p->s, "ast")))
return 1;
p->types_used|= JSON_PATH_NEGATIVE_INDEX;
is_last= 1;
- p->last_step->n_item= -1;
+ if (is_to)
+ p->last_step->n_item_end= -1;
+ else
+ p->last_step->n_item= -1;
+ continue;
+ case PS_T:
+ if ((p->s.error= skip_string_verbatim(&p->s, "o")))
+ return 1;
+ is_to= 1;
+ is_negative_index= 0;
+ is_last= 0;
+ prev_value= 0;
+ p->last_step->n_item_end= 0;
+ p->last_step->type|= JSON_PATH_ARRAY_RANGE;
+ p->types_used|= JSON_PATH_ARRAY_RANGE;
continue;
};
} while (state != PS_OK);
@@ -1420,7 +1444,7 @@ int json_find_path(json_engine_t *je,
break;
case JST_VALUE:
DBUG_ASSERT(cur_step->type & JSON_PATH_ARRAY);
- if (cur_step->type & JSON_PATH_WILD ||
+ if (cur_step->type & (JSON_PATH_WILD | JSON_PATH_ARRAY_RANGE) ||
cur_step->n_item == array_counters[cur_step - p->steps]++)
{
/* Array item matches. */
@@ -1855,14 +1879,27 @@ int json_path_parts_compare(
DBUG_ASSERT((b->type & (JSON_PATH_WILD | JSON_PATH_DOUBLE_WILD)) == 0);
-
if (a->type & JSON_PATH_ARRAY)
{
if (b->type & JSON_PATH_ARRAY)
{
- if ((a->type & JSON_PATH_WILD) ||
- (a->n_item >= 0 ? a->n_item == b->n_item :
- a->n_item == b->n_item - array_sizes[b-temp_b]))
+ int res= 0, corrected_n_item_a= 0, corrected_n_item_end_a= 0;
+ if (array_sizes)
+ {
+ corrected_n_item_a= a->n_item < 0 ? array_sizes[b-temp_b] +
+ a->n_item :
+ a->n_item;
+ corrected_n_item_end_a= a->n_item_end < 0 ? array_sizes[b-temp_b] +
+ a->n_item_end :
+ a->n_item_end;
+ }
+ if (a->type & JSON_PATH_ARRAY_RANGE)
+ res= b->n_item >= corrected_n_item_a &&
+ b->n_item <= corrected_n_item_end_a;
+ else
+ res= corrected_n_item_a == b->n_item;
+
+ if ((a->type & JSON_PATH_WILD) || res)
goto step_fits;
goto step_failed;
}