Skip to content

Commit fe6d0a0

Browse files
author
Alexey Botchkov
committed
MDEV-11471 JSON_ARRAY_APPEND returns incorrect results.
Item_func_json_array_append::val_str fixed.
1 parent abb80d2 commit fe6d0a0

File tree

3 files changed

+93
-28
lines changed

3 files changed

+93
-28
lines changed

mysql-test/r/func_json.result

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ json_array_append('["a", "b"]', '$', FALSE)
5555
select json_array_append('{"k1":1, "k2":["a", "b"]}', '$.k2', 2);
5656
json_array_append('{"k1":1, "k2":["a", "b"]}', '$.k2', 2)
5757
{"k1":1, "k2":["a", "b", 2]}
58+
select json_array_append('["a", ["b", "c"], "d"]', '$[0]', 2);
59+
json_array_append('["a", ["b", "c"], "d"]', '$[0]', 2)
60+
[["a", 2], ["b", "c"], "d"]
5861
select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1]', 'x');
5962
json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1]', 'x')
6063
["a", "x", {"b": [1, 2]}, [3, 4]]

mysql-test/t/func_json.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ select json_array(1, "text", false, null);
2121

2222
select json_array_append('["a", "b"]', '$', FALSE);
2323
select json_array_append('{"k1":1, "k2":["a", "b"]}', '$.k2', 2);
24+
select json_array_append('["a", ["b", "c"], "d"]', '$[0]', 2);
2425

2526
select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[1]', 'x');
2627
select json_array_insert('["a", {"b": [1, 2]}, [3, 4]]', '$[2]', 'x');

sql/item_jsonfunc.cc

Lines changed: 89 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -994,32 +994,69 @@ String *Item_func_json_array_append::val_str(String *str)
994994
if (json_read_value(&je))
995995
goto error;
996996

997-
if (je.value_type != JSON_VALUE_ARRAY)
998-
{
999-
/* Must be an array. */
1000-
goto error;
1001-
}
1002-
1003-
if (json_skip_level(&je))
1004-
goto error;
1005-
1006997
str->length(0);
1007998
str->set_charset(js->charset());
1008999
if (str->reserve(js->length() + 8, 1024))
10091000
goto error; /* Out of memory. */
1010-
ar_end= je.s.c_str - je.sav_c_len;
1011-
str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr());
1012-
str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr());
1013-
str->append(", ", 2);
1014-
if (append_json_value(str, args[n_arg+1], &tmp_val))
1015-
goto error; /* Out of memory. */
10161001

1017-
if (str->reserve(str_rest_len, 1024))
1018-
goto error; /* Out of memory. */
1019-
str->q_append((const char *) ar_end, str_rest_len);
1002+
if (je.value_type == JSON_VALUE_ARRAY)
1003+
{
1004+
if (json_skip_level(&je))
1005+
goto error;
1006+
1007+
ar_end= je.s.c_str - je.sav_c_len;
1008+
str_rest_len= js->length() - (ar_end - (const uchar *) js->ptr());
1009+
str->q_append(js->ptr(), ar_end-(const uchar *) js->ptr());
1010+
str->append(", ", 2);
1011+
if (append_json_value(str, args[n_arg+1], &tmp_val))
1012+
goto error; /* Out of memory. */
1013+
1014+
if (str->reserve(str_rest_len, 1024))
1015+
goto error; /* Out of memory. */
1016+
str->q_append((const char *) ar_end, str_rest_len);
1017+
}
1018+
else
1019+
{
1020+
const uchar *c_from, *c_to;
1021+
1022+
/* Wrap as an array. */
1023+
str->q_append(js->ptr(), (const char *) je.value_begin - js->ptr());
1024+
c_from= je.value_begin;
1025+
1026+
if (je.value_type == JSON_VALUE_OBJECT)
1027+
{
1028+
if (json_skip_level(&je))
1029+
goto error;
1030+
c_to= je.s.c_str;
1031+
}
1032+
else
1033+
c_to= je.value_end;
1034+
1035+
if (str->append("[", 1) ||
1036+
str->append((const char *) c_from, c_to - c_from) ||
1037+
str->append(", ", 2) ||
1038+
append_json_value(str, args[n_arg+1], &tmp_val) ||
1039+
str->append("]", 1) ||
1040+
str->append((const char *) je.s.c_str,
1041+
js->end() - (const char *) je.s.c_str))
1042+
goto error;
1043+
}
1044+
{
1045+
/* Swap str and js. */
1046+
if (str == &tmp_js)
1047+
{
1048+
str= js;
1049+
js= &tmp_js;
1050+
}
1051+
else
1052+
{
1053+
js= str;
1054+
str= &tmp_js;
1055+
}
1056+
}
10201057
}
10211058

1022-
return str;
1059+
return js;
10231060

10241061
error:
10251062
null_value= 1;
@@ -1123,9 +1160,17 @@ String *Item_func_json_array_insert::val_str(String *str)
11231160
goto error; /* Out of memory. */
11241161

11251162
{
1126-
String *tmp_str= str;
1127-
str= &tmp_js;
1128-
js= tmp_str;
1163+
/* Swap str and js. */
1164+
if (str == &tmp_js)
1165+
{
1166+
str= js;
1167+
js= &tmp_js;
1168+
}
1169+
else
1170+
{
1171+
js= str;
1172+
str= &tmp_js;
1173+
}
11291174
}
11301175
}
11311176

@@ -1539,9 +1584,17 @@ String *Item_func_json_insert::val_str(String *str)
15391584
goto error; /* Out of memory. */
15401585
continue_point:
15411586
{
1542-
String *tmp= str;
1543-
str= &tmp_js;
1544-
js= tmp;
1587+
/* Swap str and js. */
1588+
if (str == &tmp_js)
1589+
{
1590+
str= js;
1591+
js= &tmp_js;
1592+
}
1593+
else
1594+
{
1595+
js= str;
1596+
str= &tmp_js;
1597+
}
15451598
}
15461599
}
15471600

@@ -1701,9 +1754,17 @@ String *Item_func_json_remove::val_str(String *str)
17011754
goto error; /* Out of memory. */
17021755

17031756
{
1704-
String *tmp= str;
1705-
str= &tmp_js;
1706-
js= tmp;
1757+
/* Swap str and js. */
1758+
if (str == &tmp_js)
1759+
{
1760+
str= js;
1761+
js= &tmp_js;
1762+
}
1763+
else
1764+
{
1765+
js= str;
1766+
str= &tmp_js;
1767+
}
17071768
}
17081769
}
17091770

0 commit comments

Comments
 (0)