summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2018-09-11 14:37:45 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2018-09-11 14:37:45 +0400
commitc8bb43a9385cdb7a27f0702742a8d1e08a85befd (patch)
treef4375293244135af1f4fd9cfcdbf30f1961749fb
parent4d9ec7cb6c83c571115bde59d72f02b494764755 (diff)
downloadmariadb-git-c8bb43a9385cdb7a27f0702742a8d1e08a85befd.tar.gz
MDEV-17121 JSON_ARRAY_APPEND.
Extra comma added to the result when an json array is empty.
-rw-r--r--include/json_lib.h6
-rw-r--r--mysql-test/r/func_json.result6
-rw-r--r--mysql-test/t/func_json.test7
-rw-r--r--sql/item_jsonfunc.cc6
-rw-r--r--strings/json_lib.c25
5 files changed, 48 insertions, 2 deletions
diff --git a/include/json_lib.h b/include/json_lib.h
index 567b04dbdc0..e9c10906502 100644
--- a/include/json_lib.h
+++ b/include/json_lib.h
@@ -319,6 +319,12 @@ int json_skip_to_level(json_engine_t *j, int level);
json_skip_to_level((json_engine), (json_engine)->stack_p)
+/*
+ works as json_skip_level() but also counts items on the current
+ level skipped.
+*/
+int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped);
+
#define json_skip_array_item json_skip_key
/*
diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result
index e8b2fac4fb8..9c7a10625e3 100644
--- a/mysql-test/r/func_json.result
+++ b/mysql-test/r/func_json.result
@@ -790,3 +790,9 @@ JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6)
SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6');
JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6')
{"a": "ö", "x": 1, "b": "ö"}
+#
+# MDEV-17121 JSON_ARRAY_APPEND
+#
+select json_array_append('[ ]', '$', 'aue');
+json_array_append('[ ]', '$', 'aue')
+["aue"]
diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test
index fd5e3d7d7ee..e27128a3f4a 100644
--- a/mysql-test/t/func_json.test
+++ b/mysql-test/t/func_json.test
@@ -448,3 +448,10 @@ SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6);
SELECT JSON_SET('{}', '$.a', _utf8 0xC3B6, '$.b', _utf8 0xC3B6);
SELECT JSON_SET('{}', '$.a', _utf8 X'C3B6', '$.x', 1, '$.b', _utf8 X'C3B6');
+
+--echo #
+--echo # MDEV-17121 JSON_ARRAY_APPEND
+--echo #
+
+select json_array_append('[ ]', '$', 'aue');
+
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 4a837646451..1da53935441 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -1621,13 +1621,15 @@ String *Item_func_json_array_append::val_str(String *str)
if (je.value_type == JSON_VALUE_ARRAY)
{
- if (json_skip_level(&je))
+ int n_items;
+ if (json_skip_level_and_count(&je, &n_items))
goto js_error;
ar_end= je.s.c_str - je.sav_c_len;
str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr());
str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr());
- str->append(", ", 2);
+ if (n_items)
+ str->append(", ", 2);
if (append_json_value(str, args[n_arg+1], &tmp_val))
goto return_null; /* Out of memory. */
diff --git a/strings/json_lib.c b/strings/json_lib.c
index f6b4f15732d..1c0ff4b5345 100644
--- a/strings/json_lib.c
+++ b/strings/json_lib.c
@@ -1197,6 +1197,31 @@ int json_skip_to_level(json_engine_t *j, int level)
}
+#define json_skip_level(json_engine) \
+ json_skip_to_level((json_engine), (json_engine)->stack_p)
+
+
+/*
+ works as json_skip_level() but also counts items on the current
+ level skipped.
+*/
+int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped)
+{
+ int level= j->stack_p;
+
+ *n_items_skipped= 0;
+ while (json_scan_next(j) == 0)
+ {
+ if (j->stack_p < level)
+ return 0;
+ if (j->stack_p == level && j->state == JST_VALUE)
+ (*n_items_skipped)++;
+ }
+
+ return 1;
+}
+
+
int json_skip_key(json_engine_t *j)
{
if (json_read_value(j))