diff --git a/include/json_lib.h b/include/json_lib.h index 7746cd63ee0..d18c3e50fb1 100644 --- a/include/json_lib.h +++ b/include/json_lib.h @@ -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); diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index 415a6070aa8..9d29391b5e1 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -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; diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 6a64239d520..bc43eeeb066 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -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'; diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 80abc21f1b6..681e6050bf3 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -124,7 +124,7 @@ bool Item_func_geometry_from_json::fix_length_and_dec(THD *thd) mem_root_dynamic_array_init(¤t_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); } diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 48279bef3d5..1a5e388b315 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -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(¤t_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(¤t_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(¤t_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(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &temp_je.stack, sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_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(), ¤t_mem_root)) + a->charset(), ¤t_mem_root, &temp_je, &stack)) { null_value= 1; goto end; } if (json_normalize(&b_res, b->ptr(), b->length(), - b->charset(), ¤t_mem_root)) + b->charset(), ¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_mem_root); return FALSE; @@ -854,7 +862,7 @@ bool Item_func_json_query::fix_length_and_dec(THD *thd) mem_root_dynamic_array_init(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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, ¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(), ¤t_mem_root)) + raw_json->charset(), ¤t_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(¤t_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(¤t_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(¤t_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, ¤t_mem_root); + result= check_overlaps(&je, &ve, false, ¤t_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(¤t_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(¤t_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(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &temp_je.stack, sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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(¤t_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, ¤t_mem_root)) + if (get_intersect_between_arrays(str, &je2, items, ¤t_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, ¤t_mem_root)) + create_hash(je1, &items, hash_inited, &hash_root, ¤t_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(¤t_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(¤t_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(¤t_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(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &temp_je.stack, sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_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(¤t_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(¤t_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(¤t_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(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &temp_je2.stack, sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_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, ¤t_mem_root)) + create_hash(&temp_je, &items, hash_inited, &hash_root, ¤t_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(¤t_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; } diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index 34fb77f570c..3fbb3043a3e 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -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): diff --git a/sql/json_schema.cc b/sql/json_schema.cc index 00e39ecc7b3..3ea2a0bdb76 100644 --- a/sql/json_schema.cc +++ b/sql/json_schema.cc @@ -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 *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) { diff --git a/sql/json_schema.h b/sql/json_schema.h index a83e10731de..af73ef4381a 100644 --- a/sql/json_schema.h +++ b/sql/json_schema.h @@ -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, diff --git a/sql/json_schema_helper.cc b/sql/json_schema_helper.cc index 350ab4ffebe..ea258e8e5d6 100644 --- a/sql/json_schema_helper.cc +++ b/sql/json_schema_helper.cc @@ -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) diff --git a/sql/json_schema_helper.h b/sql/json_schema_helper.h index 9e1ba850f72..912a942d5b2 100644 --- a/sql/json_schema_helper.h +++ b/sql/json_schema_helper.h @@ -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 diff --git a/sql/json_table.cc b/sql/json_table.cc index 09baf8827ef..da07a547035 100644 --- a/sql/json_table.cc +++ b/sql/json_table.cc @@ -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(¤t_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, ¤t_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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - - mem_root_dynamic_array_init(¤t_mem_root, PSI_NOT_INSTRUMENTED, - &array_counters, sizeof(int), NULL, - JSON_DEPTH_DEFAULT, 0, MYF(0)); - mem_root_dynamic_array_init(¤t_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(¤t_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))) diff --git a/sql/opt_histogram_json.cc b/sql/opt_histogram_json.cc index 2b51c4adfef..8742c7758c6 100644 --- a/sql/opt_histogram_json.cc +++ b/sql/opt_histogram_json.cc @@ -759,7 +759,7 @@ bool Histogram_json_hb::parse(MEM_ROOT *mem_root, const char *db_name, mem_root_dynamic_array_init(¤t_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, diff --git a/sql/opt_histogram_json.h b/sql/opt_histogram_json.h index 248467928fd..da7a801d58a 100644 --- a/sql/opt_histogram_json.h +++ b/sql/opt_histogram_json.h @@ -88,6 +88,7 @@ class Histogram_json_hb final : public Histogram_base std::vector buckets; std::string last_bucket_end_endp; + json_engine_t je; public: static constexpr const char* JSON_NAME="histogram_hb"; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 520cbc2f357..04ba0120d5a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1807,7 +1807,7 @@ class User_table_json: public User_table mem_root_dynamic_array_init(¤t_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()) diff --git a/strings/json_lib.c b/strings/json_lib.c index 47639c28c97..76920dec125 100644 --- a/strings/json_lib.c +++ b/strings/json_lib.c @@ -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, ¤t_mem_root, BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); + mem_root_dynamic_array_init(¤t_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(¤t_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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - - mem_root_dynamic_array_init(¤t_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(¤t_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(¤t_mem_root, MYF(0)); return JSV_NOTHING; } } err_return: - free_root(¤t_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, ¤t_mem_root, + BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); + + mem_root_dynamic_array_init(¤t_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(¤t_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, ¤t_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(¤t_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(¤t_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(¤t_mem_root, MYF(0)); - return JSV_NOTHING; - } - } - -err_return: free_root(¤t_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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - - mem_root_dynamic_array_init(¤t_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(¤t_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(¤t_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(¤t_mem_root, MYF(0)); return 0; } } err_return: - free_root(¤t_mem_root, MYF(0)); return 1; } diff --git a/strings/json_normalize.c b/strings/json_normalize.c index 5221196dd61..4d239273a74 100644 --- a/strings/json_normalize.c +++ b/strings/json_normalize.c @@ -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; diff --git a/unittest/json_lib/json_lib-t.c b/unittest/json_lib/json_lib-t.c index 69e0c551171..b49b40988a2 100644 --- a/unittest/json_lib/json_lib-t.c +++ b/unittest/json_lib/json_lib-t.c @@ -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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - - mem_root_dynamic_array_init(¤t_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(¤t_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(¤t_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(¤t_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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - mem_root_dynamic_array_init(¤t_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(¤t_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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - - mem_root_dynamic_array_init(¤t_mem_root, PSI_NOT_INSTRUMENTED, - &array_counters, sizeof(int), NULL, - JSON_DEPTH_DEFAULT, 0, MYF(0)); - mem_root_dynamic_array_init(¤t_mem_root, PSI_NOT_INSTRUMENTED, - &je.stack, sizeof(int), NULL, - JSON_DEPTH_DEFAULT, 0, MYF(0)); - mem_root_dynamic_array_init(¤t_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(¤t_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, ¤t_mem_root, + BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); + + mem_root_dynamic_array_init(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &array_counters, sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &je.stack, sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_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(¤t_mem_root, MYF(0)); return exit_status(); } diff --git a/unittest/json_lib/json_normalize-t.c b/unittest/json_lib/json_normalize-t.c index 735b7cf69ea..376616c68d0 100644 --- a/unittest/json_lib/json_normalize-t.c +++ b/unittest/json_lib/json_normalize-t.c @@ -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, ¤t_mem_root, - BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - err= json_normalize(&result, in, strlen(in), cs, ¤t_mem_root); + err= json_normalize(&result, in, strlen(in), cs, ¤t_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(¤t_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, ¤t_mem_root) != 0, + ok(json_normalize(&result, STRING_WITH_LEN(""), cs, ¤t_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, ¤t_mem_root) != 0, + ok(json_normalize(&result, STRING_WITH_LEN("["), cs, ¤t_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, ¤t_mem_root) != 0, + ok(json_normalize(&result, STRING_WITH_LEN("}"), cs, ¤t_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, ¤t_mem_root) != 0, + ok(json_normalize(&result, NULL, 0, cs, ¤t_mem_root, je, stack) != 0, "expected normalized error"); dynstr_free(&result); - - free_root(¤t_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, ¤t_mem_root, BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); - err= json_normalize(&result, utf8, strlen(utf8), cs_utf8, ¤t_mem_root); + err= json_normalize(&result, utf8, strlen(utf8), cs_utf8, ¤t_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, ¤t_mem_root); + err= json_normalize(&result, latin, strlen(latin), cs_latin, ¤t_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(¤t_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, ¤t_mem_root, + BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); + mem_root_dynamic_array_init(¤t_mem_root, PSI_NOT_INSTRUMENTED, + &je.stack, + sizeof(int), NULL, + JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0)); + mem_root_dynamic_array_init(¤t_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(¤t_mem_root, MYF(0)); return exit_status(); } diff --git a/unittest/strings/json-t.c b/unittest/strings/json-t.c index 7c5f7957d42..f6fdc8a4c5b 100644 --- a/unittest/strings/json-t.c +++ b/unittest/strings/json-t.c @@ -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, ¤t_mem_root, + BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0)); + + mem_root_dynamic_array_init(¤t_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(¤t_mem_root, MYF(0)); return exit_status(); }