Commit d96ee168 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-11557 port MySQL-5.7 JSON tests to MariaDB.

        paths ending on [0]..[0] should be handled in conforming manner.
parent 71495a17
......@@ -444,3 +444,53 @@ json CREATE TABLE `json` (
`j` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table json;
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' )
1
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' )
1
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' )
1
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' )
1
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' );
json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' )
2
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' );
json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' )
2
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' );
json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' )
2
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' );
json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' )
2
select json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' );
json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' )
2
select json_set('1', '$[0]', 100);
json_set('1', '$[0]', 100)
100
select json_set('1', '$[0][0]', 100);
json_set('1', '$[0][0]', 100)
100
select json_set('1', '$[1]', 100);
json_set('1', '$[1]', 100)
[1, 100]
select json_set('{"a":12}', '$[0]', 100);
json_set('{"a":12}', '$[0]', 100)
100
select json_set('{"a":12}', '$[0].a', 100);
json_set('{"a":12}', '$[0].a', 100)
{"a":100}
select json_set('{"a":12}', '$[0][0].a', 100);
json_set('{"a":12}', '$[0][0].a', 100)
{"a":100}
select json_set('{"a":12}', '$[0][1].a', 100);
json_set('{"a":12}', '$[0][1].a', 100)
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
......@@ -179,3 +179,21 @@ create table json (j INT);
show create table json;
drop table json;
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' );
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' );
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0]' );
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0][0][0]' );
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2]' );
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0]' );
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0]' );
select json_length( '[ 1, [ 2, 3, 4 ], {"a":5, "b":6} ]', '$[2][0][0][0]' );
select json_length( '{"a":{"b":{"d":1}}, "a":{"c":{"d":1, "j":2}}}', '$.a[0][0][0].c' );
select json_set('1', '$[0]', 100);
select json_set('1', '$[0][0]', 100);
select json_set('1', '$[1]', 100);
select json_set('{"a":12}', '$[0]', 100);
select json_set('{"a":12}', '$[0].a', 100);
select json_set('{"a":12}', '$[0][0].a', 100);
select json_set('{"a":12}', '$[0][1].a', 100);
......@@ -1983,13 +1983,22 @@ String *Item_func_json_insert::val_str(String *str)
if (je.value_type != JSON_VALUE_ARRAY)
{
const uchar *v_from= je.value_begin;
if (!mode_insert)
continue;
int do_array_autowrap;
if (mode_insert)
do_array_autowrap= !mode_replace || lp->n_item;
else
{
if (lp->n_item)
continue;
do_array_autowrap= 0;
}
str->length(0);
/* Wrap the value as an array. */
if (append_simple(str, js->ptr(), (const char *) v_from - js->ptr()) ||
str->append("[", 1))
(do_array_autowrap && str->append("[", 1)))
goto js_error; /* Out of memory. */
if (je.value_type == JSON_VALUE_OBJECT)
......@@ -1998,10 +2007,11 @@ String *Item_func_json_insert::val_str(String *str)
goto js_error;
}
if (append_simple(str, v_from, je.s.c_str - v_from) ||
str->append(", ", 2) ||
if ((do_array_autowrap &&
(append_simple(str, v_from, je.s.c_str - v_from) ||
str->append(", ", 2))) ||
append_json_value(str, args[n_arg+1], &tmp_val) ||
str->append("]", 1) ||
(do_array_autowrap && str->append("]", 1)) ||
append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
goto js_error; /* Out of memory. */
......@@ -2033,7 +2043,7 @@ String *Item_func_json_insert::val_str(String *str)
v_to= (const char *) (je.s.c_str - je.sav_c_len);
str->length(0);
if (append_simple(str, js->ptr(), v_to - js->ptr()) ||
str->append(", ", 2) ||
(n_item > 0 && str->append(", ", 2)) ||
append_json_value(str, args[n_arg+1], &tmp_val) ||
append_simple(str, v_to, js->end() - v_to))
goto js_error; /* Out of memory. */
......
......@@ -1187,6 +1187,8 @@ int json_skip_key(json_engine_t *j)
}
#define SKIPPED_STEP_MARK ((uint) ~0)
/*
Current step of the patch matches the JSON construction.
Now we should either stop the search or go to the next
......@@ -1195,24 +1197,48 @@ int json_skip_key(json_engine_t *j)
static int handle_match(json_engine_t *je, json_path_t *p,
json_path_step_t **p_cur_step, uint *array_counters)
{
json_path_step_t *next_step= *p_cur_step + 1;
DBUG_ASSERT(*p_cur_step < p->last_step);
if (json_read_value(je))
return 1;
if (json_value_scalar(je))
{
while (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0)
{
if (++next_step > p->last_step)
{
je->s.c_str= je->value_begin;
return 1;
}
}
return 0;
}
if (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0 &&
je->value_type & JSON_VALUE_OBJECT)
{
do
{
array_counters[next_step - p->steps]= SKIPPED_STEP_MARK;
if (++next_step > p->last_step)
{
je->s.c_str= je->value_begin;
return 1;
}
} while (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0);
}
(*p_cur_step)++;
array_counters[*p_cur_step - p->steps]= 0;
array_counters[next_step - p->steps]= 0;
if ((int) je->value_type !=
(int) ((*p_cur_step)->type & JSON_PATH_KEY_OR_ARRAY))
{
(*p_cur_step)--;
(int) (next_step->type & JSON_PATH_KEY_OR_ARRAY))
return json_skip_level(je);
}
*p_cur_step= next_step;
return 0;
}
......@@ -1277,6 +1303,11 @@ int json_find_path(json_engine_t *je,
json_skip_array_item(je);
break;
case JST_OBJ_END:
do
{
(*p_cur_step)--;
} while (array_counters[(*p_cur_step) - p->steps] == SKIPPED_STEP_MARK);
break;
case JST_ARRAY_END:
(*p_cur_step)--;
break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment