1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

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

paths ending on [0]..[0] should be handled in conforming manner.
This commit is contained in:
Alexey Botchkov
2017-01-26 16:35:05 +04:00
parent 71495a1748
commit d96ee168a1
5 changed files with 150 additions and 53 deletions

View File

@ -444,3 +444,53 @@ json CREATE TABLE `json` (
`j` int(11) DEFAULT NULL `j` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table json; 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'

View File

@ -420,10 +420,10 @@ json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2]' )
1 1
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ); select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' ) json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][0]' )
NULL 1
select json_length( '[ 1, [ 2, 3, 4 ], {"a": 1} ]', '$[2][0]' ); select json_length( '[ 1, [ 2, 3, 4 ], {"a": 1} ]', '$[2][0]' );
json_length( '[ 1, [ 2, 3, 4 ], {"a": 1} ]', '$[2][0]' ) json_length( '[ 1, [ 2, 3, 4 ], {"a": 1} ]', '$[2][0]' )
NULL 1
select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][1]' ); select json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][1]' );
json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][1]' ) json_length( '[ 1, [ 2, 3, 4 ], 5 ]', '$[2][1]' )
NULL NULL
@ -1694,13 +1694,13 @@ JSON_ARRAY_APPEND
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
select json_array_append('{"a":1}', '$[0]', 100); select json_array_append('{"a":1}', '$[0]', 100);
json_array_append('{"a":1}', '$[0]', 100) json_array_append('{"a":1}', '$[0]', 100)
NULL [{"a":1}, 100]
select json_array_append('3', '$[0]', 100); select json_array_append('3', '$[0]', 100);
json_array_append('3', '$[0]', 100) json_array_append('3', '$[0]', 100)
NULL [3, 100]
select json_array_append('3', '$[0][0][0][0]', 100); select json_array_append('3', '$[0][0][0][0]', 100);
json_array_append('3', '$[0][0][0][0]', 100) json_array_append('3', '$[0][0][0][0]', 100)
NULL [3, 100]
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# Test of JSON_INSERT function. # Test of JSON_INSERT function.
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
@ -2118,7 +2118,7 @@ json_set('1', '$', 4)
4 4
select json_set('1', '$[0]', 4); select json_set('1', '$[0]', 4);
json_set('1', '$[0]', 4) json_set('1', '$[0]', 4)
[1, 4] 4
select json_set('1', '$[1]', 4); select json_set('1', '$[1]', 4);
json_set('1', '$[1]', 4) json_set('1', '$[1]', 4)
[1, 4] [1, 4]
@ -2127,13 +2127,13 @@ json_set('1', '$[10]', '4', '$[11]', 5)
[1, "4", 5] [1, "4", 5]
select json_set('[1,2,3]', '$[2][0]', 4); select json_set('[1,2,3]', '$[2][0]', 4);
json_set('[1,2,3]', '$[2][0]', 4) json_set('[1,2,3]', '$[2][0]', 4)
[1,2,[3, 4]] [1,2,4]
select json_set('[1,2,3]', '$[2][2]', 4); select json_set('[1,2,3]', '$[2][2]', 4);
json_set('[1,2,3]', '$[2][2]', 4) json_set('[1,2,3]', '$[2][2]', 4)
[1,2,[3, 4]] [1,2,[3, 4]]
select json_set('{"a": 3}', '$.a[0]', 4); select json_set('{"a": 3}', '$.a[0]', 4);
json_set('{"a": 3}', '$.a[0]', 4) json_set('{"a": 3}', '$.a[0]', 4)
{"a": [3, 4]} {"a": 4}
select json_set('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5'); select json_set('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5');
json_set('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5') json_set('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5')
{"a": [3, 4, "5"]} {"a": [3, 4, "5"]}
@ -2280,7 +2280,7 @@ json_replace('1', '$', 4)
4 4
select json_replace('1', '$[0]', 4); select json_replace('1', '$[0]', 4);
json_replace('1', '$[0]', 4) json_replace('1', '$[0]', 4)
1 4
select json_replace('1', '$[1]', 4); select json_replace('1', '$[1]', 4);
json_replace('1', '$[1]', 4) json_replace('1', '$[1]', 4)
1 1
@ -2289,13 +2289,13 @@ json_replace('1', '$[10]', '4', '$[11]', 5)
1 1
select json_replace('[1,2,3]', '$[2][0]', 4); select json_replace('[1,2,3]', '$[2][0]', 4);
json_replace('[1,2,3]', '$[2][0]', 4) json_replace('[1,2,3]', '$[2][0]', 4)
[1,2,3] [1,2,4]
select json_replace('[1,2,3]', '$[2][2]', 4); select json_replace('[1,2,3]', '$[2][2]', 4);
json_replace('[1,2,3]', '$[2][2]', 4) json_replace('[1,2,3]', '$[2][2]', 4)
[1,2,3] [1,2,3]
select json_replace('{"a": 3}', '$.a[0]', 4); select json_replace('{"a": 3}', '$.a[0]', 4);
json_replace('{"a": 3}', '$.a[0]', 4) json_replace('{"a": 3}', '$.a[0]', 4)
{"a": 3} {"a": 4}
select json_replace('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5'); select json_replace('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5');
json_replace('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5') json_replace('{"a": 3}', '$.a[1]', 4, '$.a[2]', '5')
{"a": 3} {"a": 3}
@ -2312,7 +2312,7 @@ true);
JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.a[0]', '$.a[0]',
true) true)
{ "a" : "foo", "b" : [ 1, 2, 3 ] } { "a" : true, "b" : [ 1, 2, 3 ] }
SELECT JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }', SELECT JSON_REPLACE('{ "a" : "foo", "b" : [ 1, 2, 3 ] }',
'$.b[5]', '$.b[5]',
true); true);
@ -3489,23 +3489,19 @@ JSON_SET('1', '$', 100)
100 100
SELECT JSON_SET('1', '$[0]', 100); SELECT JSON_SET('1', '$[0]', 100);
JSON_SET('1', '$[0]', 100) JSON_SET('1', '$[0]', 100)
[1, 100] 100
SELECT JSON_SET('1', '$[0][0]', 100); SELECT JSON_SET('1', '$[0][0]', 100);
JSON_SET('1', '$[0][0]', 100) JSON_SET('1', '$[0][0]', 100)
NULL 100
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
SELECT JSON_SET('1', '$[0][0][0]', 100); SELECT JSON_SET('1', '$[0][0][0]', 100);
JSON_SET('1', '$[0][0][0]', 100) JSON_SET('1', '$[0][0][0]', 100)
NULL 100
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
SELECT JSON_SET('[]', '$', 100); SELECT JSON_SET('[]', '$', 100);
JSON_SET('[]', '$', 100) JSON_SET('[]', '$', 100)
100 100
SELECT JSON_SET('[]', '$[0]', 100); SELECT JSON_SET('[]', '$[0]', 100);
JSON_SET('[]', '$[0]', 100) JSON_SET('[]', '$[0]', 100)
[, 100] [100]
SELECT JSON_SET('[]', '$[0][0]', 100); SELECT JSON_SET('[]', '$[0][0]', 100);
JSON_SET('[]', '$[0][0]', 100) JSON_SET('[]', '$[0][0]', 100)
NULL NULL
@ -3524,12 +3520,10 @@ JSON_SET('[1]', '$[0]', 100)
[100] [100]
SELECT JSON_SET('[1]', '$[0][0]', 100); SELECT JSON_SET('[1]', '$[0][0]', 100);
JSON_SET('[1]', '$[0][0]', 100) JSON_SET('[1]', '$[0][0]', 100)
[[1, 100]] [100]
SELECT JSON_SET('[1]', '$[0][0][0]', 100); SELECT JSON_SET('[1]', '$[0][0][0]', 100);
JSON_SET('[1]', '$[0][0][0]', 100) JSON_SET('[1]', '$[0][0][0]', 100)
NULL [100]
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_set'
SELECT JSON_SET('[[1]]', '$', 100); SELECT JSON_SET('[[1]]', '$', 100);
JSON_SET('[[1]]', '$', 100) JSON_SET('[[1]]', '$', 100)
100 100
@ -3541,7 +3535,7 @@ JSON_SET('[[1]]', '$[0][0]', 100)
[[100]] [[100]]
SELECT JSON_SET('[[1]]', '$[0][0][0]', 100); SELECT JSON_SET('[[1]]', '$[0][0][0]', 100);
JSON_SET('[[1]]', '$[0][0][0]', 100) JSON_SET('[[1]]', '$[0][0][0]', 100)
[[[1, 100]]] [[100]]
SELECT JSON_SET('[[[1]]]', '$', 100); SELECT JSON_SET('[[[1]]]', '$', 100);
JSON_SET('[[[1]]]', '$', 100) JSON_SET('[[[1]]]', '$', 100)
100 100
@ -3559,17 +3553,13 @@ JSON_REPLACE('1', '$', 100)
100 100
SELECT JSON_REPLACE('1', '$[0]', 100); SELECT JSON_REPLACE('1', '$[0]', 100);
JSON_REPLACE('1', '$[0]', 100) JSON_REPLACE('1', '$[0]', 100)
1 100
SELECT JSON_REPLACE('1', '$[0][0]', 100); SELECT JSON_REPLACE('1', '$[0][0]', 100);
JSON_REPLACE('1', '$[0][0]', 100) JSON_REPLACE('1', '$[0][0]', 100)
NULL 100
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_update'
SELECT JSON_REPLACE('1', '$[0][0][0]', 100); SELECT JSON_REPLACE('1', '$[0][0][0]', 100);
JSON_REPLACE('1', '$[0][0][0]', 100) JSON_REPLACE('1', '$[0][0][0]', 100)
NULL 100
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_update'
SELECT JSON_REPLACE('[]', '$', 100); SELECT JSON_REPLACE('[]', '$', 100);
JSON_REPLACE('[]', '$', 100) JSON_REPLACE('[]', '$', 100)
100 100
@ -3594,12 +3584,10 @@ JSON_REPLACE('[1]', '$[0]', 100)
[100] [100]
SELECT JSON_REPLACE('[1]', '$[0][0]', 100); SELECT JSON_REPLACE('[1]', '$[0][0]', 100);
JSON_REPLACE('[1]', '$[0][0]', 100) JSON_REPLACE('[1]', '$[0][0]', 100)
[1] [100]
SELECT JSON_REPLACE('[1]', '$[0][0][0]', 100); SELECT JSON_REPLACE('[1]', '$[0][0][0]', 100);
JSON_REPLACE('[1]', '$[0][0][0]', 100) JSON_REPLACE('[1]', '$[0][0][0]', 100)
NULL [100]
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_update'
SELECT JSON_REPLACE('[[1]]', '$', 100); SELECT JSON_REPLACE('[[1]]', '$', 100);
JSON_REPLACE('[[1]]', '$', 100) JSON_REPLACE('[[1]]', '$', 100)
100 100
@ -3611,7 +3599,7 @@ JSON_REPLACE('[[1]]', '$[0][0]', 100)
[[100]] [[100]]
SELECT JSON_REPLACE('[[1]]', '$[0][0][0]', 100); SELECT JSON_REPLACE('[[1]]', '$[0][0][0]', 100);
JSON_REPLACE('[[1]]', '$[0][0][0]', 100) JSON_REPLACE('[[1]]', '$[0][0][0]', 100)
[[1]] [[100]]
SELECT JSON_REPLACE('[[[1]]]', '$', 100); SELECT JSON_REPLACE('[[[1]]]', '$', 100);
JSON_REPLACE('[[[1]]]', '$', 100) JSON_REPLACE('[[[1]]]', '$', 100)
100 100

