mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-12789 JSON_KEYS returns duplicate keys twice.
Check for duplicating keys added.
This commit is contained in:
@ -356,6 +356,12 @@ json_keys('foo')
|
|||||||
NULL
|
NULL
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 1
|
Warning 4038 Syntax error in JSON text in argument 1 to function 'json_keys' at position 1
|
||||||
|
select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}');
|
||||||
|
json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}')
|
||||||
|
["a", "b", "c"]
|
||||||
|
select json_keys('{"c1": "value 1", "c1": "value 2"}');
|
||||||
|
json_keys('{"c1": "value 1", "c1": "value 2"}')
|
||||||
|
["c1"]
|
||||||
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
|
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
|
||||||
select json_search(@j, 'one', 'abc');
|
select json_search(@j, 'one', 'abc');
|
||||||
json_search(@j, 'one', 'abc')
|
json_search(@j, 'one', 'abc')
|
||||||
|
@ -138,6 +138,11 @@ select json_keys('{"a":{"c":1, "d":2}, "b":2}');
|
|||||||
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a");
|
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.a");
|
||||||
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b");
|
select json_keys('{"a":{"c":1, "d":2}, "b":2}', "$.b");
|
||||||
select json_keys('foo');
|
select json_keys('foo');
|
||||||
|
#
|
||||||
|
# mdev-12789 JSON_KEYS returns duplicate keys twice
|
||||||
|
#
|
||||||
|
select json_keys('{"a":{"c":1, "d":2}, "b":2, "c":1, "a":3, "b":1, "c":2}');
|
||||||
|
select json_keys('{"c1": "value 1", "c1": "value 2"}');
|
||||||
|
|
||||||
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
|
SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
|
||||||
select json_search(@j, 'one', 'abc');
|
select json_search(@j, 'one', 'abc');
|
||||||
|
@ -2779,6 +2779,41 @@ void Item_func_json_keys::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
That function is for Item_func_json_keys::val_str exclusively.
|
||||||
|
It utilizes the fact the resulting string is in specific format:
|
||||||
|
["key1", "key2"...]
|
||||||
|
*/
|
||||||
|
static int check_key_in_list(String *res,
|
||||||
|
const uchar *key, int key_len)
|
||||||
|
{
|
||||||
|
const uchar *c= (const uchar *) res->ptr() + 2; /* beginning '["' */
|
||||||
|
const uchar *end= (const uchar *) res->end() - 1; /* ending '"' */
|
||||||
|
|
||||||
|
while (c < end)
|
||||||
|
{
|
||||||
|
int n_char;
|
||||||
|
for (n_char=0; c[n_char] != '"' && n_char < key_len; n_char++)
|
||||||
|
{
|
||||||
|
if (c[n_char] != key[n_char])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c[n_char] == '"')
|
||||||
|
{
|
||||||
|
if (n_char == key_len)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (c[n_char] != '"')
|
||||||
|
n_char++;
|
||||||
|
}
|
||||||
|
c+= n_char + 4; /* skip ', "' */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
String *Item_func_json_keys::val_str(String *str)
|
String *Item_func_json_keys::val_str(String *str)
|
||||||
{
|
{
|
||||||
json_engine_t je;
|
json_engine_t je;
|
||||||
@ -2835,6 +2870,7 @@ skip_search:
|
|||||||
while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
|
while (json_scan_next(&je) == 0 && je.state != JST_OBJ_END)
|
||||||
{
|
{
|
||||||
const uchar *key_start, *key_end;
|
const uchar *key_start, *key_end;
|
||||||
|
int key_len;
|
||||||
|
|
||||||
switch (je.state)
|
switch (je.state)
|
||||||
{
|
{
|
||||||
@ -2844,13 +2880,19 @@ skip_search:
|
|||||||
{
|
{
|
||||||
key_end= je.s.c_str;
|
key_end= je.s.c_str;
|
||||||
} while (json_read_keyname_chr(&je) == 0);
|
} while (json_read_keyname_chr(&je) == 0);
|
||||||
if (je.s.error ||
|
if (je.s.error)
|
||||||
(n_keys > 0 && str->append(", ", 2)) ||
|
goto err_return;
|
||||||
|
key_len= key_end - key_start;
|
||||||
|
|
||||||
|
if (!check_key_in_list(str, key_start, key_len))
|
||||||
|
{
|
||||||
|
if ((n_keys > 0 && str->append(", ", 2)) ||
|
||||||
str->append("\"", 1) ||
|
str->append("\"", 1) ||
|
||||||
append_simple(str, key_start, key_end - key_start) ||
|
append_simple(str, key_start, key_len) ||
|
||||||
str->append("\"", 1))
|
str->append("\"", 1))
|
||||||
goto err_return;
|
goto err_return;
|
||||||
n_keys++;
|
n_keys++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case JST_OBJ_START:
|
case JST_OBJ_START:
|
||||||
case JST_ARRAY_START:
|
case JST_ARRAY_START:
|
||||||
|
Reference in New Issue
Block a user