diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index b7710aaaa89..2991eb4e6fb 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -1690,6 +1690,12 @@ select json_arrayagg('ä'), json_objectagg(1, 'ä'); json_arrayagg('ä') json_objectagg(1, 'ä') ["ä"] {"1":"ä"} # +# MDEV-32287: JSON_EXTRACT not returning multiple values for same path +# +select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]'); +JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]') +[40, 40] +# # MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json # CREATE TABLE t (id CHAR AS (JSON_COMPACT (JSON_EXTRACT(doc,"$._id"))) UNIQUE KEY,doc JSON,CONSTRAINT notnu CHECK (id IS NOT NULL)); diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 35b9d9bffb9..5787ee88960 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -1115,6 +1115,14 @@ set names latin1; select json_arrayagg('ä'), json_objectagg(1, 'ä'); --enable_service_connection + +--echo # +--echo # MDEV-32287: JSON_EXTRACT not returning multiple values for same path +--echo # + +select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]'); + + --echo # --echo # MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json --echo # diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 95f8bfde7ce..5622bf3e803 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -893,15 +893,16 @@ bool Item_func_json_extract::fix_length_and_dec() } -static bool path_exact(const json_path_with_flags *paths_list, int n_paths, +static int path_exact(const json_path_with_flags *paths_list, int n_paths, const json_path_t *p, json_value_types vt) { + int count_path= 0; for (; n_paths > 0; n_paths--, paths_list++) { if (json_path_compare(&paths_list->p, p, vt) == 0) - return TRUE; + count_path++; } - return FALSE; + return count_path; } @@ -925,7 +926,7 @@ String *Item_func_json_extract::read_json(String *str, json_engine_t je, sav_je; json_path_t p; const uchar *value; - int not_first_value= 0; + int not_first_value= 0, count_path= 0; uint n_arg; size_t v_len; int possible_multiple_values; @@ -972,7 +973,7 @@ String *Item_func_json_extract::read_json(String *str, while (json_get_path_next(&je, &p) == 0) { - if (!path_exact(paths, arg_count-1, &p, je.value_type)) + if (!(count_path= path_exact(paths, arg_count-1, &p, je.value_type))) continue; value= je.value_begin; @@ -1002,9 +1003,12 @@ String *Item_func_json_extract::read_json(String *str, je= sav_je; } - if ((not_first_value && str->append(", ", 2)) || - str->append((const char *) value, v_len)) - goto error; /* Out of memory. */ + for (int count= 0; count < count_path; count++) + { + if (str->append((const char *) value, v_len) || + str->append(", ", 2)) + goto error; /* Out of memory. */ + } not_first_value= 1; @@ -1025,6 +1029,11 @@ String *Item_func_json_extract::read_json(String *str, goto return_null; } + if (str->length()>2) + { + str->chop(); + str->chop(); + } if (possible_multiple_values && str->append("]", 1)) goto error; /* Out of memory. */