View File

@ -179,3 +179,21 @@ create table json (j INT);
show create table json; show create table json;
drop 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);

View File

@ -1983,13 +1983,22 @@ String *Item_func_json_insert::val_str(String *str)
if (je.value_type != JSON_VALUE_ARRAY) if (je.value_type != JSON_VALUE_ARRAY)
{ {
const uchar *v_from= je.value_begin; const uchar *v_from= je.value_begin;
if (!mode_insert) int do_array_autowrap;
continue;
if (mode_insert)
do_array_autowrap= !mode_replace || lp->n_item;
else
{
if (lp->n_item)
continue;
do_array_autowrap= 0;
}
str->length(0); str->length(0);
/* Wrap the value as an array. */ /* Wrap the value as an array. */
if (append_simple(str, js->ptr(), (const char *) v_from - js->ptr()) || 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. */ goto js_error; /* Out of memory. */
if (je.value_type == JSON_VALUE_OBJECT) if (je.value_type == JSON_VALUE_OBJECT)
@ -1998,10 +2007,11 @@ String *Item_func_json_insert::val_str(String *str)
goto js_error; goto js_error;
} }
if (append_simple(str, v_from, je.s.c_str - v_from) || if ((do_array_autowrap &&
str->append(", ", 2) || (append_simple(str, v_from, je.s.c_str - v_from) ||
str->append(", ", 2))) ||
append_json_value(str, args[n_arg+1], &tmp_val) || 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)) append_simple(str, je.s.c_str, js->end()-(const char *) je.s.c_str))
goto js_error; /* Out of memory. */ 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); v_to= (const char *) (je.s.c_str - je.sav_c_len);
str->length(0); str->length(0);
if (append_simple(str, js->ptr(), v_to - js->ptr()) || 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_json_value(str, args[n_arg+1], &tmp_val) ||
append_simple(str, v_to, js->end() - v_to)) append_simple(str, v_to, js->end() - v_to))
goto js_error; /* Out of memory. */ goto js_error; /* Out of memory. */

