This commit is contained in:
Rucha Deodhar 2024-12-11 22:59:31 +05:30
parent b6cee50a5a
commit 5ddab60c5d
19 changed files with 523 additions and 425 deletions

View file

@ -9,6 +9,7 @@ extern "C" {
#define JSON_DEPTH_DEFAULT 32
#define JSON_DEPTH_LIMIT JSON_DEPTH_DEFAULT /* Still used in column store. */
#define JSON_DEPTH_INC JSON_DEPTH_DEFAULT*100
/*
Because this array will store approximate two arrays of
type json_path_step_t and one or two integer arrays,
@ -450,14 +451,16 @@ int json_path_compare(const json_path_t *a, const json_path_t *b,
int json_valid(const char *js, size_t js_len,
CHARSET_INFO *cs, json_engine_t *je);
int json_locate_key(const char *js, const char *js_end,
int json_locate_key(json_engine_t *je, const char *js, const char *js_end,
const char *kname,
const char **key_start, const char **key_end,
int *comma_pos);
int json_normalize(DYNAMIC_STRING *result,
const char *s, size_t size, CHARSET_INFO *cs,
MEM_ROOT *current_mem_root);
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack);
int json_skip_array_and_count(json_engine_t *j, int* n_item);

View file

@ -640,24 +640,20 @@ ex
set @save_max_allowed_packet=@@max_allowed_packet;
set @save_net_buffer_length=@@net_buffer_length;
set @@global.net_buffer_length=1024;
set @@global.max_allowed_packet=2048;
set @@global.max_allowed_packet=4096;
connect newconn, localhost, root,,;
show variables like 'net_buffer_length';
Variable_name Value
net_buffer_length 1024
show variables like 'max_allowed_packet';
Variable_name Value
max_allowed_packet 2048
max_allowed_packet 4096
select json_array(repeat('a',1024),repeat('a',1024)) as ex;
ex
NULL
Warnings:
Warning 1301 Result of json_array() was larger than max_allowed_packet (2048) - truncated
["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
select json_object("a", repeat('a',1024),"b", repeat('a',1024)) as ex;
ex
NULL
Warnings:
Warning 1301 Result of json_object() was larger than max_allowed_packet (2048) - truncated
{"a": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "b": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}
connection default;
set @@global.max_allowed_packet = @save_max_allowed_packet;
set @@global.net_buffer_length = @save_net_buffer_length;

View file

@ -286,7 +286,7 @@ set @save_max_allowed_packet=@@max_allowed_packet;
set @save_net_buffer_length=@@net_buffer_length;
set @@global.net_buffer_length=1024;
set @@global.max_allowed_packet=2048;
set @@global.max_allowed_packet=4096;
--connect (newconn, localhost, root,,)
show variables like 'net_buffer_length';

View file

@ -124,7 +124,7 @@ bool Item_func_geometry_from_json::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return Item_geometry_func::fix_length_and_dec(thd);
}

View file

@ -22,9 +22,11 @@
#include "json_schema_helper.h"
static bool get_current_value(json_engine_t *, const uchar *&, size_t &);
static int check_overlaps(json_engine_t *, json_engine_t *, bool, MEM_ROOT*);
static int check_overlaps(json_engine_t *, json_engine_t *, bool, MEM_ROOT*, json_engine_t *temp_je, MEM_ROOT_DYNAMIC_ARRAY *stack);
static int json_find_overlap_with_object(json_engine_t *,
json_engine_t *, bool, MEM_ROOT*);
json_engine_t *, bool, MEM_ROOT*,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack);
#ifndef DBUG_OFF
static int dbug_json_check_min_stack_requirement()
@ -601,7 +603,7 @@ bool Item_func_json_valid::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (Item_bool_func::fix_length_and_dec(thd))
return TRUE;
@ -638,10 +640,16 @@ bool Item_func_json_equals::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je1.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je2.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (Item_bool_func::fix_length_and_dec(thd))
return TRUE;
@ -702,14 +710,14 @@ longlong Item_func_json_equals::val_int()
}
if (json_normalize(&a_res, a->ptr(), a->length(),
a->charset(), &current_mem_root))
a->charset(), &current_mem_root, &temp_je, &stack))
{
null_value= 1;
goto end;
}
if (json_normalize(&b_res, b->ptr(), b->length(),
b->charset(), &current_mem_root))
b->charset(), &current_mem_root, &temp_je, &stack))
{
null_value= 1;
goto end;
@ -738,13 +746,13 @@ bool Item_func_json_exists::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&path.p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return FALSE;
}
@ -820,7 +828,7 @@ bool Item_func_json_value::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
Json_path_extractor::init_json_engine_stack(&current_mem_root);
return FALSE;
@ -854,7 +862,7 @@ bool Item_func_json_query::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
Json_path_extractor::init_json_engine_stack(&current_mem_root);
return FALSE;
@ -877,10 +885,10 @@ void Json_path_extractor::init_json_engine_stack(MEM_ROOT *current_mem_root)
{
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
bool Json_path_extractor::extract(MEM_ROOT *mem_root, String *str,
@ -1015,7 +1023,7 @@ bool Item_func_json_quote::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
collation.set(&my_charset_utf8mb4_bin);
/*
Odd but realistic worst case is when all characters
@ -1070,7 +1078,7 @@ bool Item_func_json_unquote::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
collation.set(&my_charset_utf8mb3_general_ci,
DERIVATION_CAST, MY_REPERTOIRE_ASCII);
@ -1237,24 +1245,24 @@ bool Item_func_json_extract::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&sav_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
for (uint n_arg=1; n_arg < arg_count; n_arg++)
{
json_path_with_flags *c_path= paths + n_arg - 1;
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&(c_path->p.steps), sizeof(json_path_step_t),
NULL, JSON_DEPTH_DEFAULT, 0, MYF(0));
NULL, JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return FALSE;
}
@ -1561,16 +1569,16 @@ bool Item_func_json_contains::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&(path.p.steps), sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&ve.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return Item_bool_func::fix_length_and_dec(thd);
}
@ -1603,7 +1611,7 @@ int Item_func_json_contains::check_contains(json_engine_t *js,
init_alloc_root(PSI_NOT_INSTRUMENTED, &tmp_mem_root, 8192, 0, MYF(0));
mem_root_dynamic_array_init(&tmp_mem_root, PSI_NOT_INSTRUMENTED,
&loc_js.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
DBUG_EXECUTE_IF("json_check_min_stack_requirement",
return dbug_json_check_min_stack_requirement(););
@ -1897,20 +1905,20 @@ bool Item_func_json_contains_path::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&(p.steps), sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
for (uint n_arg=2; n_arg < arg_count; n_arg++)
{
json_path_with_flags *c_path= paths + n_arg - 2;
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&c_path->p.steps,
sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
return Item_bool_func::fix_length_and_dec(thd);
@ -2306,7 +2314,7 @@ bool Item_func_json_array::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (arg_count == 0)
{
@ -2421,15 +2429,15 @@ bool Item_func_json_array_append::fix_length_and_dec(THD *thd)
if (!mem_root_inited)
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
2*BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_inited= true;
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
for (uint n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
{
@ -2437,7 +2445,7 @@ bool Item_func_json_array_append::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&c_path->p.steps,
sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
fix_char_length_ulonglong(char_length);
@ -2596,7 +2604,6 @@ String *Item_func_json_array_insert::val_str(String *str)
for (n_arg=1, n_path=0; n_arg < arg_count; n_arg+=2, n_path++)
{
json_path_with_flags *c_path= paths + n_path;
json_path_step_t *psteps= (json_path_step_t*)(c_path->p.steps.buffer);
const char *item_pos;
int n_item, corrected_n_item;
@ -2606,8 +2613,15 @@ String *Item_func_json_array_insert::val_str(String *str)
if (s_p &&
(path_setup_nwc(&c_path->p,s_p->charset(),(const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()) ||
((json_path_step_t*)(mem_root_dynamic_array_get_val(&c_path->p.steps, c_path->p.last_step_idx))) - 1 < psteps ||
((json_path_step_t*)(mem_root_dynamic_array_get_val(&c_path->p.steps, c_path->p.last_step_idx)))->type != JSON_PATH_ARRAY))
((json_path_step_t*)
(mem_root_dynamic_array_get_val(&c_path->p.steps,
c_path->p.last_step_idx))) - 1 <
((json_path_step_t*)
(mem_root_dynamic_array_get_val(&c_path->p.steps,
0))) ||
((json_path_step_t*)
(mem_root_dynamic_array_get_val(&c_path->p.steps,
c_path->p.last_step_idx)))->type != JSON_PATH_ARRAY))
{
if (c_path->p.s.error == 0)
c_path->p.s.error= SHOULD_END_WITH_ARRAY;
@ -3006,7 +3020,7 @@ bool Item_func_json_merge::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je2.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return Item_func_json_array::fix_length_and_dec(thd);
}
@ -3429,15 +3443,15 @@ bool Item_func_json_length::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&(path.p.steps),
sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return FALSE;
}
@ -3538,7 +3552,7 @@ bool Item_func_json_depth::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return false;
}
@ -3606,7 +3620,7 @@ bool Item_func_json_type::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return FALSE;
}
@ -3689,10 +3703,10 @@ bool Item_func_json_insert::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
collation.set(args[0]->collation);
char_length= args[0]->max_char_length();
@ -3703,7 +3717,7 @@ bool Item_func_json_insert::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&c_path->p.steps,
sizeof(json_path_step_t),
NULL, JSON_DEPTH_DEFAULT, 0, MYF(0));
NULL, JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
for (n_arg= 1; n_arg < arg_count; n_arg+= 2)
@ -4002,17 +4016,17 @@ bool Item_func_json_remove::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
for (uint n_arg=1, n_path=0; n_arg < arg_count; n_arg++, n_path++)
{
json_path_with_flags *c_path= paths + n_path;
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&c_path->p.steps, sizeof(json_path_step_t),
NULL, JSON_DEPTH_DEFAULT, 0, MYF(0));
NULL, JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mark_constant_paths(paths, args+1, arg_count-1);
set_maybe_null();
@ -4243,13 +4257,13 @@ bool Item_func_json_keys::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&path.p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
set_maybe_null();
if (arg_count > 1)
path.set_constant_flag(args[1]->const_item());
@ -4453,22 +4467,22 @@ bool Item_func_json_search::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&sav_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
for (uint n_arg=4; n_arg < arg_count; n_arg++)
{
json_path_with_flags *c_path= paths + n_arg - 4;
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&c_path->p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
return FALSE;
@ -4695,7 +4709,7 @@ bool Item_func_json_format::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return FALSE;
}
@ -4762,7 +4776,7 @@ int Arg_comparator::compare_json_str_basic(Item *j, Item *s)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if ((js= j->val_str(&value1)))
{
json_scan_start(&je, js->charset(), (const uchar *) js->ptr(),
@ -5046,7 +5060,8 @@ String *Item_func_json_normalize::val_str(String *buf)
if (json_normalize(&normalized_json,
raw_json->ptr(), raw_json->length(),
raw_json->charset(), &current_mem_root))
raw_json->charset(), &current_mem_root,
&temp_je, &stack))
{
null_value= 1;
goto end;
@ -5074,7 +5089,14 @@ bool Item_func_json_normalize::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
collation.set(&my_charset_utf8mb4_bin);
/* 0 becomes 0.0E0, thus one character becomes 5 chars */
fix_char_length_ulonglong((ulonglong) args[0]->max_char_length() * 5);
@ -5150,7 +5172,9 @@ static bool json_find_overlap_with_scalar(json_engine_t *js, json_engine_t *valu
equal return true else return false.
*/
static bool json_compare_arr_and_obj(json_engine_t *js, json_engine_t *value,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
st_json_engine_t loc_val= *value;
while (json_scan_next(js) == 0 && js->state == JST_VALUE)
@ -5160,7 +5184,9 @@ static bool json_compare_arr_and_obj(json_engine_t *js, json_engine_t *value,
if (js->value_type == JSON_VALUE_OBJECT)
{
int res1= json_find_overlap_with_object(js, value, true,
current_mem_root);
current_mem_root,
temp_je,
stack);
if (res1)
return TRUE;
*value= loc_val;
@ -5173,7 +5199,8 @@ static bool json_compare_arr_and_obj(json_engine_t *js, json_engine_t *value,
bool json_compare_arrays_in_order(json_engine_t *js, json_engine_t *value,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root, json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
bool res= false;
while (json_scan_next(js) == 0 && json_scan_next(value) == 0 &&
@ -5186,7 +5213,7 @@ bool json_compare_arrays_in_order(json_engine_t *js, json_engine_t *value,
json_skip_current_level(js, value);
return FALSE;
}
res= check_overlaps(js, value, true, current_mem_root);
res= check_overlaps(js, value, true, current_mem_root, temp_je, stack);
if (!res)
{
json_skip_current_level(js, value);
@ -5202,12 +5229,13 @@ bool json_compare_arrays_in_order(json_engine_t *js, json_engine_t *value,
static int json_find_overlap_with_array(json_engine_t *js, json_engine_t *value,
bool compare_whole,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *temp_je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
if (value->value_type == JSON_VALUE_ARRAY)
{
if (compare_whole)
return json_compare_arrays_in_order(js, value, current_mem_root);
return json_compare_arrays_in_order(js, value, current_mem_root, temp_je, stack);
json_engine_t loc_value= *value, current_js= *js;
@ -5222,7 +5250,7 @@ static int json_find_overlap_with_array(json_engine_t *js, json_engine_t *value,
return FALSE;
if (js->value_type == value->value_type)
{
int res1= check_overlaps(js, value, true, current_mem_root);
int res1= check_overlaps(js, value, true, current_mem_root, temp_je, stack);
if (res1)
return TRUE;
}
@ -5246,7 +5274,7 @@ static int json_find_overlap_with_array(json_engine_t *js, json_engine_t *value,
json_skip_current_level(js, value);
return FALSE;
}
return json_compare_arr_and_obj(js, value, current_mem_root);
return json_compare_arr_and_obj(js, value, current_mem_root, temp_je, stack);
}
else
return json_find_overlap_with_scalar(value, js);
@ -5254,7 +5282,9 @@ static int json_find_overlap_with_array(json_engine_t *js, json_engine_t *value,
int compare_nested_object(json_engine_t *js, json_engine_t *value,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int result= 0;
const char *value_begin= (const char*)value->s.c_str-1;
@ -5274,9 +5304,9 @@ int compare_nested_object(json_engine_t *js, json_engine_t *value,
goto error;
}
if (json_normalize(&a_res, a.ptr(), a.length(), value->s.cs,
current_mem_root) ||
current_mem_root, temp_je, stack) ||
json_normalize(&b_res, b.ptr(), b.length(), value->s.cs,
current_mem_root))
current_mem_root, temp_je, stack))
{
goto error;
}
@ -5293,13 +5323,15 @@ int compare_nested_object(json_engine_t *js, json_engine_t *value,
static int json_find_overlap_with_object(json_engine_t *js, json_engine_t *value,
bool compare_whole,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
if (value->value_type == JSON_VALUE_OBJECT)
{
if (compare_whole)
{
return compare_nested_object(js, value, current_mem_root);
return compare_nested_object(js, value, current_mem_root, temp_je, stack);
}
else
{
@ -5338,7 +5370,7 @@ static int json_find_overlap_with_object(json_engine_t *js, json_engine_t *value
to true.
*/
if (js->value_type == value->value_type)
found_value= check_overlaps(js, value, true, current_mem_root);
found_value= check_overlaps(js, value, true, current_mem_root, temp_je, stack);
if (found_value)
{
/*
@ -5392,7 +5424,7 @@ static int json_find_overlap_with_object(json_engine_t *js, json_engine_t *value
json_skip_current_level(js, value);
return FALSE;
}
return json_compare_arr_and_obj(value, js, current_mem_root);
return json_compare_arr_and_obj(value, js, current_mem_root, temp_je, stack);
}
return FALSE;
}
@ -5449,7 +5481,9 @@ static int json_find_overlap_with_object(json_engine_t *js, json_engine_t *value
TRUE - if two json documents overlap
*/
static int check_overlaps(json_engine_t *js, json_engine_t *value,
bool compare_whole, MEM_ROOT *current_mem_root)
bool compare_whole, MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
DBUG_EXECUTE_IF("json_check_min_stack_requirement",
return dbug_json_check_min_stack_requirement(););
@ -5460,10 +5494,11 @@ static int check_overlaps(json_engine_t *js, json_engine_t *value,
{
case JSON_VALUE_OBJECT:
return json_find_overlap_with_object(js, value, compare_whole,
current_mem_root);
current_mem_root, temp_je,
stack);
case JSON_VALUE_ARRAY:
return json_find_overlap_with_array(js, value, compare_whole,
current_mem_root);
current_mem_root, temp_je, stack);
default:
return json_find_overlap_with_scalar(js, value);
}
@ -5498,7 +5533,7 @@ longlong Item_func_json_overlaps::val_int()
if (json_read_value(&je) || json_read_value(&ve))
goto error;
result= check_overlaps(&je, &ve, false, &current_mem_root);
result= check_overlaps(&je, &ve, false, &current_mem_root, &temp_je, &stack);
while (json_scan_next(&je) == 0) {}
while(json_scan_next(&ve) == 0) {}
@ -5528,10 +5563,16 @@ bool Item_func_json_overlaps::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&ve.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return Item_bool_func::fix_length_and_dec(thd);
}
@ -5621,10 +5662,10 @@ bool Item_func_json_schema_valid::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&ve.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (!is_schema_constant)
{
my_error(ER_JSON_NO_VARIABLE_SCHEMA, MYF(0));
@ -5821,26 +5862,27 @@ bool Item_func_json_key_value::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&json_depth_array,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps,
sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je_scan.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
Json_path_extractor::init_json_engine_stack(&current_mem_root);
return FALSE;
}
static bool create_hash(json_engine_t *value, HASH *items, bool &hash_inited,
MEM_ROOT *hash_root, MEM_ROOT *current_mem_root)
MEM_ROOT *hash_root, MEM_ROOT *current_mem_root,
json_engine_t *temp_je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int level= value->stack_p;
if (my_hash_init(PSI_INSTRUMENT_ME, items, value->s.cs, 0, 0, 0,
@ -5860,7 +5902,8 @@ static bool create_hash(json_engine_t *value, HASH *items, bool &hash_inited,
return true;
if (json_normalize(&norm_val, (const char*) value_start,
value_len, value->s.cs, current_mem_root))
value_len, value->s.cs, current_mem_root,
temp_je, stack))
{
dynstr_free(&norm_val);
return true;
@ -5929,7 +5972,9 @@ static bool get_current_value(json_engine_t *js, const uchar *&value_start,
*/
static bool get_intersect_between_arrays(String *str, json_engine_t *value,
HASH items,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
bool res= true, has_value= false;
int level= value->stack_p;
@ -5948,7 +5993,7 @@ static bool get_intersect_between_arrays(String *str, json_engine_t *value,
goto error;
if (json_normalize(&norm_val, (const char*) value_start,
value_len, value->s.cs, current_mem_root))
value_len, value->s.cs, current_mem_root, temp_je, stack))
{
dynstr_free(&norm_val);
goto error;
@ -6032,7 +6077,7 @@ String* Item_func_json_array_intersect::val_str(String *str)
if (json_read_value(&je2) || je2.value_type != JSON_VALUE_ARRAY)
goto error_return;
if (get_intersect_between_arrays(str, &je2, items, &current_mem_root))
if (get_intersect_between_arrays(str, &je2, items, &current_mem_root, &temp_je, &stack))
goto error_return;
if (str->length())
@ -6072,7 +6117,7 @@ void Item_func_json_array_intersect::prepare_json_and_create_hash(json_engine_t
hash_root_inited= true;
if (json_read_value(je1) || je1->value_type != JSON_VALUE_ARRAY ||
create_hash(je1, &items, hash_inited, &hash_root, &current_mem_root))
create_hash(je1, &items, hash_inited, &hash_root, &current_mem_root, &temp_je, &stack))
{
if (je1->s.error)
report_json_error(js, je1, 0);
@ -6094,15 +6139,21 @@ bool Item_func_json_array_intersect::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je1.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&res_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je2.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (!args[0]->const_item())
{
@ -6254,13 +6305,19 @@ bool Item_func_json_object_filter_keys::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je1.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je_res.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je2.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (args[1]->null_value)
{
@ -6275,7 +6332,7 @@ bool Item_func_json_object_filter_keys::fix_length_and_dec(THD *thd)
hash_root_inited= true;
if (json_read_value(&temp_je) || temp_je.value_type != JSON_VALUE_ARRAY ||
create_hash(&temp_je, &items, hash_inited, &hash_root, &current_mem_root))
create_hash(&temp_je, &items, hash_inited, &hash_root, &current_mem_root, &temp_je2, &stack))
{
if (temp_je.s.error)
report_json_error(js2, &temp_je, 0);
@ -6410,7 +6467,7 @@ bool Item_func_json_object_to_array::fix_length_and_dec(THD *thd)
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return FALSE;
}

View file

@ -134,9 +134,10 @@ public:
class Item_func_json_equals: public Item_bool_func
{
json_engine_t je1, je2;
json_engine_t je1, je2, temp_je;
MEM_ROOT current_mem_root;
bool mem_root_inited;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_equals(THD *thd, Item *a, Item *b):
@ -613,9 +614,10 @@ public:
class Item_func_json_normalize: public Item_json_func
{
json_engine_t je;
json_engine_t je, temp_je;
MEM_ROOT current_mem_root;
bool mem_root_inited;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_normalize(THD *thd, Item *a):
@ -1050,9 +1052,10 @@ class Item_func_json_overlaps: public Item_bool_func
String tmp_js;
bool a2_constant, a2_parsed;
String tmp_val, *val;
json_engine_t je, ve;
json_engine_t je, ve, temp_je;
MEM_ROOT current_mem_root;
bool mem_root_inited;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_overlaps(THD *thd, Item *a, Item *b):
@ -1150,9 +1153,10 @@ protected:
HASH items;
MEM_ROOT hash_root;
bool parse_for_each_row;
json_engine_t je1, je2, res_je;
json_engine_t je1, je2, res_je, temp_je;
MEM_ROOT current_mem_root;
bool mem_root_inited;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_array_intersect(THD *thd, Item *a, Item *b):
@ -1191,9 +1195,10 @@ protected:
bool hash_inited, hash_root_inited;
HASH items;
MEM_ROOT hash_root;
json_engine_t je1, je_res, temp_je;
json_engine_t je1, je_res, temp_je, temp_je2;
MEM_ROOT current_mem_root;
bool mem_root_inited;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_object_filter_keys(THD *thd, Item *a, Item *b):

View file

@ -424,16 +424,12 @@ bool Json_schema_const::validate(const json_engine_t *je,
const char *start= (char*)curr_je.value;
const char *end= (char*)curr_je.value+curr_je.value_len;
json_engine_t temp_je= *je;
json_engine_t temp_je_2;
String a_res("", 0, curr_je.s.cs);
int err= 0;
if (type != curr_je.value_type)
return true;
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je_2.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
if (curr_je.value_type <= JSON_VALUE_NUMBER)
{
if (!json_value_scalar(&temp_je))
@ -457,7 +453,7 @@ mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
curr_je= temp_je;
return true;
}
json_get_normalized_string(&temp_je_2, &a_res, &err, current_mem_root);
json_get_normalized_string(&temp_je_2, &a_res, &err, current_mem_root, &temp_je_arg, &stack);
if (err)
{
return true;
@ -495,6 +491,15 @@ bool Json_schema_const::handle_keyword(THD *thd,
&temp_je.stack,
sizeof(int), NULL,
32, 32, MYF(0));
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je_arg.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je_2.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
type= je->value_type;
@ -515,7 +520,7 @@ bool Json_schema_const::handle_keyword(THD *thd,
{
return true;
}
json_get_normalized_string(&temp_je, &a_res, &err, current_mem_root);
json_get_normalized_string(&temp_je, &a_res, &err, current_mem_root, &temp_je_arg, &stack);
if (err)
{
return true;
@ -557,7 +562,7 @@ bool Json_schema_enum::validate(const json_engine_t *je,
else
return false;
}
json_get_normalized_string(&temp_je, &a_res, &err, current_mem_root);
json_get_normalized_string(&temp_je, &a_res, &err, current_mem_root, &temp_je_arg, &stack);
if (err)
return true;
@ -578,6 +583,14 @@ bool Json_schema_enum::handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
*all_keywords)
{
int count= 0;
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je_arg.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (my_hash_init(PSI_INSTRUMENT_ME,
&this->enum_values,
je->s.cs, 1024, 0, 0, (my_hash_get_key) get_key_name,
@ -608,7 +621,7 @@ bool Json_schema_enum::handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
int err= 1;
String a_res("", 0, je->s.cs);
json_get_normalized_string(je, &a_res, &err, current_mem_root);
json_get_normalized_string(je, &a_res, &err, current_mem_root, &temp_je_arg, &stack);
if (err)
return true;
@ -1355,7 +1368,7 @@ bool Json_schema_prefix_items::handle_keyword(THD *thd,
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
while(json_scan_next(je)==0 && je->stack_p >= level)
{
@ -1430,7 +1443,7 @@ bool Json_schema_unique_items::validate(const json_engine_t *je,
if (json_read_value(&curr_je))
goto end;
json_get_normalized_string(&curr_je, &a_res, &err, current_mem_root);
json_get_normalized_string(&curr_je, &a_res, &err, current_mem_root, &temp_je_arg, &stack);
if (err)
goto end;
@ -1486,6 +1499,13 @@ bool Json_schema_unique_items::handle_keyword(THD *thd,
List<Json_schema_keyword>
*all_keywords)
{
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je_arg.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (je->value_type == JSON_VALUE_TRUE)
is_unique= true;
else if (je->value_type == JSON_VALUE_FALSE)
@ -2446,7 +2466,7 @@ bool Json_schema_logic::handle_keyword(THD *thd,
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (je->value_type != JSON_VALUE_ARRAY)
{

View file

@ -170,6 +170,8 @@ class Json_schema_const : public Json_schema_keyword
{
private:
char *const_json_value;
json_engine_t temp_je_arg, temp_je_2;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
enum json_value_types type;
@ -193,6 +195,8 @@ class Json_schema_enum : public Json_schema_keyword
private:
HASH enum_values;
uint enum_scalar;
json_engine_t temp_je_arg;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
@ -407,6 +411,8 @@ class Json_schema_unique_items : public Json_schema_keyword
{
private:
bool is_unique;
json_engine_t temp_je_arg;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,

View file

@ -59,7 +59,9 @@ uchar* get_key_name(const char *key_name, size_t *length,
}
void json_get_normalized_string(json_engine_t *je, String *res,
int *error, MEM_ROOT *current_mem_root)
int *error, MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
char *val_begin= (char*)je->value, *val_end= NULL;
String val("",0,je->s.cs);
@ -83,7 +85,7 @@ void json_get_normalized_string(json_engine_t *je, String *res,
je->value_type == JSON_VALUE_OBJECT)
{
if (json_normalize(&a_res, (const char*)val.ptr(),
val_end-val_begin, je->s.cs, current_mem_root))
val_end-val_begin, je->s.cs, current_mem_root, temp_je, stack))
goto error;
}
else if(je->value_type == JSON_VALUE_STRING)

View file

@ -26,5 +26,7 @@ bool json_assign_type(uint *curr_type, json_engine_t *je);
uchar* get_key_name(const char *key_name, size_t *length,
my_bool /* unused */);
void json_get_normalized_string(json_engine_t *je, String *res,
int *error, MEM_ROOT *current_mem_root);
int *error, MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack);
#endif

View file

@ -188,6 +188,11 @@ class ha_json_table: public handler
String *m_js; // The JSON document we're reading
String m_tmps; // Buffer for the above
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY array_counters;
MEM_ROOT current_mem_root;
bool mem_root_inited;
int fill_column_values(THD *thd, uchar * buf, uchar *pos);
public:
@ -205,6 +210,8 @@ public:
/* See ha_json_table::position for format definition */
ref_length= m_jt->m_columns.elements * 4;
mem_root_inited= false;
}
~ha_json_table() {}
handler *clone(const char *name, MEM_ROOT *mem_root) override { return NULL; }
@ -251,6 +258,12 @@ public:
buf->length(0);
return TRUE;
}
int ha_rnd_end()
{
if (mem_root_inited)
free_root(&current_mem_root, MYF(0));
DBUG_RETURN(handler::ha_rnd_end());
}
};
@ -358,6 +371,17 @@ int ha_json_table::rnd_init(bool scan)
(const uchar *) m_js->ptr(), (const uchar *) m_js->end());
}
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_inited= true;
mem_root_dynamic_array_init(current_thd->mem_root, PSI_NOT_INSTRUMENTED,
&array_counters, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_thd->mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
DBUG_RETURN(0);
}
@ -428,13 +452,13 @@ void Json_table_nested_path::init_json_engine()
{
mem_root_dynamic_array_init(current_thd->mem_root, PSI_NOT_INSTRUMENTED,
&m_engine.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_thd->mem_root, PSI_NOT_INSTRUMENTED,
&m_cur_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_thd->mem_root, PSI_NOT_INSTRUMENTED,
&m_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
@ -491,19 +515,6 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
my_ptrdiff_t ptrdiff= buf - table->record[0];
Abort_on_warning_instant_set ao_set(table->in_use, FALSE);
enum_check_fields cf_orig= table->in_use->count_cuted_fields;
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY array_counters;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&array_counters, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
table->in_use->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
@ -652,7 +663,6 @@ cont_loop:
pos+= 4;
}
free_root(&current_mem_root, MYF(0));
dbug_tmp_restore_column_map(&table->write_set, orig_map);
thd->pop_internal_handler();
thd->count_cuted_fields= cf_orig;
@ -927,7 +937,7 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
mem_root_dynamic_array_init(thd->mem_root, PSI_NOT_INSTRUMENTED,
&m_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (json_path_setup(&m_path, thd->variables.collation_connection,
(const uchar *) path.str, (const uchar *)(path.str + path.length)))
{
@ -955,7 +965,7 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
{
mem_root_dynamic_array_init(thd->mem_root, PSI_NOT_INSTRUMENTED,
&m_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (cl.is_empty() || cl.is_contextually_typed_collate_default())
return set(thd, ctype, path, nullptr);
@ -1035,7 +1045,7 @@ int Json_table_nested_path::set_path(THD *thd, const LEX_CSTRING &path)
{
mem_root_dynamic_array_init(thd->mem_root, PSI_NOT_INSTRUMENTED,
&m_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (json_path_setup(&m_path, thd->variables.collation_connection,
(const uchar *) path.str, (const uchar *)(path.str + path.length)))

View file

@ -759,7 +759,7 @@ bool Histogram_json_hb::parse(MEM_ROOT *mem_root, const char *db_name,
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
json_scan_start(&je, &my_charset_utf8mb4_bin,
(const uchar*)hist_data,

View file

@ -88,6 +88,7 @@ class Histogram_json_hb final : public Histogram_base
std::vector<Bucket> buckets;
std::string last_bucket_end_endp;
json_engine_t je;
public:
static constexpr const char* JSON_NAME="histogram_hb";

View file

@ -1807,7 +1807,7 @@ class User_table_json: public User_table
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
String str, *res= m_table->field[2]->val_str(&str);
if (!res || !res->length())

View file

@ -2015,81 +2015,97 @@ err_return:
}
enum json_types json_type_int(json_engine_t *tmp,
const char *js, const char *js_end,
const char **value, int *value_len)
{
enum json_types return_value;
json_scan_start(tmp, &my_charset_utf8mb4_bin,(const uchar *) js,
(const uchar *) js_end);
return_value= smart_read_value(tmp, value, value_len);
return return_value;
}
enum json_types json_type(const char *js, const char *js_end,
const char **value, int *value_len)
{
json_engine_t je;
MEM_ROOT current_mem_root;
enum json_types return_value;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
(const uchar *) js_end);
return_value= smart_read_value(&je, value, value_len);
return_value= json_type_int(&je, js, js_end, value, value_len);
free_root(&current_mem_root, MYF(0));
return return_value;
}
enum json_types json_get_array_item(const char *js, const char *js_end,
int n_item,
const char **value, int *value_len)
enum json_types json_get_array_item_int(json_engine_t *je, const char *js,
const char *js_end, int n_item,
const char **value, int *value_len)
{
json_engine_t je;
int c_item= 0;
MEM_ROOT current_mem_root;
enum json_types return_value;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
json_scan_start(je, &my_charset_utf8mb4_bin,(const uchar *) js,
(const uchar *) js_end);
if (json_read_value(&je) ||
je.value_type != JSON_VALUE_ARRAY)
if (json_read_value(je) ||
je->value_type != JSON_VALUE_ARRAY)
goto err_return;
while (!json_scan_next(&je))
while (!json_scan_next(je))
{
switch (je.state)
switch (je->state)
{
case JST_VALUE:
if (c_item == n_item)
{
return_value= smart_read_value(&je, value, value_len);
free_root(&current_mem_root, MYF(0));
return return_value;
}
if (json_skip_key(&je))
return smart_read_value(je, value, value_len);
if (json_skip_key(je))
goto err_return;
c_item++;
break;
case JST_ARRAY_END:
*value= (const char *) (je.s.c_str - je.sav_c_len);
*value= (const char *) (je->s.c_str - je->sav_c_len);
*value_len= c_item;
free_root(&current_mem_root, MYF(0));
return JSV_NOTHING;
}
}
err_return:
free_root(&current_mem_root, MYF(0));
return JSV_BAD_JSON;
}
enum json_types json_get_array_item(const char *js, const char *js_end, int n_item,
const char **value, int *value_len)
{
json_engine_t je;
enum json_types return_value;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
return_value= json_get_array_item_int(&je, js, js_end, n_item, value, value_len);
free_root(&current_mem_root, MYF(0));
return return_value;
}
/** Simple json lookup for a value by the key.
@ -2109,16 +2125,57 @@ err_return:
or not JSON object.
@retval JSV_NOTHING - no such key found.
*/
enum json_types json_get_object_key(const char *js, const char *js_end,
const char *key,
const char **value, int *value_len)
enum json_types json_get_object_key_int(json_engine_t *je, const char *js,
const char *js_end, const char *key,
const char **value, int *value_len)
{
const char *key_end= key + strlen(key);
json_engine_t je;
const char *key_end= key + strlen(key);
json_string_t key_name;
int n_keys= 0;
MEM_ROOT current_mem_root;
json_string_set_cs(&key_name, &my_charset_utf8mb4_bin);
json_scan_start(je, &my_charset_utf8mb4_bin,(const uchar *) js,
(const uchar *) js_end);
if (json_read_value(je) ||
je->value_type != JSON_VALUE_OBJECT)
goto err_return;
while (!json_scan_next(je))
{
switch (je->state)
{
case JST_KEY:
n_keys++;
json_string_set_str(&key_name, (const uchar *) key,
(const uchar *) key_end);
if (json_key_matches(je, &key_name))
return smart_read_value(je, value, value_len);
if (json_skip_key(je))
goto err_return;
break;
case JST_OBJ_END:
*value= (const char *) (je->s.c_str - je->sav_c_len);
*value_len= n_keys;
return JSV_NOTHING;
}
}
err_return:
return JSV_BAD_JSON;
}
enum json_types json_get_object_key(const char *js, const char *js_end,
const char *key, const char **value,
int *value_len)
{
json_engine_t je;
enum json_types return_value;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
@ -2126,47 +2183,12 @@ enum json_types json_get_object_key(const char *js, const char *js_end,
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
return_value= json_get_object_key_int(&je, js, js_end, key, value, value_len);
json_string_set_cs(&key_name, &my_charset_utf8mb4_bin);
json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
(const uchar *) js_end);
if (json_read_value(&je) ||
je.value_type != JSON_VALUE_OBJECT)
goto err_return;
while (!json_scan_next(&je))
{
switch (je.state)
{
case JST_KEY:
n_keys++;
json_string_set_str(&key_name, (const uchar *) key,
(const uchar *) key_end);
if (json_key_matches(&je, &key_name))
{
return_value= smart_read_value(&je, value, value_len);
free_root(&current_mem_root, MYF(0));
return return_value;
}
if (json_skip_key(&je))
goto err_return;
break;
case JST_OBJ_END:
*value= (const char *) (je.s.c_str - je.sav_c_len);
*value_len= n_keys;
free_root(&current_mem_root, MYF(0));
return JSV_NOTHING;
}
}
err_return:
free_root(&current_mem_root, MYF(0));
return JSV_BAD_JSON;
return return_value;
}
@ -2210,55 +2232,46 @@ int json_valid(const char *js, size_t js_len, CHARSET_INFO *cs, json_engine_t *j
if no such key found *key_start is set to NULL.
*/
int json_locate_key(const char *js, const char *js_end,
int json_locate_key(json_engine_t *je, const char *js, const char *js_end,
const char *kname,
const char **key_start, const char **key_end,
int *comma_pos)
{
const char *kname_end= kname + strlen(kname);
json_engine_t je;
json_string_t key_name;
int t_next, c_len, match_result;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
json_string_set_cs(&key_name, &my_charset_utf8mb4_bin);
json_scan_start(&je, &my_charset_utf8mb4_bin,(const uchar *) js,
json_scan_start(je, &my_charset_utf8mb4_bin,(const uchar *) js,
(const uchar *) js_end);
if (json_read_value(&je) ||
je.value_type != JSON_VALUE_OBJECT)
if (json_read_value(je) ||
je->value_type != JSON_VALUE_OBJECT)
goto err_return;
*key_start= (const char *) je.s.c_str;
*key_start= (const char *) je->s.c_str;
*comma_pos= 0;
while (!json_scan_next(&je))
while (!json_scan_next(je))
{
switch (je.state)
switch (je->state)
{
case JST_KEY:
json_string_set_str(&key_name, (const uchar *) kname,
(const uchar *) kname_end);
match_result= json_key_matches(&je, &key_name);
if (json_skip_key(&je))
match_result= json_key_matches(je, &key_name);
if (json_skip_key(je))
goto err_return;
get_first_nonspace(&je.s, &t_next, &c_len);
je.s.c_str-= c_len;
get_first_nonspace(&je->s, &t_next, &c_len);
je->s.c_str-= c_len;
if (match_result)
{
*key_end= (const char *) je.s.c_str;
*key_end= (const char *) je->s.c_str;
if (*comma_pos == 1)
{
free_root(&current_mem_root, MYF(0));
return 0;
}
@ -2273,23 +2286,20 @@ int json_locate_key(const char *js, const char *js_end,
*comma_pos= 0;
else
goto err_return;
free_root(&current_mem_root, MYF(0));
return 0;
}
*key_start= (const char *) je.s.c_str;
*key_start= (const char *) je->s.c_str;
*comma_pos= 1;
break;
case JST_OBJ_END:
*key_start= NULL;
free_root(&current_mem_root, MYF(0));
return 0;
}
}
err_return:
free_root(&current_mem_root, MYF(0));
return 1;
}

View file

@ -646,21 +646,15 @@ json_norm_append_to_object(struct json_norm_value *val,
static int
json_norm_parse(struct json_norm_value *root, json_engine_t *je, MEM_ROOT *current_mem_root)
json_norm_parse(struct json_norm_value *root, json_engine_t *je, MEM_ROOT *current_mem_root, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
size_t current = 0;
MEM_ROOT_DYNAMIC_ARRAY stack;
int err = 0;
DYNAMIC_STRING key;
struct json_norm_value* root_ptr = root;
// Initialize the dynamic array to hold pointers to json_norm_value
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&stack, sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
// Set the root pointer in the stack
mem_root_dynamic_array_set_val(&stack, &root_ptr, current);
mem_root_dynamic_array_set_val(stack, &root_ptr, current);
err = init_dynamic_string(&key, NULL, 0, 0);
if (err)
@ -677,7 +671,7 @@ json_norm_parse(struct json_norm_value *root, json_engine_t *je, MEM_ROOT *curre
const uchar *key_end;
struct json_norm_value* new_val_ptr= NULL;
struct json_norm_value** curr_val_ptr =
(struct json_norm_value**)mem_root_dynamic_array_get_val(&stack, current);
(struct json_norm_value**)mem_root_dynamic_array_get_val(stack, current);
struct json_norm_value* curr_val = *curr_val_ptr;
DBUG_ASSERT(curr_val->type == JSON_VALUE_OBJECT);
@ -706,14 +700,14 @@ json_norm_parse(struct json_norm_value *root, json_engine_t *je, MEM_ROOT *curre
struct json_norm_kv* kv;
kv = json_norm_object_get_last_element(&curr_val->value.object);
new_val_ptr = &kv->value;
mem_root_dynamic_array_set_val(&stack, &new_val_ptr, ++current);
mem_root_dynamic_array_set_val(stack, &new_val_ptr, ++current);
}
break;
}
case JST_VALUE:
{
struct json_norm_value** curr_val_ptr =
(struct json_norm_value**)mem_root_dynamic_array_get_val(&stack, current);
(struct json_norm_value**)mem_root_dynamic_array_get_val(stack, current);
struct json_norm_value* curr_val = *curr_val_ptr;
struct json_norm_array* current_arr = &curr_val->value.array;
@ -732,7 +726,7 @@ json_norm_parse(struct json_norm_value *root, json_engine_t *je, MEM_ROOT *curre
{
struct json_norm_value* element =
json_norm_array_get_last_element(current_arr);
mem_root_dynamic_array_set_val(&stack, &element, ++current);
mem_root_dynamic_array_set_val(stack, &element, ++current);
}
break;
}
@ -763,33 +757,28 @@ json_norm_parse_end:
static int
json_norm_build(struct json_norm_value *root,
const char *s, size_t size, CHARSET_INFO *cs,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int err= 0;
json_engine_t je;
DBUG_ASSERT(s);
memset(&je, 0x00, sizeof(je));
memset(root, 0x00, sizeof(struct json_norm_value));
root->type= JSON_VALUE_UNINITIALIZED;
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
err= json_scan_start(&je, cs, (const uchar *)s, (const uchar *)(s + size));
if (json_read_value(&je))
err= json_scan_start(je, cs, (const uchar *)s, (const uchar *)(s + size));
if (json_read_value(je))
{
return err;
}
err= json_norm_value_init(root, &je);
err= json_norm_value_init(root, je);
if (root->type == JSON_VALUE_OBJECT ||
root->type == JSON_VALUE_ARRAY)
{
err= json_norm_parse(root, &je, current_mem_root);
err= json_norm_parse(root, je, current_mem_root, stack);
if (err)
{
return err;
@ -803,7 +792,9 @@ json_norm_build(struct json_norm_value *root,
int
json_normalize(DYNAMIC_STRING *result,
const char *s, size_t size, CHARSET_INFO *cs,
MEM_ROOT *current_mem_root)
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int err= 0;
uint convert_err= 0;
@ -811,11 +802,6 @@ json_normalize(DYNAMIC_STRING *result,
char *s_utf8= NULL;
size_t in_size;
const char *in;
json_engine_t temp_je;
mem_root_dynamic_array_init(current_mem_root, PSI_NOT_INSTRUMENTED,
&temp_je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
DBUG_ASSERT(result);
@ -851,14 +837,14 @@ json_normalize(DYNAMIC_STRING *result,
}
if (!(json_valid(in, in_size, &my_charset_utf8mb4_bin, &temp_je) == 0))
if (!(json_valid(in, in_size, &my_charset_utf8mb4_bin, temp_je) == 0))
{
err= 1;
goto json_normalize_end;
}
err= json_norm_build(&root, in, in_size,
&my_charset_utf8mb4_bin, current_mem_root);
&my_charset_utf8mb4_bin, current_mem_root, temp_je, stack);
if (err)
goto json_normalize_end;

View file

@ -38,40 +38,26 @@ struct st_parse_result
};
static void parse_json(const uchar *j, struct st_parse_result *result)
static void parse_json(const uchar *j, struct st_parse_result *result, json_engine_t *je)
{
json_engine_t je;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
bzero(result, sizeof(*result));
if (json_scan_start(&je, ci, s_e(j)))
{
free_root(&current_mem_root, MYF(0));
if (json_scan_start(je, ci, s_e(j)))
return;
}
do
{
result->n_steps++;
switch (je.state)
switch (je->state)
{
case JST_KEY:
result->n_keys++;
while (json_read_keyname_chr(&je) == 0)
while (json_read_keyname_chr(je) == 0)
{
result->keyname_csum^= je.s.c_next;
result->keyname_csum^= je->s.c_next;
}
if (je.s.error)
if (je->s.error)
{
free_root(&current_mem_root, MYF(0));
return;
}
break;
@ -87,10 +73,9 @@ static void parse_json(const uchar *j, struct st_parse_result *result)
default:
break;
};
} while (json_scan_next(&je) == 0);
} while (json_scan_next(je) == 0);
free_root(&current_mem_root, MYF(0));
result->error= je.s.error;
result->error= je->s.error;
}
@ -104,17 +89,17 @@ static const uchar *js3= (const uchar *) "{\"key1\":{\"ikey1\":321},"
Test json_lib functions to parse JSON.
*/
static void
test_json_parsing()
test_json_parsing(json_engine_t *je)
{
struct st_parse_result r;
parse_json(js0, &r);
parse_json(js0, &r, je);
ok(r.n_steps == 1 && r.n_values == 1, "simple value");
parse_json(js1, &r);
parse_json(js1, &r, je);
ok(r.n_steps == 5 && r.n_values == 3 && r.n_arrays == 1, "array");
parse_json(js2, &r);
parse_json(js2, &r, je);
ok(r.n_steps == 5 && r.n_keys == 2 && r.n_objects == 1 && r.keyname_csum == 3,
"object");
parse_json(js3, &r);
parse_json(js3, &r, je);
ok(r.n_steps == 12 && r.n_keys == 3 && r.n_objects == 2 &&
r.n_arrays == 1 && r.keyname_csum == 44,
"complex json");
@ -126,23 +111,15 @@ static const uchar *p0= (const uchar *) "$.key1[12].*[*]";
Test json_lib functions to parse JSON path.
*/
static void
test_path_parsing()
test_path_parsing(json_path_t *p)
{
json_path_t p;
MEM_ROOT current_mem_root;
json_path_step_t *initial_step= NULL;
initial_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&p->steps, 0));
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
initial_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&p.steps, 0));
if (json_path_setup(&p, ci, s_e(p0)))
if (json_path_setup(p, ci, s_e(p0)))
goto error;
ok(p.last_step_idx == 4 &&
ok(p->last_step_idx == 4 &&
(initial_step+0)->type == JSON_PATH_ARRAY_WILD &&
(initial_step+1)->type == JSON_PATH_KEY &&
(initial_step+2)->type == JSON_PATH_ARRAY && (initial_step+2)->n_item == 12 &&
@ -151,7 +128,6 @@ test_path_parsing()
"path");
error:
free_root(&current_mem_root, MYF(0));
return;
}
@ -164,49 +140,33 @@ static const uchar *fp0= (const uchar *) "$[*].k1";
Test json_lib functions to search through JSON.
*/
static void
test_search()
test_search(MEM_ROOT_DYNAMIC_ARRAY* array_counters, json_engine_t *je, json_path_t *p)
{
json_engine_t je;
json_path_t p;
MEM_ROOT_DYNAMIC_ARRAY *cur_step;
int n_matches, scal_values;
json_path_step_t *tmp_ptr= NULL;
MEM_ROOT current_mem_root;
MEM_ROOT_DYNAMIC_ARRAY array_counters;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&array_counters, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, 0, MYF(0));
if (json_scan_start(&je, ci, s_e(fj0)) ||
json_path_setup(&p, ci, s_e(fp0)))
if (json_scan_start(je, ci, s_e(fj0)) ||
json_path_setup(p, ci, s_e(fp0)))
goto end;
cur_step= &p.steps;
cur_step= &p->steps;
n_matches= scal_values= 0;
tmp_ptr= (json_path_step_t*)mem_root_dynamic_array_get_val(cur_step, 0);
while (json_find_path(&je, &p, &tmp_ptr, &array_counters) == 0)
while (json_find_path(je, p, &tmp_ptr, array_counters) == 0)
{
n_matches++;
if (json_read_value(&je))
if (json_read_value(je))
goto end;
if (json_value_scalar(&je))
if (json_value_scalar(je))
{
scal_values++;
if (json_scan_next(&je))
if (json_scan_next(je))
goto end;
}
else
{
if (json_skip_level(&je) || json_scan_next(&je))
if (json_skip_level(je) || json_scan_next(je))
goto end;
}
@ -215,21 +175,40 @@ test_search()
ok(n_matches == 3, "search");
end:
free_root(&current_mem_root, MYF(0));
return;
}
int main()
{
MEM_ROOT current_mem_root;
MEM_ROOT_DYNAMIC_ARRAY array_counters;
json_engine_t je;
json_path_t p;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&array_counters, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&p.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
ci= &my_charset_utf8mb3_general_ci;
plan(6);
diag("Testing json_lib functions.");
test_json_parsing();
test_path_parsing();
test_search();
test_json_parsing(&je);
test_path_parsing(&p);
test_search(&array_counters, &je, &p);
free_root(&current_mem_root, MYF(0));
return exit_status();
}

View file

@ -21,7 +21,7 @@
static void
check_json_normalize(const char *in, const char *expected)
check_json_normalize(const char *in, const char *expected, json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int err;
DYNAMIC_STRING result;
@ -30,10 +30,8 @@ check_json_normalize(const char *in, const char *expected)
CHARSET_INFO *cs= &my_charset_utf8mb4_general_ci;
init_dynamic_string(&result, NULL, 0, 0);
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
err= json_normalize(&result, in, strlen(in), cs, &current_mem_root);
err= json_normalize(&result, in, strlen(in), cs, &current_mem_root, je, stack);
ok(err == 0, "normalize err?");
@ -42,12 +40,11 @@ check_json_normalize(const char *in, const char *expected)
expected, in, result.str);
dynstr_free(&result);
free_root(&current_mem_root, MYF(0));
}
static void
test_json_normalize_invalid(void)
test_json_normalize_invalid(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
DYNAMIC_STRING result;
MEM_ROOT current_mem_root;
@ -58,31 +55,29 @@ test_json_normalize_invalid(void)
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
init_dynamic_string(&result, NULL, 0, 0);
ok(json_normalize(&result, STRING_WITH_LEN(""), cs, &current_mem_root) != 0,
ok(json_normalize(&result, STRING_WITH_LEN(""), cs, &current_mem_root, je, stack) != 0,
"expected normalized error");
dynstr_free(&result);
init_dynamic_string(&result, NULL, 0, 0);
ok(json_normalize(&result, STRING_WITH_LEN("["), cs, &current_mem_root) != 0,
ok(json_normalize(&result, STRING_WITH_LEN("["), cs, &current_mem_root, je, stack) != 0,
"expected normalized error");
dynstr_free(&result);
init_dynamic_string(&result, NULL, 0, 0);
ok(json_normalize(&result, STRING_WITH_LEN("}"), cs, &current_mem_root) != 0,
ok(json_normalize(&result, STRING_WITH_LEN("}"), cs, &current_mem_root, je, stack) != 0,
"expected normalized error");
dynstr_free(&result);
init_dynamic_string(&result, NULL, 0, 0);
ok(json_normalize(&result, NULL, 0, cs, &current_mem_root) != 0,
ok(json_normalize(&result, NULL, 0, cs, &current_mem_root, je, stack) != 0,
"expected normalized error");
dynstr_free(&result);
free_root(&current_mem_root, MYF(0));
}
static void
test_json_normalize_single_kv(void)
test_json_normalize_single_kv(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
const char *in= ""
"{\n"
@ -90,12 +85,12 @@ test_json_normalize_single_kv(void)
"}\n";
const char *expected= "{\"foo\":\"value\"}";
check_json_normalize(in, expected);
check_json_normalize(in, expected, je, stack);
}
static void
test_json_normalize_multi_kv(void)
test_json_normalize_multi_kv(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
const char *in= ""
"{\n"
@ -104,42 +99,42 @@ test_json_normalize_multi_kv(void)
"}\n";
const char *expected= "{\"bar\":\"baz\",\"foo\":\"value\"}";
check_json_normalize(in, expected);
check_json_normalize(in, expected, je, stack);
}
static void
test_json_normalize_array(void)
test_json_normalize_array(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
const char *in= "[ \"a\", \"b\", true, false, null ]";
const char *expected= "[\"a\",\"b\",true,false,null]";
check_json_normalize(in, expected);
check_json_normalize(in, expected, je, stack);
}
static void
test_json_normalize_values(void)
test_json_normalize_values(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
check_json_normalize("\"foo\"", "\"foo\"");
check_json_normalize("true", "true");
check_json_normalize("false", "false");
check_json_normalize("null", "null");
check_json_normalize("\"\"", "\"\"");
check_json_normalize("{}", "{}");
check_json_normalize("[]", "[]");
check_json_normalize("5", "5.0E0");
check_json_normalize("5.1", "5.1E0");
check_json_normalize("-5.1", "-5.1E0");
check_json_normalize("12345.67890", "1.23456789E4");
check_json_normalize("2.99792458e8", "2.99792458E8");
check_json_normalize("6.02214076e23", "6.02214076E23");
check_json_normalize("6.62607015e-34", "6.62607015E-34");
check_json_normalize("-6.62607015e-34", "-6.62607015E-34");
check_json_normalize("\"foo\"", "\"foo\"", je, stack);
check_json_normalize("true", "true", je, stack);
check_json_normalize("false", "false", je, stack);
check_json_normalize("null", "null", je, stack);
check_json_normalize("\"\"", "\"\"", je, stack);
check_json_normalize("{}", "{}", je, stack);
check_json_normalize("[]", "[]", je, stack);
check_json_normalize("5", "5.0E0", je, stack);
check_json_normalize("5.1", "5.1E0", je, stack);
check_json_normalize("-5.1", "-5.1E0", je, stack);
check_json_normalize("12345.67890", "1.23456789E4", je, stack);
check_json_normalize("2.99792458e8", "2.99792458E8", je, stack);
check_json_normalize("6.02214076e23", "6.02214076E23", je, stack);
check_json_normalize("6.62607015e-34", "6.62607015E-34", je, stack);
check_json_normalize("-6.62607015e-34", "-6.62607015E-34", je, stack);
}
static void
test_json_normalize_nested_objects(void)
test_json_normalize_nested_objects(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
const char *in = ""
"{\n"
@ -150,12 +145,12 @@ test_json_normalize_nested_objects(void)
const char *expected= "{\"foo\":{\"value\":true},"
"\"wiz\":{\"alpha\":false,\"bang\":\"a\"}}";
check_json_normalize(in, expected);
check_json_normalize(in, expected, je, stack);
}
static void
test_json_normalize_nested_arrays(void)
test_json_normalize_nested_arrays(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
const char *in = ""
"[\n"
@ -164,12 +159,12 @@ test_json_normalize_nested_arrays(void)
"]";
const char *expected= "[\"wiz\",[\"bang\",\"alpha\"]]";
check_json_normalize(in, expected);
check_json_normalize(in, expected, je, stack);
}
static void
test_json_normalize_nested_deep(void)
test_json_normalize_nested_deep(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
const char *in = ""
"{\n"
@ -194,7 +189,7 @@ test_json_normalize_nested_deep(void)
"[-1.2E0,\"w\",\"x\"]"
"]"
"}";
check_json_normalize(in, expected);
check_json_normalize(in, expected, je, stack);
}
@ -204,7 +199,7 @@ json_normalize_number(DYNAMIC_STRING *out, const char *str, size_t str_len);
static void
test_json_normalize_non_utf8(void)
test_json_normalize_non_utf8(json_engine_t *je, MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int err;
const char utf8[]= { 0x22, 0xC3, 0x8A, 0x22, 0x00 };
@ -217,18 +212,16 @@ test_json_normalize_non_utf8(void)
init_dynamic_string(&result, NULL, 0, 0);
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
err= json_normalize(&result, utf8, strlen(utf8), cs_utf8, &current_mem_root);
err= json_normalize(&result, utf8, strlen(utf8), cs_utf8, &current_mem_root, je, stack);
ok(err == 0, "normalize err?");
ok((strcmp(utf8, result.str) == 0), "utf8 round trip");
dynstr_free(&result);
init_dynamic_string(&result, NULL, 0, 0);
err= json_normalize(&result, latin, strlen(latin), cs_latin, &current_mem_root);
err= json_normalize(&result, latin, strlen(latin), cs_latin, &current_mem_root, je, stack);
ok(err == 0, "normalize err?");
ok((strcmp(utf8, result.str) == 0), "latin to utf8 round trip");
dynstr_free(&result);
free_root(&current_mem_root, MYF(0));
}
@ -258,6 +251,20 @@ check_number_normalize(const char *in, const char *expected)
int
main(void)
{
MEM_ROOT current_mem_root;
MEM_ROOT_DYNAMIC_ARRAY stack;
json_engine_t je;
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&stack,
sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
plan(88);
diag("Testing json_normalization.");
@ -281,15 +288,17 @@ main(void)
check_number_normalize("0000123.456000000e-9", "1.23456E-7");
check_number_normalize("0000123.456000000e+9", "1.23456E11");
test_json_normalize_invalid();
test_json_normalize_values();
test_json_normalize_single_kv();
test_json_normalize_multi_kv();
test_json_normalize_array();
test_json_normalize_nested_objects();
test_json_normalize_nested_arrays();
test_json_normalize_nested_deep();
test_json_normalize_non_utf8();
test_json_normalize_invalid(&je, &stack);
test_json_normalize_values(&je, &stack);
test_json_normalize_single_kv(&je, &stack);
test_json_normalize_multi_kv(&je, &stack);
test_json_normalize_array(&je, &stack);
test_json_normalize_nested_objects(&je, &stack);
test_json_normalize_nested_arrays(&je, &stack);
test_json_normalize_nested_deep(&je, &stack);
test_json_normalize_non_utf8(&je, &stack);
free_root(&current_mem_root, MYF(0));
return exit_status();
}

View file

@ -58,12 +58,12 @@ void do_json_ar(int n, int type, const char *value)
"%i: type=%u keys=%u end=\"%s\"", n, value_type, value_len, value_start);
}
void do_json_locate(const char *json, const char *key, int from, int to, int cp)
void do_json_locate(json_engine_t *je, const char *json, const char *key, int from, int to, int cp)
{
const char *key_start, *key_end;
int res, comma_pos;
res= json_locate_key(json, json + strlen(json),
res= json_locate_key(je, json, json + strlen(json),
key, &key_start, &key_end, &comma_pos);
if (key_start)
ok(res == 0 && key_start - json == from && key_end - json == to &&
@ -75,8 +75,18 @@ void do_json_locate(const char *json, const char *key, int from, int to, int cp)
int main()
{
json_engine_t je;
MEM_ROOT current_mem_root;
plan(18);
init_alloc_root(PSI_NOT_INSTRUMENTED, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_NOT_INSTRUMENTED,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
diag("%s", json);
do_json("int", 4, "1");
do_json("str", 3, "foo bar");
@ -90,14 +100,16 @@ int main()
do_json_ar(3, 6, "false");
do_json_ar(4, 0, "1234");
do_json_locate(json, "bool", 50, 63, 1);
do_json_locate(json, "int", 1, 9, 2);
do_json_locate(json, "array", 24, 50, 1);
do_json_locate(json_w, "bool", 43, 61, 1);
do_json_locate(json_w, "int", 1, 12, 2);
do_json_locate(json_w, "array", 11, 43, 1);
do_json_locate(json_w, "c", -1, -1, -1);
do_json_locate(json_1, "str", 1, 22, 0);
do_json_locate(&je, json, "bool", 50, 63, 1);
do_json_locate(&je, json, "int", 1, 9, 2);
do_json_locate(&je, json, "array", 24, 50, 1);
do_json_locate(&je, json_w, "bool", 43, 61, 1);
do_json_locate(&je, json_w, "int", 1, 12, 2);
do_json_locate(&je, json_w, "array", 11, 43, 1);
do_json_locate(&je, json_w, "c", -1, -1, -1);
do_json_locate(&je, json_1, "str", 1, 22, 0);
free_root(&current_mem_root, MYF(0));
return exit_status();
}