From 1da0865058cca5e92e39f5c876c220ebca1ffa66 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Mon, 5 Dec 2016 09:34:28 +0400 Subject: [PATCH] MDEV-11467 JSON_EXTRACT returns incorrect results. Item_func_json_extract::val_str fixed. --- mysql-test/r/func_json.result | 6 +++ mysql-test/t/func_json.test | 2 + sql/item_jsonfunc.cc | 76 +++++++++++++++++------------------ 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result index e69e1f138c3..36430973fe7 100644 --- a/mysql-test/r/func_json.result +++ b/mysql-test/r/func_json.result @@ -132,6 +132,12 @@ json_extract('{"key0":true, "key1":"qwe"}', "$.key1") select json_extract(json_object('foo', 'foobar'),'$'); json_extract(json_object('foo', 'foobar'),'$') {"foo": "foobar"} +select json_extract('[10, 20, [30, 40]]', '$[2][*]'); +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] 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]} diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test index 2a3d1cc81d2..62853de6ad2 100644 --- a/mysql-test/t/func_json.test +++ b/mysql-test/t/func_json.test @@ -52,6 +52,8 @@ select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2"); select json_extract('{"key1":5, "key2":[2,3]}', "$.key1", "$.key2"); select json_extract('{"key0":true, "key1":"qwe"}', "$.key1"); select json_extract(json_object('foo', 'foobar'),'$'); +select json_extract('[10, 20, [30, 40]]', '$[2][*]'); +select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'); select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3); diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 5361f0143d3..cb1c174d08d 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -461,52 +461,52 @@ String *Item_func_json_extract::val_str(String *str) c_path->cur_step= c_path->p.steps; - if (json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters)) + while (!json_find_path(&je, &c_path->p, &c_path->cur_step, array_counters)) { - /* Path wasn't found. */ - if (je.s.error) + if (json_read_value(&je)) goto error; - continue; - } - - if (json_read_value(&je)) - goto error; - - value= je.value_begin; - if (json_value_scalar(&je)) - v_len= je.value_end - value; - else - { - if (json_skip_level(&je)) - goto error; - v_len= je.s.c_str - value; - } - - if (!multiple_values_found) - { - if (first_value == NULL) - { - /* - Just remember the first value as we don't know yet - if we need to create an array out of it or not. - */ - first_value= (const char *) value; - first_len= v_len; - continue; - } + value= je.value_begin; + if (json_value_scalar(&je)) + v_len= je.value_end - value; else { - multiple_values_found= TRUE; /* We have to make an JSON array. */ - if (str->append("[", 1) || - str->append(first_value, first_len)) - goto error; /* Out of memory. */ + if (json_skip_level(&je)) + goto error; + v_len= je.s.c_str - value; } + if (json_scan_next(&je) && je.s.error) + goto error; + + if (!multiple_values_found) + { + if (first_value == NULL) + { + /* + Just remember the first value as we don't know yet + if we need to create an array out of it or not. + */ + first_value= (const char *) value; + first_len= v_len; + continue; + } + else + { + multiple_values_found= TRUE; /* We have to make an JSON array. */ + if (str->append("[", 1) || + str->append(first_value, first_len)) + goto error; /* Out of memory. */ + } + + } + if (str->append(", ", 2) || + str->append((const char *) value, v_len)) + goto error; /* Out of memory. */ } - if (str->append(", ", 2) || - str->append((const char *) value, v_len)) - goto error; /* Out of memory. */ + + if (je.s.error) + goto error; } if (first_value == NULL)