View File

@ -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. Current step of the patch matches the JSON construction.
Now we should either stop the search or go to the next 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, 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 **p_cur_step, uint *array_counters)
{ {
json_path_step_t *next_step= *p_cur_step + 1;
DBUG_ASSERT(*p_cur_step < p->last_step); DBUG_ASSERT(*p_cur_step < p->last_step);
if (json_read_value(je)) if (json_read_value(je))
return 1; return 1;
if (json_value_scalar(je)) if (json_value_scalar(je))
return 0;
(*p_cur_step)++;
array_counters[*p_cur_step - p->steps]= 0;
if ((int) je->value_type !=
(int) ((*p_cur_step)->type & JSON_PATH_KEY_OR_ARRAY))
{ {
(*p_cur_step)--; while (next_step->type == JSON_PATH_ARRAY && next_step->n_item == 0)
return json_skip_level(je); {
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);
}
array_counters[next_step - p->steps]= 0;
if ((int) je->value_type !=
(int) (next_step->type & JSON_PATH_KEY_OR_ARRAY))
return json_skip_level(je);
*p_cur_step= next_step;
return 0; return 0;
} }
@ -1277,6 +1303,11 @@ int json_find_path(json_engine_t *je,
json_skip_array_item(je); json_skip_array_item(je);
break; break;
case JST_OBJ_END: case JST_OBJ_END:
do
{
(*p_cur_step)--;
} while (array_counters[(*p_cur_step) - p->steps] == SKIPPED_STEP_MARK);
break;
case JST_ARRAY_END: case JST_ARRAY_END:
(*p_cur_step)--; (*p_cur_step)--;
break; break;