Skip to content

Commit 5ca64e6

Browse files
MDEV-32287: JSON_EXTRACT not returning multiple values for same path
Analysis: When scanning json and getting the exact path at each step, if a path is reached, we end up adding the item in the result and immediately get the next item which results in current path changing. Fix: Instead of immediately returning the item, count the occurences of the path in argument and append in the result as needed.
1 parent d7df63e commit 5ca64e6

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

mysql-test/main/func_json.result

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,12 @@ select json_arrayagg('ä'), json_objectagg(1, 'ä');
16901690
json_arrayagg('ä') json_objectagg(1, 'ä')
16911691
["ä"] {"1":"ä"}
16921692
#
1693+
# MDEV-32287: JSON_EXTRACT not returning multiple values for same path
1694+
#
1695+
select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]');
1696+
JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]')
1697+
[40, 40]
1698+
#
16931699
# MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json
16941700
#
16951701
CREATE TABLE t (id CHAR AS (JSON_COMPACT (JSON_EXTRACT(doc,"$._id"))) UNIQUE KEY,doc JSON,CONSTRAINT notnu CHECK (id IS NOT NULL));

mysql-test/main/func_json.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,14 @@ set names latin1;
11151115
select json_arrayagg('ä'), json_objectagg(1, 'ä');
11161116
--enable_service_connection
11171117

1118+
1119+
--echo #
1120+
--echo # MDEV-32287: JSON_EXTRACT not returning multiple values for same path
1121+
--echo #
1122+
1123+
select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]');
1124+
1125+
11181126
--echo #
11191127
--echo # MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json
11201128
--echo #

sql/item_jsonfunc.cc

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -893,15 +893,16 @@ bool Item_func_json_extract::fix_length_and_dec()
893893
}
894894

895895

896-
static bool path_exact(const json_path_with_flags *paths_list, int n_paths,
896+
static int path_exact(const json_path_with_flags *paths_list, int n_paths,
897897
const json_path_t *p, json_value_types vt)
898898
{
899+
int count_path= 0;
899900
for (; n_paths > 0; n_paths--, paths_list++)
900901
{
901902
if (json_path_compare(&paths_list->p, p, vt) == 0)
902-
return TRUE;
903+
count_path++;
903904
}
904-
return FALSE;
905+
return count_path;
905906
}
906907

907908

@@ -925,7 +926,7 @@ String *Item_func_json_extract::read_json(String *str,
925926
json_engine_t je, sav_je;
926927
json_path_t p;
927928
const uchar *value;
928-
int not_first_value= 0;
929+
int not_first_value= 0, count_path= 0;
929930
uint n_arg;
930931
size_t v_len;
931932
int possible_multiple_values;
@@ -972,7 +973,7 @@ String *Item_func_json_extract::read_json(String *str,
972973

973974
while (json_get_path_next(&je, &p) == 0)
974975
{
975-
if (!path_exact(paths, arg_count-1, &p, je.value_type))
976+
if (!(count_path= path_exact(paths, arg_count-1, &p, je.value_type)))
976977
continue;
977978

978979
value= je.value_begin;
@@ -1002,9 +1003,12 @@ String *Item_func_json_extract::read_json(String *str,
10021003
je= sav_je;
10031004
}
10041005

1005-
if ((not_first_value && str->append(", ", 2)) ||
1006-
str->append((const char *) value, v_len))
1007-
goto error; /* Out of memory. */
1006+
for (int count= 0; count < count_path; count++)
1007+
{
1008+
if (str->append((const char *) value, v_len) ||
1009+
str->append(", ", 2))
1010+
goto error; /* Out of memory. */
1011+
}
10081012

10091013
not_first_value= 1;
10101014

@@ -1025,6 +1029,11 @@ String *Item_func_json_extract::read_json(String *str,
10251029
goto return_null;
10261030
}
10271031

1032+
if (str->length()>2)
1033+
{
1034+
str->chop();
1035+
str->chop();
1036+
}
10281037
if (possible_multiple_values && str->append("]", 1))
10291038
goto error; /* Out of memory. */
10301039

0 commit comments

Comments
 (0)