From b915b96f7224e04d4509f1e4c6a4193347715097 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Thu, 29 Dec 2022 21:53:12 +0530 Subject: [PATCH] MDEV-30304: Json Range only affects first row of the result set Analysis: Parsing json path happens only once. When paring, we set types of path (types_used) to use later. If the path type has range or wild card, only then multiple values get added to the result set. However for each row in the table, types_used still gets overwritten to default (no multiple values) and is also not set again (because path is already parsed). Since multiple values depend on the type of path, they dont get added to result set either. Fix: set default for types_used only if path is not parsed already. --- mysql-test/main/func_json.result | 18 ++++++++++++++++++ mysql-test/main/func_json.test | 15 +++++++++++++++ sql/item_jsonfunc.cc | 2 +- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 7ce5d70f9fc..3cb78ee5dc9 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -2506,6 +2506,24 @@ SELECT JSON_OVERLAPS(@json1, @json2); JSON_OVERLAPS(@json1, @json2) 0 # +# MDEV-30304: Json Range only affects first row of the result set +# +CREATE TABLE t1 ( j JSON ); +INSERT INTO t1 (j) VALUES ('[{"key1": 1, "key2": 1}, {"key3": 1, "key4": 1}]'); +INSERT INTO t1 (j) VALUES ('[{"key1": 2, "key2": 2}, {"key3": 2, "key4": 2}, {"key5": 2, "key6": 2}]'); +INSERT INTO t1 (j) VALUES ('[{"key1": 3, "key2": 3}, {"key3": 3, "key4": 3}, {"key5": 3}]'); +SELECT JSON_EXTRACT(j, '$[0 to 1]') FROM t1 ; +JSON_EXTRACT(j, '$[0 to 1]') +[{"key1": 1, "key2": 1}, {"key3": 1, "key4": 1}] +[{"key1": 2, "key2": 2}, {"key3": 2, "key4": 2}] +[{"key1": 3, "key2": 3}, {"key3": 3, "key4": 3}] +SELECT JSON_EXTRACT(j, '$[*]') FROM t1 ; +JSON_EXTRACT(j, '$[*]') +[{"key1": 1, "key2": 1}, {"key3": 1, "key4": 1}] +[{"key1": 2, "key2": 2}, {"key3": 2, "key4": 2}, {"key5": 2, "key6": 2}] +[{"key1": 3, "key2": 3}, {"key3": 3, "key4": 3}, {"key5": 3}] +DROP TABLE t1; +# # End of 10.9 Test # # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index da830ed08fd..e0614a252ce 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -1706,6 +1706,21 @@ SET @json2 = '{"kk":{"k1":"v1","k2":"v2","k3":"v3"}}'; SELECT JSON_OVERLAPS(@json2, @json1); SELECT JSON_OVERLAPS(@json1, @json2); +--echo # +--echo # MDEV-30304: Json Range only affects first row of the result set +--echo # + +CREATE TABLE t1 ( j JSON ); + +INSERT INTO t1 (j) VALUES ('[{"key1": 1, "key2": 1}, {"key3": 1, "key4": 1}]'); +INSERT INTO t1 (j) VALUES ('[{"key1": 2, "key2": 2}, {"key3": 2, "key4": 2}, {"key5": 2, "key6": 2}]'); +INSERT INTO t1 (j) VALUES ('[{"key1": 3, "key2": 3}, {"key3": 3, "key4": 3}, {"key5": 3}]'); + +SELECT JSON_EXTRACT(j, '$[0 to 1]') FROM t1 ; +SELECT JSON_EXTRACT(j, '$[*]') FROM t1 ; + +DROP TABLE t1; + --echo # --echo # End of 10.9 Test --echo # diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 2efb8e39439..4d798b6ef72 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -1019,9 +1019,9 @@ String *Item_func_json_extract::read_json(String *str, for (n_arg=1; n_arg < arg_count; n_arg++) { json_path_with_flags *c_path= paths + n_arg - 1; - c_path->p.types_used= JSON_PATH_KEY_NULL; if (!c_path->parsed) { + c_path->p.types_used= JSON_PATH_KEY_NULL; String *s_p= args[n_arg]->val_str(tmp_paths + (n_arg-1)); if (s_p) {