1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-32854: Make JSON_DEPTH_LIMIT unlimited

The initial hard capped limit on the depth was 32. It was implemented using
static arrays of relevant type and size 32.
Hence, to implement unlimited depth, dynamic array on mem_root was
implemented which grows by 3200 as needed. Relevant arrays were replaced
with this dynamic array.
This commit is contained in:
Rucha Deodhar
2024-02-27 19:43:51 +05:30
parent 374f30c41f
commit b8a7728963
30 changed files with 2922 additions and 885 deletions

View File

@@ -7,8 +7,27 @@
extern "C" {
#endif
#define JSON_DEPTH_LIMIT 32
#define JSON_DEPTH_DEFAULT 32
#define JSON_DEPTH_LIMIT 32 /* Still used in columnstore. */
#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,
each of average 70 elements. So this size should suffice.
*/
#define BLOCK_SIZE_JSON_DYN_ARRAY 4096
#define get_json_step(p,s) if (p->last_step_idx < (int)(p->steps.max_element)) \
s= ((json_path_step_t*)(p->steps.buffer))+p->last_step_idx; \
else \
s= (json_path_step_t*) mem_root_dynamic_array_resize_and_get_val(&p->steps, p->last_step_idx);
#define set_json_array_value_ptr(idx, max_element, dyn_arr_ptr, val) \
if ((size_t)(idx) < (max_element)) \
memcpy((dyn_arr_ptr)->buffer + (dyn_arr_ptr)->size_of_element * (idx), &(val), sizeof(val)); \
else \
mem_root_dynamic_array_resize_and_set_val((dyn_arr_ptr), &(val), (idx));
/*
When error happens, the c_next of the JSON engine contains the
character that caused the error, and the c_str is the position
@@ -28,7 +47,7 @@ enum json_errors {
JE_ESCAPING= -6, /* Error in the escaping. */
JE_DEPTH= -7, /* The limit on the JSON depth was overrun. */
JE_DEPTH= -7, /* The limit on the JSON depth was overrun. Still used in columnstore*/
};
@@ -104,8 +123,8 @@ typedef struct st_json_path_step_t
typedef struct st_json_path_t
{
json_string_t s; /* The string to be parsed. */
json_path_step_t steps[JSON_DEPTH_LIMIT]; /* Steps of the path. */
json_path_step_t *last_step; /* Points to the last step. */
MEM_ROOT_DYNAMIC_ARRAY steps; /* Steps of the path. */
int last_step_idx;
int mode_strict; /* TRUE if the path specified as 'strict' */
enum json_path_step_types types_used; /* The '|' of all step's 'type'-s */
@@ -225,8 +244,8 @@ typedef struct st_json_engine_t
const uchar *value_end; /* Points to the next character after the value. */
int value_len; /* The length of the value. Does not count quotations for */
/* string constants. */
int stack[JSON_DEPTH_LIMIT]; /* Keeps the stack of nested JSON structures. */
/* Keeps the stack of nested JSON structures. */
MEM_ROOT_DYNAMIC_ARRAY stack;
int stack_p; /* The 'stack' pointer. */
volatile uchar *killed_ptr;
} json_engine_t;
@@ -341,6 +360,13 @@ int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped);
*/
#define json_value_scalar(je) ((je)->value_type > JSON_VALUE_ARRAY)
#define report_json_error(js, je, n_param) \
report_json_error_ex(js->ptr(), je, func_name(), n_param, \
Sql_condition::WARN_LEVEL_WARN)
#define report_path_error(js, je, n_param) \
report_path_error_ex(js->ptr(), je, func_name(), n_param,\
Sql_condition::WARN_LEVEL_WARN)
/*
Look for the JSON PATH in the json string.
@@ -350,7 +376,7 @@ int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped);
initialized with the JSON string, and the json_path_t with the JSON path
appropriately. The 'p_cur_step' should point at the first
step of the path.
The 'array_counters' is the array of JSON_DEPTH_LIMIT size.
The 'array_counters' is the array of 'curr_json_depth_limit' size.
It stores the array counters of the parsed JSON.
If function returns 0, it means it found the match. The position of
the match is je->s.c_str. Then we can call the json_find_path()
@@ -360,7 +386,7 @@ int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped);
*/
int json_find_path(json_engine_t *je,
json_path_t *p, json_path_step_t **p_cur_step,
int *array_counters);
MEM_ROOT_DYNAMIC_ARRAY *array_counters);
typedef struct st_json_find_paths_t
@@ -369,7 +395,7 @@ typedef struct st_json_find_paths_t
json_path_t *paths;
uint cur_depth;
uint *path_depths;
int array_counters[JSON_DEPTH_LIMIT];
MEM_ROOT_DYNAMIC_ARRAY array_counters;
} json_find_paths_t;
@@ -431,17 +457,22 @@ int json_get_path_start(json_engine_t *je, CHARSET_INFO *i_cs,
int json_get_path_next(json_engine_t *je, json_path_t *p);
int json_path_compare(const json_path_t *a, const json_path_t *b,
enum json_value_types vt, const int* array_size_counter);
enum json_value_types vt,
MEM_ROOT_DYNAMIC_ARRAY* array_size_counter);
int json_valid(const char *js, size_t js_len, CHARSET_INFO *cs);
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);
const char *s, size_t size, CHARSET_INFO *cs,
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);
@@ -450,6 +481,8 @@ inline static int json_scan_ended(json_engine_t *j)
return (j->state == JST_ARRAY_END && j->stack_p == 0);
}
void initJsonArray(MEM_ROOT *mem_root, MEM_ROOT_DYNAMIC_ARRAY *mem_root_array, size_t size, void *buffer, myf myflag);
#ifdef __cplusplus
}
#endif

View File

@@ -89,6 +89,7 @@ C_MODE_START
#define MY_FREE_ON_ERROR 128U /* my_realloc() ; Free old ptr on error */
#define MY_DONT_OVERWRITE_FILE 2048U /* my_copy: Don't overwrite file */
#define MY_THREADSAFE 2048U /* my_seek(): lock fd mutex */
#define MY_BUFFER_NO_RESIZE 512U
#define MY_SYNC 4096U /* my_copy(): sync dst file */
#define MY_SYNC_DIR 32768U /* my_create/delete/rename: sync directory */
#define MY_THREAD_SPECIFIC 0x10000U /* my_malloc(): thread specific */
@@ -362,6 +363,17 @@ typedef struct st_dynamic_array
myf malloc_flags;
} DYNAMIC_ARRAY;
typedef struct st_mem_root_dynamic_array
{
MEM_ROOT *mem_root;
uchar *buffer;
size_t elements, max_element;
size_t alloc_increment;
size_t size_of_element;
PSI_memory_key m_psi_key;
myf malloc_flags;
} MEM_ROOT_DYNAMIC_ARRAY;
typedef struct st_dynamic_array_append
{
@@ -1176,6 +1188,74 @@ extern void thd_increment_bytes_sent(void *thd, size_t length);
extern void thd_increment_bytes_received(void *thd, size_t length);
extern void thd_increment_net_big_packet_count(void *thd, size_t length);
extern int mem_root_dynamic_array_init(MEM_ROOT *mem_root,
PSI_memory_key psi_key,
MEM_ROOT_DYNAMIC_ARRAY *array,
size_t element_size, void *init_buffer,
size_t init_alloc,
size_t alloc_increment,
myf my_flags);
int mem_root_allocate_dynamic(MEM_ROOT *mem_root,
MEM_ROOT_DYNAMIC_ARRAY *array,
size_t idx);
extern void* mem_root_dynamic_array_get_val(MEM_ROOT_DYNAMIC_ARRAY *array, size_t idx);
extern void mem_root_dynamic_array_reset(MEM_ROOT_DYNAMIC_ARRAY *array);
extern int mem_root_dynamic_array_resize_not_allowed(MEM_ROOT_DYNAMIC_ARRAY *array);
extern void mem_root_dynamic_array_copy_values(MEM_ROOT_DYNAMIC_ARRAY *dest, MEM_ROOT_DYNAMIC_ARRAY *src);
static inline int mem_root_dynamic_array_set_val(MEM_ROOT_DYNAMIC_ARRAY *array,
const void *element, size_t idx)
{
DBUG_ASSERT(idx < array->max_element);
memcpy(array->buffer+(idx * array->size_of_element), element,
array->size_of_element);
return TRUE;
}
static inline int mem_root_dynamic_array_resize_and_set_val(MEM_ROOT_DYNAMIC_ARRAY *array,
const void *element, size_t idx)
{
if (array->malloc_flags & MY_BUFFER_NO_RESIZE)
return TRUE;
if (idx >= array->max_element)
{
if (mem_root_allocate_dynamic(array->mem_root, array, idx))
return 1;
array->elements++;
}
/*
Ensure the array size has increased and the index is
now well within the array bounds.
*/
DBUG_ASSERT(idx < array->max_element);
memcpy(array->buffer+(idx * array->size_of_element), element,
array->size_of_element);
return FALSE;
}
static inline void* mem_root_dynamic_array_resize_and_get_val(MEM_ROOT_DYNAMIC_ARRAY *array, size_t idx)
{
if (array->malloc_flags & MY_BUFFER_NO_RESIZE)
return NULL;
if (idx >= array->max_element)
{
if (mem_root_allocate_dynamic(array->mem_root, array, idx))
return NULL;
}
/*
Ensure the array size has increased and the index is
now well within the array bounds.
*/
DBUG_ASSERT(idx < array->max_element);
return mem_root_dynamic_array_get_val(array, idx);
}
#include <mysql/psi/psi.h>
#ifdef HAVE_PSI_INTERFACE

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;
@@ -4842,16 +4838,16 @@ JSON_SCHEMA_VALID(@schema_array, '[')
0
Warnings:
Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_schema_valid'
SELECT JSON_SCHEMA_VALID(repeat('[', 100000), json_object());
JSON_SCHEMA_VALID(repeat('[', 100000), json_object())
SELECT JSON_SCHEMA_VALID(repeat('[', 100), json_object());
JSON_SCHEMA_VALID(repeat('[', 100), json_object())
NULL
Warnings:
Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 1 to function 'json_schema_valid' at position 32
SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000));
JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000))
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_schema_valid'
SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 100));
JSON_SCHEMA_VALID(json_object(), repeat('[', 100))
0
Warnings:
Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 2 to function 'json_schema_valid' at position 32
Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_schema_valid'
#
# MDEV-30677: Incorrect result for "SELECT JSON_SCHEMA_VALID('{}', NULL)"
#
@@ -4895,6 +4891,8 @@ NULL
SELECT JSON_KEY_VALUE('', '$.a');
JSON_KEY_VALUE('', '$.a')
NULL
Warnings:
Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_key_value'
SELECT JSON_KEY_VALUE('[1,2,3]', '');
JSON_KEY_VALUE('[1,2,3]', '')
NULL

View File

@@ -310,7 +310,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';
@@ -3800,10 +3800,10 @@ SET @schema_array= '{"type":"array"}';
SELECT JSON_SCHEMA_VALID(@schema_array, '[');
--disable_view_protocol
SELECT JSON_SCHEMA_VALID(repeat('[', 100000), json_object());
SELECT JSON_SCHEMA_VALID(repeat('[', 100), json_object());
--enable_view_protocol
SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000));
SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 100));
--echo #
--echo # MDEV-30677: Incorrect result for "SELECT JSON_SCHEMA_VALID('{}', NULL)"

View File

@@ -65,7 +65,7 @@ select json_equals('{"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"ob
select json_equals('{"obj":{"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"key": "value"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}',
'{"obj":{"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"key": "value"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}') as 32_levels;
32_levels
NULL
1
#
# test values from different charset
# (UTF-8 two-bytes vs. latin1 single high-byte)

View File

@@ -0,0 +1,454 @@
SET @json_doc_obj_lev45_valid='{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }';
SET @json_doc_arr_lev45_valid='[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]';
CREATE TABLE t1 (val JSON);
INSERT INTO t1 VALUES (@json_doc_arr_lev45_valid), ('[1, 2, 10,3, [4, 5, 6, [7, 8, 9]]]');
SELECT JSON_ARRAY(@json_doc_arr_lev45_valid, 1, 2, 3);
JSON_ARRAY(@json_doc_arr_lev45_valid, 1, 2, 3)
["[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", 1, 2, 3]
SELECT JSON_ARRAY (@json_doc_obj_lev45_valid, '{"key1":1, "key2":2}');
JSON_ARRAY (@json_doc_obj_lev45_valid, '{"key1":1, "key2":2}')
["{ \"level1\": { \"level2\": { \"level3\": { \"level4\": { \"level5\": { \"level6\": { \"level7\": { \"level8\": { \"level9\": { \"level10\": { \"level11\": { \"level12\": { \"level13\": { \"level14\": { \"level15\": { \"level16\": { \"level17\": { \"level18\": { \"level19\": { \"level20\": { \"level21\": { \"level22\": { \"level23\": { \"level24\": { \"level25\": { \"level26\": { \"level27\": { \"level28\": { \"level29\": { \"level30\": { \"level31\": { \"level32\": { \"level33\": { \"level34\": { \"level35\": { \"level36\": { \"level37\": { \"level38\": { \"level39\": { \"level40\": { \"level41\": { \"level42\": { \"level43\": { \"level44\": { \"level45\": \"This is level 45\" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }", "{\"key1\":1, \"key2\":2}"]
SELECT JSON_ARRAYAGG(val) FROM t1;
JSON_ARRAYAGG(val)
[[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],[1, 2, 10,3, [4, 5, 6, [7, 8, 9]]]]
SELECT JSON_ARRAY_APPEND(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result;
result
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45, false]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_ARRAY_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result;
result
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, false, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_ARRAY_INTERSECT(@json_doc_arr_lev45_valid, '[1, [2, [3]]]');
JSON_ARRAY_INTERSECT(@json_doc_arr_lev45_valid, '[1, [2, [3]]]')
[1]
SELECT JSON_COMPACT(@json_doc_obj_lev45_valid);
JSON_COMPACT(@json_doc_obj_lev45_valid)
{"level1":{"level2":{"level3":{"level4":{"level5":{"level6":{"level7":{"level8":{"level9":{"level10":{"level11":{"level12":{"level13":{"level14":{"level15":{"level16":{"level17":{"level18":{"level19":{"level20":{"level21":{"level22":{"level23":{"level24":{"level25":{"level26":{"level27":{"level28":{"level29":{"level30":{"level31":{"level32":{"level33":{"level34":{"level35":{"level36":{"level37":{"level38":{"level39":{"level40":{"level41":{"level42":{"level43":{"level44":{"level45":"This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
SELECT JSON_COMPACT(@json_doc_arr_lev45_valid);
JSON_COMPACT(@json_doc_arr_lev45_valid)
[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20,[21,[22,[23,[24,[25,[26,[27,[28,[29,[30,[31,[32,[33,[34,[35,[36,[37,[38,[39,[40,[41,[42,[43,[44,[45,45,45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_CONTAINS(@json_doc_obj_lev45_valid, ' { "level45": "This is level 45" }', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_CONTAINS(@json_doc_obj_lev45_valid, ' { "level45": "This is level 45" }', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level2
1
SELECT JSON_CONTAINS(@json_doc_arr_lev45_valid, '[45, 45, 45]', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_CONTAINS(@json_doc_arr_lev45_valid, '[45, 45, 45]', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
1
SELECT JSON_CONTAINS_PATH(@json_doc_arr_lev45_valid, 'all', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_CONTAINS_PATH(@json_doc_arr_lev45_valid, 'all', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
1
SELECT JSON_CONTAINS_PATH(@json_doc_obj_lev45_valid, 'all', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_CONTAINS_PATH(@json_doc_obj_lev45_valid, 'all', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.
1
SELECT JSON_DEPTH(@json_doc_arr_lev45_valid);
JSON_DEPTH(@json_doc_arr_lev45_valid)
46
SELECT JSON_DEPTH(@json_doc_obj_lev45_valid);
JSON_DEPTH(@json_doc_obj_lev45_valid)
46
SELECT JSON_DETAILED(@json_doc_obj_lev45_valid);
JSON_DETAILED(@json_doc_obj_lev45_valid)
{
"level1":
{
"level2":
{
"level3":
{
"level4":
{
"level5":
{
"level6":
{
"level7":
{
"level8":
{
"level9":
{
"level10":
{
"level11":
{
"level12":
{
"level13":
{
"level14":
{
"level15":
{
"level16":
{
"level17":
{
"level18":
{
"level19":
{
"level20":
{
"level21":
{
"level22":
{
"level23":
{
"level24":
{
"level25":
{
"level26":
{
"level27":
{
"level28":
{
"level29":
{
"level30":
{
"level31":
{
"level32":
{
"level33":
{
"level34":
{
"level35":
{
"level36":
{
"level37":
{
"level38":
{
"level39":
{
"level40":
{
"level41":
{
"level42":
{
"level43":
{
"level44":
{
"level45": "This is level 45"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
SELECT JSON_DETAILED(@json_doc_arr_lev45_valid);
JSON_DETAILED(@json_doc_arr_lev45_valid)
[
1,
[
2,
[
3,
[
4,
[
5,
[
6,
[
7,
[
8,
[
9,
[
10,
[
11,
[
12,
[
13,
[
14,
[
15,
[
16,
[
17,
[
18,
[
19,
[
20,
[
21,
[
22,
[
23,
[
24,
[
25,
[
26,
[
27,
[
28,
[
29,
[
30,
[
31,
[
32,
[
33,
[
34,
[
35,
[
36,
[
37,
[
38,
[
39,
[
40,
[
41,
[
42,
[
43,
[
44,
[
45,
45,
45
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
SELECT JSON_EQUALS(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid);
JSON_EQUALS(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid)
1
SELECT JSON_EQUALS(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid);
JSON_EQUALS(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid)
1
SELECT JSON_EXISTS(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_EXISTS(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
1
SELECT JSON_EXISTS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_EXISTS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level2
1
SELECT JSON_EXTRACT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_EXTRACT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
[45, 45, 45]
SELECT JSON_EXTRACT(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_EXTRACT(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level
{"level45": "This is level 45"}
SELECT JSON_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][3]', 46);
JSON_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][3]', 46)
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, [45, 46], 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_KEY_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_KEY_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.lev
[{"key": "level45", "value": "This is level 45"}]
SELECT JSON_KEYS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_KEYS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.
["level45"]
SELECT JSON_LENGTH(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
JSON_LENGTH(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level2
1
SELECT JSON_LENGTH(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_LENGTH(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
1
SELECT JSON_LOOSE(@json_doc_obj_lev45_valid);
JSON_LOOSE(@json_doc_obj_lev45_valid)
{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
SELECT JSON_LOOSE(@json_doc_arr_lev45_valid);
JSON_LOOSE(@json_doc_arr_lev45_valid)
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_MERGE(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}');
JSON_MERGE(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}')
{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, "key1": "val1", "key2": "val2"}
SELECT JSON_MERGE(@json_doc_arr_lev45_valid, '[1, 2, 3]');
JSON_MERGE(@json_doc_arr_lev45_valid, '[1, 2, 3]')
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], 1, 2, 3]
SELECT JSON_MERGE_PATCH(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}');
JSON_MERGE_PATCH(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}')
{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, "key1": "val1", "key2": "val2"}
SELECT JSON_MERGE_PATCH(@json_doc_arr_lev45_valid, '[1, 2, 3]');
JSON_MERGE_PATCH(@json_doc_arr_lev45_valid, '[1, 2, 3]')
[1, 2, 3]
SELECT JSON_MERGE_PRESERVE(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid);
JSON_MERGE_PRESERVE(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid)
{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": ["This is level 45", "This is level 45"]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
SELECT JSON_MERGE_PRESERVE(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid);
JSON_MERGE_PRESERVE(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid)
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], 1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_NORMALIZE(@json_doc_arr_lev45_valid);
JSON_NORMALIZE(@json_doc_arr_lev45_valid)
[1.0E0,[2.0E0,[3.0E0,[4.0E0,[5.0E0,[6.0E0,[7.0E0,[8.0E0,[9.0E0,[1.0E1,[1.1E1,[1.2E1,[1.3E1,[1.4E1,[1.5E1,[1.6E1,[1.7E1,[1.8E1,[1.9E1,[2.0E1,[2.1E1,[2.2E1,[2.3E1,[2.4E1,[2.5E1,[2.6E1,[2.7E1,[2.8E1,[2.9E1,[3.0E1,[3.1E1,[3.2E1,[3.3E1,[3.4E1,[3.5E1,[3.6E1,[3.7E1,[3.8E1,[3.9E1,[4.0E1,[4.1E1,[4.2E1,[4.3E1,[4.4E1,[4.5E1,4.5E1,4.5E1]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_OBJECT('level1', @json_doc_obj_lev45_valid);
JSON_OBJECT('level1', @json_doc_obj_lev45_valid)
{"level1": "{ \"level1\": { \"level2\": { \"level3\": { \"level4\": { \"level5\": { \"level6\": { \"level7\": { \"level8\": { \"level9\": { \"level10\": { \"level11\": { \"level12\": { \"level13\": { \"level14\": { \"level15\": { \"level16\": { \"level17\": { \"level18\": { \"level19\": { \"level20\": { \"level21\": { \"level22\": { \"level23\": { \"level24\": { \"level25\": { \"level26\": { \"level27\": { \"level28\": { \"level29\": { \"level30\": { \"level31\": { \"level32\": { \"level33\": { \"level34\": { \"level35\": { \"level36\": { \"level37\": { \"level38\": { \"level39\": { \"level40\": { \"level41\": { \"level42\": { \"level43\": { \"level44\": { \"level45\": \"This is level 45\" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }"}
SELECT JSON_OBJECT_FILTER_KEYS(@json_doc_obj_lev45_valid, '["level1"]');
JSON_OBJECT_FILTER_KEYS(@json_doc_obj_lev45_valid, '["level1"]')
{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
SELECT JSON_OBJECT_TO_ARRAY(@json_doc_obj_lev45_valid);
JSON_OBJECT_TO_ARRAY(@json_doc_obj_lev45_valid)
[["level1", {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}]]
CREATE TABLE t2 (val1 VARCHAR(10), val2 JSON);
INSERT INTO t2 VALUES('level0', @json_doc_obj_lev45_valid);
SELECT JSON_OBJECTAGG(val1, val2) FROM t2;
JSON_OBJECTAGG(val1, val2)
{"level0":{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }}
SELECT JSON_OVERLAPS(@json_doc_obj_lev45_valid,'{ "level44": { "level45": "This is level 45" } }');
JSON_OVERLAPS(@json_doc_obj_lev45_valid,'{ "level44": { "level45": "This is level 45" } }')
0
SELECT JSON_QUERY(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_QUERY(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
[45, 45, 45]
SELECT JSON_QUOTE(@json_doc_obj_lev45_valid);
JSON_QUOTE(@json_doc_obj_lev45_valid)
"{ \"level1\": { \"level2\": { \"level3\": { \"level4\": { \"level5\": { \"level6\": { \"level7\": { \"level8\": { \"level9\": { \"level10\": { \"level11\": { \"level12\": { \"level13\": { \"level14\": { \"level15\": { \"level16\": { \"level17\": { \"level18\": { \"level19\": { \"level20\": { \"level21\": { \"level22\": { \"level23\": { \"level24\": { \"level25\": { \"level26\": { \"level27\": { \"level28\": { \"level29\": { \"level30\": { \"level31\": { \"level32\": { \"level33\": { \"level34\": { \"level35\": { \"level36\": { \"level37\": { \"level38\": { \"level39\": { \"level40\": { \"level41\": { \"level42\": { \"level43\": { \"level44\": { \"level45\": \"This is level 45\" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }"
SELECT JSON_QUOTE(@json_doc_arr_lev45_valid);
JSON_QUOTE(@json_doc_arr_lev45_valid)
"[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
SET @json_removed= JSON_REMOVE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39');
SET @json_removed= JSON_REMOVE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT @json_removed;
@json_removed
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SET @json_schema= '{"type": "object", "properties": { "level1": { "type": "object", "properties": { "level2": { "type": "object", "properties": { "level3": { "type": "object", "properties": { "level4": { "type": "object", "properties": { "level5": { "type": "object", "properties": { "level6": { "type": "object", "properties": { "level7": { "type": "object", "properties": { "level8": { "type": "object", "properties": { "level9": { "type": "object", "properties": { "level10": { "type": "object", "properties": { "level11": { "type": "object", "properties": { "level12": { "type": "object", "properties": { "level13": { "type": "object", "properties": { "level14": { "type": "object", "properties": { "level15": { "type": "object", "properties": { "level16": { "type": "object", "properties": { "level17": { "type": "object", "properties": { "level18": { "type": "object", "properties": { "level19": { "type": "object", "properties": { "level20": { "type": "object", "properties": { "level21": { "type": "object", "properties": { "level22": { "type": "object", "properties": { "level23": { "type": "object", "properties": { "level24": { "type": "object", "properties": { "level25": { "type": "object", "properties": { "level26": { "type": "object", "properties": { "level27": { "type": "object", "properties": { "level28": { "type": "object", "properties": { "level29": { "type": "object", "properties": { "level30": { "type": "object", "properties": { "level31": { "type": "object", "properties": { "level32": { "type": "object", "properties": { "level33": { "type": "object", "properties": { "level34": { "type": "object", "properties": { "level35": { "type": "object", "properties": { "level36": { "type": "object", "properties": { "level37": { "type": "object", "properties": { "level38": { "type": "object", "properties": { "level39": { "type": "object", "properties": { "level40": { "type": "object", "properties": { "level41": { "type": "object", "properties": { "level42": { "type": "object", "properties": { "level43": { "type": "object", "properties": { "level44": { "type": "object", "properties": { "level45": { "type": "string", "const": "This is level 45" } }, "required": ["level45"] } }, "required": ["level44"] } }, "required": ["level43"] } }, "required": ["level42"] } }, "required": ["level41"] } }, "required": ["level40"] } }, "required": ["level39"] } }, "required": ["level38"] } }, "required": ["level37"] } }, "required": ["level36"] } }, "required": ["level35"] } }, "required": ["level34"] } }, "required": ["level33"] } }, "required": ["level32"] } }, "required": ["level31"] } }, "required": ["level30"] } }, "required": ["level29"] } }, "required": ["level28"] } }, "required": ["level27"] } }, "required": ["level26"] } }, "required": ["level25"] } }, "required": ["level24"] } }, "required": ["level23"] } }, "required": ["level22"] } }, "required": ["level21"] } }, "required": ["level20"] } }, "required": ["level19"] } }, "required": ["level18"] } }, "required": ["level17"] } }, "required": ["level16"] } }, "required": ["level15"] } }, "required": ["level14"] } }, "required": ["level13"] } }, "required": ["level12"] } }, "required": ["level11"] } }, "required": ["level10"] } }, "required": ["level9"] } }, "required": ["level8"] } }, "required": ["level7"] } }, "required": ["level6"] } }, "required": ["level5"] } }, "required": ["level4"] } }, "required": ["level3"] } }, "required": ["level2"] } }, "required": ["level1"] }';
SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid) AS found_path;
found_path
1
SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid2);
JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid2)
NULL
SELECT JSON_SEARCH(@json_doc_obj_lev45_valid,'one', 'This is level 45');
JSON_SEARCH(@json_doc_obj_lev45_valid,'one', 'This is level 45')
"$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44.level45"
SET @json_updated = JSON_SET(@json_doc_obj_lev45_valid,
'$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41',
'Updated value');
SELECT @json_updated;
@json_updated
{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": "Updated value"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
SELECT JSON_TYPE(@json_doc_obj_lev45_valid);
JSON_TYPE(@json_doc_obj_lev45_valid)
OBJECT
SELECT JSON_TYPE(@json_doc_arr_lev45_valid);
JSON_TYPE(@json_doc_arr_lev45_valid)
ARRAY
SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_obj_lev45_valid));
JSON_UNQUOTE(JSON_QUOTE(@json_doc_obj_lev45_valid))
{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }
SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_arr_lev45_valid));
JSON_UNQUOTE(JSON_QUOTE(@json_doc_arr_lev45_valid))
[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
SELECT JSON_VALID(@json_doc_obj_lev45_valid);
JSON_VALID(@json_doc_obj_lev45_valid)
1
SELECT JSON_VALID(@json_doc_arr_lev45_valid);
JSON_VALID(@json_doc_arr_lev45_valid)
1
SELECT JSON_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44.level45');
JSON_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28
This is level 45
SELECT JSON_VALUE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
JSON_VALUE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]')
45
DROP TABLE t1 ,t2;

View File

@@ -0,0 +1,113 @@
SET @json_doc_obj_lev45_valid='{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }';
SET @json_doc_arr_lev45_valid='[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]';
CREATE TABLE t1 (val JSON);
INSERT INTO t1 VALUES (@json_doc_arr_lev45_valid), ('[1, 2, 10,3, [4, 5, 6, [7, 8, 9]]]');
SELECT JSON_ARRAY(@json_doc_arr_lev45_valid, 1, 2, 3);
SELECT JSON_ARRAY (@json_doc_obj_lev45_valid, '{"key1":1, "key2":2}');
SELECT JSON_ARRAYAGG(val) FROM t1;
SELECT JSON_ARRAY_APPEND(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result;
SELECT JSON_ARRAY_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result;
SELECT JSON_ARRAY_INTERSECT(@json_doc_arr_lev45_valid, '[1, [2, [3]]]');
SELECT JSON_COMPACT(@json_doc_obj_lev45_valid);
SELECT JSON_COMPACT(@json_doc_arr_lev45_valid);
SELECT JSON_CONTAINS(@json_doc_obj_lev45_valid, ' { "level45": "This is level 45" }', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_CONTAINS(@json_doc_arr_lev45_valid, '[45, 45, 45]', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT JSON_CONTAINS_PATH(@json_doc_arr_lev45_valid, 'all', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT JSON_CONTAINS_PATH(@json_doc_obj_lev45_valid, 'all', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_DEPTH(@json_doc_arr_lev45_valid);
SELECT JSON_DEPTH(@json_doc_obj_lev45_valid);
SELECT JSON_DETAILED(@json_doc_obj_lev45_valid);
SELECT JSON_DETAILED(@json_doc_arr_lev45_valid);
SELECT JSON_EQUALS(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid);
SELECT JSON_EQUALS(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid);
SELECT JSON_EXISTS(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT JSON_EXISTS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_EXTRACT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT JSON_EXTRACT(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][3]', 46);
SELECT JSON_KEY_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_KEYS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_LENGTH(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44');
SELECT JSON_LENGTH(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT JSON_LOOSE(@json_doc_obj_lev45_valid);
SELECT JSON_LOOSE(@json_doc_arr_lev45_valid);
SELECT JSON_MERGE(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}');
SELECT JSON_MERGE(@json_doc_arr_lev45_valid, '[1, 2, 3]');
SELECT JSON_MERGE_PATCH(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}');
SELECT JSON_MERGE_PATCH(@json_doc_arr_lev45_valid, '[1, 2, 3]');
SELECT JSON_MERGE_PRESERVE(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid);
SELECT JSON_MERGE_PRESERVE(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid);
SELECT JSON_NORMALIZE(@json_doc_arr_lev45_valid);
SELECT JSON_OBJECT('level1', @json_doc_obj_lev45_valid);
SELECT JSON_OBJECT_FILTER_KEYS(@json_doc_obj_lev45_valid, '["level1"]');
SELECT JSON_OBJECT_TO_ARRAY(@json_doc_obj_lev45_valid);
CREATE TABLE t2 (val1 VARCHAR(10), val2 JSON);
INSERT INTO t2 VALUES('level0', @json_doc_obj_lev45_valid);
SELECT JSON_OBJECTAGG(val1, val2) FROM t2;
SELECT JSON_OVERLAPS(@json_doc_obj_lev45_valid,'{ "level44": { "level45": "This is level 45" } }');
SELECT JSON_QUERY(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT JSON_QUOTE(@json_doc_obj_lev45_valid);
SELECT JSON_QUOTE(@json_doc_arr_lev45_valid);
SET @json_removed= JSON_REMOVE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39');
SET @json_removed= JSON_REMOVE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
SELECT @json_removed;
SET @json_schema= '{"type": "object", "properties": { "level1": { "type": "object", "properties": { "level2": { "type": "object", "properties": { "level3": { "type": "object", "properties": { "level4": { "type": "object", "properties": { "level5": { "type": "object", "properties": { "level6": { "type": "object", "properties": { "level7": { "type": "object", "properties": { "level8": { "type": "object", "properties": { "level9": { "type": "object", "properties": { "level10": { "type": "object", "properties": { "level11": { "type": "object", "properties": { "level12": { "type": "object", "properties": { "level13": { "type": "object", "properties": { "level14": { "type": "object", "properties": { "level15": { "type": "object", "properties": { "level16": { "type": "object", "properties": { "level17": { "type": "object", "properties": { "level18": { "type": "object", "properties": { "level19": { "type": "object", "properties": { "level20": { "type": "object", "properties": { "level21": { "type": "object", "properties": { "level22": { "type": "object", "properties": { "level23": { "type": "object", "properties": { "level24": { "type": "object", "properties": { "level25": { "type": "object", "properties": { "level26": { "type": "object", "properties": { "level27": { "type": "object", "properties": { "level28": { "type": "object", "properties": { "level29": { "type": "object", "properties": { "level30": { "type": "object", "properties": { "level31": { "type": "object", "properties": { "level32": { "type": "object", "properties": { "level33": { "type": "object", "properties": { "level34": { "type": "object", "properties": { "level35": { "type": "object", "properties": { "level36": { "type": "object", "properties": { "level37": { "type": "object", "properties": { "level38": { "type": "object", "properties": { "level39": { "type": "object", "properties": { "level40": { "type": "object", "properties": { "level41": { "type": "object", "properties": { "level42": { "type": "object", "properties": { "level43": { "type": "object", "properties": { "level44": { "type": "object", "properties": { "level45": { "type": "string", "const": "This is level 45" } }, "required": ["level45"] } }, "required": ["level44"] } }, "required": ["level43"] } }, "required": ["level42"] } }, "required": ["level41"] } }, "required": ["level40"] } }, "required": ["level39"] } }, "required": ["level38"] } }, "required": ["level37"] } }, "required": ["level36"] } }, "required": ["level35"] } }, "required": ["level34"] } }, "required": ["level33"] } }, "required": ["level32"] } }, "required": ["level31"] } }, "required": ["level30"] } }, "required": ["level29"] } }, "required": ["level28"] } }, "required": ["level27"] } }, "required": ["level26"] } }, "required": ["level25"] } }, "required": ["level24"] } }, "required": ["level23"] } }, "required": ["level22"] } }, "required": ["level21"] } }, "required": ["level20"] } }, "required": ["level19"] } }, "required": ["level18"] } }, "required": ["level17"] } }, "required": ["level16"] } }, "required": ["level15"] } }, "required": ["level14"] } }, "required": ["level13"] } }, "required": ["level12"] } }, "required": ["level11"] } }, "required": ["level10"] } }, "required": ["level9"] } }, "required": ["level8"] } }, "required": ["level7"] } }, "required": ["level6"] } }, "required": ["level5"] } }, "required": ["level4"] } }, "required": ["level3"] } }, "required": ["level2"] } }, "required": ["level1"] }';
SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid) AS found_path;
SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid2);
SELECT JSON_SEARCH(@json_doc_obj_lev45_valid,'one', 'This is level 45');
SET @json_updated = JSON_SET(@json_doc_obj_lev45_valid,
'$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41',
'Updated value');
SELECT @json_updated;
SELECT JSON_TYPE(@json_doc_obj_lev45_valid);
SELECT JSON_TYPE(@json_doc_arr_lev45_valid);
SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_obj_lev45_valid));
SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_arr_lev45_valid));
SELECT JSON_VALID(@json_doc_obj_lev45_valid);
SELECT JSON_VALID(@json_doc_arr_lev45_valid);
SELECT JSON_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44.level45');
SELECT JSON_VALUE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]');
DROP TABLE t1 ,t2;

View File

@@ -411,3 +411,126 @@ void freeze_size(DYNAMIC_ARRAY *array)
array->max_element= elements;
}
}
int mem_root_dynamic_array_resize_not_allowed(MEM_ROOT_DYNAMIC_ARRAY *array)
{
return (array->malloc_flags & MY_BUFFER_NO_RESIZE);
}
int mem_root_dynamic_array_init(MEM_ROOT *current_mem_root,
PSI_memory_key psi_key,
MEM_ROOT_DYNAMIC_ARRAY *array,
size_t element_size, void *init_buffer,
size_t init_alloc, size_t alloc_increment,
myf my_flags)
{
DBUG_ENTER("init_mem_root_dynamic_array");
array->elements=0;
array->max_element=init_alloc;
array->alloc_increment=alloc_increment;
array->size_of_element=element_size;
array->m_psi_key= psi_key;
array->malloc_flags= my_flags;
array->mem_root= current_mem_root;
if ((array->buffer= (uchar*)init_buffer))
{
array->malloc_flags|= MY_INIT_BUFFER_USED;
memset(array->buffer, 0, array->size_of_element*array->max_element);
DBUG_RETURN(FALSE);
}
if (!alloc_increment && !(my_flags & MY_BUFFER_NO_RESIZE))
{
alloc_increment=MY_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
if (init_alloc > 8 && alloc_increment > init_alloc * 2)
alloc_increment=init_alloc*2;
}
/*
Since the dynamic array is usable even if allocation fails here malloc
should not throw an error
*/
if (init_alloc &&
!(array->buffer= (uchar*) alloc_root(array->mem_root,
array->size_of_element*
array->max_element)))
array->max_element=0;
memset(array->buffer, 0, array->size_of_element*array->max_element);
DBUG_RETURN(FALSE);
}
void mem_root_dynamic_array_reset(MEM_ROOT_DYNAMIC_ARRAY *array)
{
memset(array->buffer, 0, (array->size_of_element)*(array->max_element));
}
int mem_root_allocate_dynamic(MEM_ROOT *mem_root,
MEM_ROOT_DYNAMIC_ARRAY *array,
size_t idx)
{
DBUG_ENTER("allocate_dynamic");
if (idx >= array->max_element)
{
size_t size;
uchar *new_ptr;
size= (idx + array->alloc_increment);
if (array->malloc_flags & MY_INIT_BUFFER_USED)
{
/*
In this senerio, the buffer is statically preallocated,
so we have to create an all-new malloc since we overflowed
*/
if (!(new_ptr= (uchar *) alloc_root(mem_root,
size * array->size_of_element)))
DBUG_RETURN(0);
array->malloc_flags&= ~MY_INIT_BUFFER_USED;
}
else if (!(new_ptr= (uchar*) alloc_root(mem_root, size*array->size_of_element)))
DBUG_RETURN(TRUE);
/* copy old elements first. */
memcpy(new_ptr, array->buffer,
array->max_element * array->size_of_element);
/* set the remainging memory to 0. */
memset(new_ptr+((array->max_element) * array->size_of_element), 0,
array->alloc_increment*array->size_of_element);
array->buffer= new_ptr;
array->max_element= size;
}
DBUG_RETURN(FALSE);
}
/*
Note: If these two are merged, the resultant function will have to have
a conditional block of code. Now, these are called in recursive functions.
and although in non-recursive case it would probably not matter much,
calling functions with conditional block recursively introduces performance
delay.
Hence, to avoid the performance issue, where we know for sure
that there will be no need to resize, directly get value. And
in other places where there might be a need to resize the array,
use the one with resize.
*/
inline void* mem_root_dynamic_array_get_val(MEM_ROOT_DYNAMIC_ARRAY *array, size_t idx)
{
void* element_ptr;
DBUG_ASSERT(idx < array->max_element);
// Calculate the pointer to the desired element in the array
element_ptr = array->buffer + (idx * array->size_of_element);
return element_ptr;
}
inline void mem_root_dynamic_array_copy_values(MEM_ROOT_DYNAMIC_ARRAY *dest, MEM_ROOT_DYNAMIC_ARRAY *src)
{
size_t number_of_elements= dest->max_element < src->max_element ? dest->max_element : src->max_element;
memcpy(dest->buffer, src->buffer, dest->size_of_element * number_of_elements);
}

View File

@@ -124,6 +124,16 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
return str;
}
bool Item_func_geometry_from_json::fix_length_and_dec(THD *thd)
{
mem_root_dynamic_array_init(thd->mem_root, PSI_INSTRUMENT_MEM,
&je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
return Item_geometry_func::fix_length_and_dec(thd);
}
String *Item_func_geometry_from_json::val_str(String *str)
{
@@ -132,7 +142,6 @@ String *Item_func_geometry_from_json::val_str(String *str)
String *js= args[0]->val_str_ascii(&tmp_js);
uint32 srid= 0;
longlong options= 0;
json_engine_t je;
if ((null_value= args[0]->null_value))
return 0;

View File

@@ -248,6 +248,10 @@ public:
class Item_func_geometry_from_json: public Item_geometry_func
{
String tmp_js;
json_engine_t je;
MEM_ROOT current_mem_root;
int mem_root_inited;
bool check_arguments() const override
{
// TODO: check with Alexey, for better args[1] and args[2] type control
@@ -255,16 +259,18 @@ class Item_func_geometry_from_json: public Item_geometry_func
check_argument_types_traditional_scalar(1, MY_MIN(3, arg_count));
}
public:
Item_func_geometry_from_json(THD *thd, Item *js): Item_geometry_func(thd, js) {}
Item_func_geometry_from_json(THD *thd, Item *js): Item_geometry_func(thd, js)
{ mem_root_inited= false; }
Item_func_geometry_from_json(THD *thd, Item *js, Item *opt):
Item_geometry_func(thd, js, opt) {}
Item_geometry_func(thd, js, opt) { mem_root_inited= false; }
Item_func_geometry_from_json(THD *thd, Item *js, Item *opt, Item *srid):
Item_geometry_func(thd, js, opt, srid) {}
Item_geometry_func(thd, js, opt, srid) { mem_root_inited= false; }
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("st_geomfromgeojson") };
return name;
}
bool fix_length_and_dec(THD *thd) override;
String *val_str(String *) override;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_geometry_from_json>(thd, this); }

File diff suppressed because it is too large Load Diff

View File

@@ -33,7 +33,7 @@ public:
json_path_t p;
bool constant;
bool parsed;
json_path_step_t *cur_step;
MEM_ROOT_DYNAMIC_ARRAY *cur_step;
void set_constant_flag(bool s_constant)
{
constant= s_constant;
@@ -52,14 +52,16 @@ void report_json_error_ex(const char *js, json_engine_t *je,
class Json_engine_scan: public json_engine_t
{
public:
Json_engine_scan(CHARSET_INFO *i_cs, const uchar *str, const uchar *end)
Json_engine_scan(MEM_ROOT *mem_root, CHARSET_INFO *i_cs, const uchar *str,
const uchar *end)
{
json_scan_start(this, i_cs, str, end);
}
Json_engine_scan(const String &str)
:Json_engine_scan(str.charset(), (const uchar *) str.ptr(),
(const uchar *) str.end())
Json_engine_scan(MEM_ROOT *mem_root, const String &str)
:Json_engine_scan(mem_root, str.charset(), (const uchar *) str.ptr(),
(const uchar *) str.end())
{ }
Json_engine_scan(){}
bool check_and_get_value_scalar(String *res, int *error);
bool check_and_get_value_complex(String *res, int *error,
json_value_types cur_value_type=
@@ -70,11 +72,19 @@ public:
class Json_path_extractor: public json_path_with_flags
{
protected:
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
String tmp_js, tmp_path;
virtual ~Json_path_extractor() { }
Json_engine_scan je;
~Json_path_extractor() { }
virtual bool check_and_get_value(Json_engine_scan *je,
String *to, int *error)=0;
bool extract(String *to, Item *js, Item *jp, CHARSET_INFO *cs);
bool extract(MEM_ROOT *mem_root, String *to, Item *js,
Item *jp, CHARSET_INFO *cs,
MEM_ROOT_DYNAMIC_ARRAY *,
LEX_CSTRING *func_name);
void init_json_engine_stack(MEM_ROOT *mem_root);
public:
Json_path_extractor() {}
};
@@ -82,22 +92,18 @@ class Item_func_json_valid: public Item_bool_func
{
protected:
String tmp_value;
json_engine_t je;
public:
Item_func_json_valid(THD *thd, Item *json) : Item_bool_func(thd, json) {}
Item_func_json_valid(THD *thd, Item *json) :
Item_bool_func(thd, json) {}
bool val_bool() override;
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_valid") };
return name;
}
bool fix_length_and_dec(THD *thd) override
{
if (Item_bool_func::fix_length_and_dec(thd))
return TRUE;
set_maybe_null();
return FALSE;
}
bool fix_length_and_dec(THD *thd) override;
bool set_format_by_check_constraint(Send_field_extended_metadata *to) const
override
{
@@ -112,9 +118,13 @@ public:
class Item_func_json_equals: public Item_bool_func
{
json_engine_t je1, je2, temp_je;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_equals(THD *thd, Item *a, Item *b):
Item_bool_func(thd, a, b) {}
Item_bool_func(thd, a, b)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_equals") };
@@ -130,12 +140,15 @@ public:
class Item_func_json_exists: public Item_bool_func
{
protected:
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
json_path_with_flags path;
String tmp_js, tmp_path;
json_engine_t je;
public:
Item_func_json_exists(THD *thd, Item *js, Item *i_path):
Item_bool_func(thd, js, i_path) {}
Item_bool_func(thd, js, i_path)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_exists") };
@@ -169,6 +182,7 @@ public:
class Item_func_json_value: public Item_str_func,
public Json_path_extractor
{
LEX_CSTRING func_name_str;
public:
Item_func_json_value(THD *thd, Item *js, Item *i_path):
@@ -179,12 +193,7 @@ public:
return name;
}
bool fix_length_and_dec(THD *thd) override ;
String *val_str(String *to) override
{
null_value= Json_path_extractor::extract(to, args[0], args[1],
collation.collation);
return null_value ? NULL : to;
}
String *val_str(String *to) override;
bool check_and_get_value(Json_engine_scan *je,
String *res, int *error) override
{
@@ -198,21 +207,19 @@ public:
class Item_func_json_query: public Item_json_func,
public Json_path_extractor
{
LEX_CSTRING func_name_str;
public:
Item_func_json_query(THD *thd, Item *js, Item *i_path):
Item_json_func(thd, js, i_path) {}
Item_json_func(thd, js, i_path)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_query") };
return name;
}
bool fix_length_and_dec(THD *thd) override;
String *val_str(String *to) override
{
null_value= Json_path_extractor::extract(to, args[0], args[1],
collation.collation);
return null_value ? NULL : to;
}
String *val_str(String *to) override;
bool check_and_get_value(Json_engine_scan *je,
String *res, int *error) override
{
@@ -227,9 +234,11 @@ class Item_func_json_quote: public Item_str_func
{
protected:
String tmp_s;
json_engine_t je;
public:
Item_func_json_quote(THD *thd, Item *s): Item_str_func(thd, s) {}
Item_func_json_quote(THD *thd, Item *s): Item_str_func(thd, s)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_quote") };
@@ -244,11 +253,15 @@ public:
class Item_func_json_unquote: public Item_str_func
{
private:
json_engine_t je;
protected:
String tmp_s;
String *read_json(json_engine_t *je);
public:
Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s) {}
Item_func_json_unquote(THD *thd, Item *s): Item_str_func(thd, s)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_unquote") };
@@ -266,6 +279,7 @@ class Item_json_str_multipath: public Item_json_func
protected:
json_path_with_flags *paths;
String *tmp_paths;
private:
/**
Number of paths returned by calling virtual method get_n_paths() and
@@ -282,10 +296,12 @@ private:
uint n_paths;
public:
Item_json_str_multipath(THD *thd, List<Item> &list):
Item_json_func(thd, list), paths(NULL), tmp_paths(0), n_paths(0) {}
virtual ~Item_json_str_multipath();
Item_json_func(thd, list), paths(NULL), tmp_paths(0), n_paths(0)
{}
~Item_json_str_multipath();
bool fix_fields(THD *thd, Item **ref) override;
bool fix_length_and_dec(THD* thd) override;
virtual uint get_n_paths() const = 0;
};
@@ -293,12 +309,17 @@ public:
class Item_func_json_extract: public Item_json_str_multipath
{
protected:
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
String tmp_js;
json_path_t p;
json_engine_t je, sav_je;
public:
String *read_json(String *str, json_value_types *type,
char **out_val, int *value_len);
Item_func_json_extract(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
Item_json_str_multipath(thd, list)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_extract") };
@@ -319,14 +340,19 @@ public:
class Item_func_json_contains: public Item_bool_func
{
protected:
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
String tmp_js;
json_path_with_flags path;
String tmp_path;
bool a2_constant, a2_parsed;
String tmp_val, *val;
json_engine_t je, ve;
int loc_js_stack_buffer[JSON_DEPTH_LIMIT];
public:
Item_func_json_contains(THD *thd, List<Item> &list):
Item_bool_func(thd, list) {}
Item_bool_func(thd, list)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_contains") };
@@ -336,22 +362,27 @@ public:
bool val_bool() override;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_json_contains>(thd, this); }
int check_contains(json_engine_t *je, json_engine_t *ve);
};
class Item_func_json_contains_path: public Item_bool_func
{
protected:
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
String tmp_js;
json_path_with_flags *paths;
String *tmp_paths;
bool mode_one;
bool ooa_constant, ooa_parsed;
bool *p_found;
json_path_t p;
json_engine_t je;
public:
Item_func_json_contains_path(THD *thd, List<Item> &list):
Item_bool_func(thd, list), tmp_paths(0) {}
Item_bool_func(thd, list), tmp_paths(0)
{}
virtual ~Item_func_json_contains_path();
LEX_CSTRING func_name_cstring() const override
{
@@ -371,11 +402,15 @@ class Item_func_json_array: public Item_json_func
protected:
String tmp_val;
ulong result_limit;
json_engine_t je;
public:
Item_func_json_array(THD *thd):
Item_json_func(thd) {}
Item_json_func(thd)
{result_limit= 0;}
Item_func_json_array(THD *thd, List<Item> &list):
Item_json_func(thd, list) {}
Item_json_func(thd, list)
{}
String *val_str(String *) override;
bool fix_length_and_dec(THD *thd) override;
LEX_CSTRING func_name_cstring() const override
@@ -391,8 +426,12 @@ public:
class Item_func_json_array_append: public Item_json_str_multipath
{
protected:
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
String tmp_js;
String tmp_val;
json_engine_t je;
MEM_ROOT current_mem_root;
public:
Item_func_json_array_append(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
@@ -447,6 +486,8 @@ class Item_func_json_merge: public Item_func_json_array
{
protected:
String tmp_js1, tmp_js2;
json_engine_t je2;
public:
Item_func_json_merge(THD *thd, List<Item> &list):
Item_func_json_array(thd, list) {}
@@ -456,6 +497,7 @@ public:
static LEX_CSTRING name= {STRING_WITH_LEN("json_merge_preserve") };
return name;
}
bool fix_length_and_dec(THD *thd) override;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_json_merge>(thd, this); }
};
@@ -478,6 +520,9 @@ public:
class Item_func_json_normalize: public Item_json_func
{
json_engine_t je, temp_je;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_normalize(THD *thd, Item *a):
Item_json_func(thd, a) {}
@@ -497,9 +542,12 @@ class Item_func_json_object_to_array: public Item_json_func
{
protected:
String tmp;
json_engine_t je;
public:
Item_func_json_object_to_array(THD *thd, Item *a):
Item_json_func(thd, a) {}
Item_json_func(thd, a)
{}
String *val_str(String *) override;
LEX_CSTRING func_name_cstring() const override
{
@@ -529,6 +577,9 @@ protected:
json_path_with_flags path;
String tmp_js;
String tmp_path;
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
public:
Item_func_json_length(THD *thd, List<Item> &list):
Item_long_func(thd, list) {}
@@ -550,14 +601,17 @@ class Item_func_json_depth: public Item_long_func
{ return args[0]->check_type_can_return_text(func_name_cstring()); }
protected:
String tmp_js;
json_engine_t je;
public:
Item_func_json_depth(THD *thd, Item *js): Item_long_func(thd, js) {}
Item_func_json_depth(THD *thd, Item *js): Item_long_func(thd, js)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_depth") };
return name;
}
bool fix_length_and_dec(THD *thd) override { max_length= 10; return FALSE; }
bool fix_length_and_dec(THD *thd) override;
longlong val_int() override;
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_json_depth>(thd, this); }
@@ -568,6 +622,8 @@ class Item_func_json_type: public Item_str_func
{
protected:
String tmp_js;
json_engine_t je;
public:
Item_func_json_type(THD *thd, Item *js): Item_str_func(thd, js) {}
LEX_CSTRING func_name_cstring() const override
@@ -588,6 +644,9 @@ protected:
String tmp_js;
String tmp_val;
bool mode_insert, mode_replace;
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
public:
Item_func_json_insert(bool i_mode, bool r_mode, THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list),
@@ -612,9 +671,13 @@ class Item_func_json_remove: public Item_json_str_multipath
{
protected:
String tmp_js;
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
public:
Item_func_json_remove(THD *thd, List<Item> &list):
Item_json_str_multipath(thd, list) {}
Item_json_str_multipath(thd, list)
{}
bool fix_length_and_dec(THD *thd) override;
String *val_str(String *) override;
uint get_n_paths() const override { return arg_count - 1; }
@@ -633,6 +696,8 @@ class Item_func_json_keys: public Item_str_func
protected:
json_path_with_flags path;
String tmp_js, tmp_path;
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
public:
Item_func_json_keys(THD *thd, List<Item> &list):
@@ -652,12 +717,14 @@ public:
class Item_func_json_search: public Item_json_str_multipath
{
protected:
String tmp_js, tmp_path, esc_value;
String tmp_js, tmp_path, esc_value, temp;
bool mode_one;
bool ooa_constant, ooa_parsed;
int escape;
int n_path_found;
json_path_t sav_path;
json_path_t p, sav_path;
json_engine_t je;
MEM_ROOT_DYNAMIC_ARRAY json_depth_array;
int compare_json_value_wild(json_engine_t *je, const String *cmp_str);
@@ -691,11 +758,15 @@ public:
protected:
formats fmt;
String tmp_js;
json_engine_t je;
public:
Item_func_json_format(THD *thd, Item *js, formats format):
Item_json_func(thd, js), fmt(format) {}
Item_json_func(thd, js), fmt(format)
{}
Item_func_json_format(THD *thd, List<Item> &list):
Item_json_func(thd, list), fmt(DETAILED) {}
Item_json_func(thd, list), fmt(DETAILED)
{}
LEX_CSTRING func_name_cstring() const override;
bool fix_length_and_dec(THD *thd) override;
@@ -807,6 +878,9 @@ 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, temp_je;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_overlaps(THD *thd, Item *a, Item *b):
Item_bool_func(thd, a, b)
@@ -829,6 +903,7 @@ class Item_func_json_schema_valid: public Item_bool_func
String tmp_val, *val;
List<Json_schema_keyword> keyword_list;
List<Json_schema_keyword> all_keywords;
json_engine_t je, ve;
public:
Item_func_json_schema_valid(THD *thd, Item *a, Item *b):
@@ -837,6 +912,7 @@ public:
val= NULL;
schema_parsed= false;
set_maybe_null();
}
LEX_CSTRING func_name_cstring() const override
{
@@ -851,14 +927,16 @@ public:
};
class Item_func_json_key_value: public Item_json_func,
public Json_path_extractor
public Json_path_extractor
{
String tmp_str;
String tmp_str, tmp_val;
json_engine_t je, je_scan;
LEX_CSTRING func_name_str;
public:
Item_func_json_key_value(THD *thd, Item *js, Item *i_path):
Item_json_func(thd, js, i_path) {}
Item_json_func(thd, js, i_path)
{}
LEX_CSTRING func_name_cstring() const override
{
static LEX_CSTRING name= {STRING_WITH_LEN("json_key_value") };
@@ -882,13 +960,19 @@ class Item_func_json_array_intersect: public Item_str_func
{
protected:
String tmp_js1, tmp_js2;
bool hash_inited, root_inited;
bool hash_inited, hash_root_inited;
HASH items;
MEM_ROOT hash_root;
bool parse_for_each_row;
json_engine_t je1, je2, res_je, temp_je;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_array_intersect(THD *thd, Item *a, Item *b):
Item_str_func(thd, a, b) { hash_inited= root_inited= parse_for_each_row= false; }
Item_str_func(thd, a, b)
{
hash_inited= hash_root_inited= parse_for_each_row= false;
}
String *val_str(String *) override;
bool fix_length_and_dec(THD *thd) override;
LEX_CSTRING func_name_cstring() const override
@@ -903,8 +987,9 @@ public:
Item_str_func::cleanup();
if (hash_inited)
my_hash_free(&items);
if (root_inited)
if (hash_root_inited)
free_root(&hash_root, MYF(0));
Item_str_func::cleanup();
}
void prepare_json_and_create_hash(json_engine_t *je1, String *js);
};
@@ -913,12 +998,18 @@ class Item_func_json_object_filter_keys: public Item_str_func
{
protected:
String tmp_js1, tmp_js2;
bool hash_inited, root_inited;
bool hash_inited, hash_root_inited;
HASH items;
MEM_ROOT hash_root;
json_engine_t je1, je_res, temp_je, temp_je2;
MEM_ROOT_DYNAMIC_ARRAY stack;
public:
Item_func_json_object_filter_keys(THD *thd, Item *a, Item *b):
Item_str_func(thd, a, b) { hash_inited= root_inited= false; }
Item_str_func(thd, a, b)
{
hash_inited= hash_root_inited= false;
}
String *val_str(String *) override;
bool fix_length_and_dec(THD *thd) override;
LEX_CSTRING func_name_cstring() const override
@@ -931,11 +1022,11 @@ public:
void cleanup() override
{
Item_str_func::cleanup();
if (hash_inited)
my_hash_free(&items);
if (root_inited)
if (hash_root_inited)
free_root(&hash_root, MYF(0));
Item_str_func::cleanup();
}
};

View File

@@ -177,10 +177,15 @@ Item_func_vec_totext::Item_func_vec_totext(THD *thd, Item *a)
Item_func_vec_fromtext::Item_func_vec_fromtext(THD *thd, Item *a)
: Item_str_func(thd, a)
{
mem_root_inited= false;
}
bool Item_func_vec_fromtext::fix_length_and_dec(THD *thd)
{
mem_root_dynamic_array_init(thd->mem_root, PSI_INSTRUMENT_MEM,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
decimals= 0;
/* Worst case scenario, for a valid input we have a string of the form:
[1,2,3,4,5,...] single digit numbers.
@@ -193,7 +198,6 @@ bool Item_func_vec_fromtext::fix_length_and_dec(THD *thd)
String *Item_func_vec_fromtext::val_str(String *buf)
{
json_engine_t je;
bool end_ok= false;
String *value = args[0]->val_json(&tmp_js);

View File

@@ -90,6 +90,9 @@ public:
class Item_func_vec_fromtext: public Item_str_func
{
String tmp_js;
MEM_ROOT current_mem_root;
bool mem_root_inited;
json_engine_t je;
public:
bool fix_length_and_dec(THD *thd) override;
Item_func_vec_fromtext(THD *thd, Item *a);
@@ -101,5 +104,11 @@ public:
}
Item *do_get_copy(THD *thd) const override
{ return get_item_copy<Item_func_vec_fromtext>(thd, this); }
void cleanup() override
{
if (mem_root_inited)
free_root(&current_mem_root, MYF(0));
Item_str_func::cleanup();
}
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -43,10 +43,12 @@ class Json_schema_keyword : public Sql_alloc
/*
Called for each keyword on the current level.
*/
virtual bool validate(const json_engine_t *je, const uchar *k_start= NULL,
virtual bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL)
{ return false; }
virtual bool handle_keyword(THD *thd, json_engine_t *je,
virtual bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords)
@@ -62,15 +64,18 @@ class Json_schema_keyword : public Sql_alloc
alternate_schema= schema;
}
virtual bool fall_back_on_alternate_schema(const json_engine_t *je,
MEM_ROOT *current_mem_root,
const uchar* k_start= NULL,
const uchar* k_end= NULL);
virtual bool validate_as_alternate(const json_engine_t *je,
const uchar* k_start= NULL,
const uchar* k_end= NULL)
const uchar* k_start= NULL,
const uchar* k_end= NULL,
MEM_ROOT *current_mem_root= NULL)
{
return false;
}
virtual bool validate_schema_items(const json_engine_t *je,
MEM_ROOT *current_mem_root,
List<Json_schema_keyword>*schema_items);
virtual void set_alternate_schema_choice(Json_schema_keyword *schema1,
Json_schema_keyword *schema2)
@@ -101,25 +106,29 @@ class Json_schema_additional_and_unevaluated : public Json_schema_keyword
{
allowed= allowed_val;
}
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
bool validate(const json_engine_t *je,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override
{
return false;
}
bool validate_as_alternate(const json_engine_t *je, const uchar *k_start,
const uchar *k_end) override;
bool validate_as_alternate(const json_engine_t *je,
const uchar *k_start,
const uchar *k_end,
MEM_ROOT *current_mem_root) override;
};
class Json_schema_annotation : public Json_schema_keyword
{
public:
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -128,7 +137,8 @@ class Json_schema_annotation : public Json_schema_keyword
class Json_schema_format : public Json_schema_keyword
{
public:
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -142,10 +152,10 @@ class Json_schema_type : public Json_schema_keyword
uint type;
public:
bool validate(const json_engine_t *je,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
@@ -160,13 +170,16 @@ 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;
bool validate(const json_engine_t *je,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -182,12 +195,15 @@ 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,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -204,10 +220,11 @@ class Json_schema_enum : public Json_schema_keyword
class Json_schema_maximum : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -216,10 +233,11 @@ class Json_schema_maximum : public Json_schema_keyword
class Json_schema_minimum : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -231,9 +249,11 @@ class Json_schema_multiple_of : public Json_schema_keyword
longlong multiple_of;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -242,9 +262,11 @@ class Json_schema_multiple_of : public Json_schema_keyword
class Json_schema_ex_maximum : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -253,9 +275,11 @@ class Json_schema_ex_maximum : public Json_schema_keyword
class Json_schema_ex_minimum : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -264,9 +288,11 @@ class Json_schema_ex_minimum : public Json_schema_keyword
class Json_schema_max_len : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -275,9 +301,11 @@ class Json_schema_max_len : public Json_schema_keyword
class Json_schema_min_len : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -291,9 +319,11 @@ class Json_schema_pattern : public Json_schema_keyword
Item_string *str;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -308,9 +338,11 @@ class Json_schema_pattern : public Json_schema_keyword
class Json_schema_max_items : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -319,9 +351,11 @@ class Json_schema_max_items : public Json_schema_keyword
class Json_schema_min_items : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -330,7 +364,8 @@ class Json_schema_min_items : public Json_schema_keyword
class Json_schema_max_contains : public Json_schema_keyword
{
public:
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -339,7 +374,8 @@ class Json_schema_max_contains : public Json_schema_keyword
class Json_schema_min_contains : public Json_schema_keyword
{
public:
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -356,9 +392,11 @@ class Json_schema_contains : public Json_schema_keyword
Json_schema_keyword *max_contains;
Json_schema_keyword *min_contains;
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -373,11 +411,15 @@ 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, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -388,9 +430,11 @@ class Json_schema_prefix_items : public Json_schema_keyword
{
public:
List <List_schema_keyword> prefix_items;
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -408,7 +452,8 @@ class Json_schema_unevaluated_items :
{
priority= 4;
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
};
@@ -420,7 +465,8 @@ class Json_schema_additional_items :
{
priority= 3;
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
};
@@ -434,14 +480,18 @@ class Json_schema_items : public Json_schema_keyword
priority= 2;
}
void set_allowed(bool allowed_val) { allowed= allowed_val; }
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
bool validate_as_alternate(const json_engine_t *je, const uchar *k_start,
const uchar *k_end) override;
bool validate_as_alternate(const json_engine_t *je,
const uchar *k_start,
const uchar *k_end,
MEM_ROOT *current_mem_root) override;
};
@@ -451,9 +501,11 @@ class Json_schema_property_names : public Json_schema_keyword
List <Json_schema_keyword> property_names;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -476,9 +528,11 @@ class Json_schema_properties : public Json_schema_keyword
{
priority= 1;
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -487,8 +541,10 @@ class Json_schema_properties : public Json_schema_keyword
if (is_hash_inited)
my_hash_free(&properties);
}
bool validate_as_alternate(const json_engine_t *je, const uchar *k_start,
const uchar *k_end) override;
bool validate_as_alternate(const json_engine_t *je,
const uchar *k_start,
const uchar *k_end,
MEM_ROOT *current_mem_root) override;
};
class Json_schema_dependent_schemas : public Json_schema_keyword
@@ -503,9 +559,11 @@ class Json_schema_dependent_schemas : public Json_schema_keyword
if (is_hash_inited)
my_hash_free(&properties);
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -520,7 +578,8 @@ class Json_schema_additional_properties :
{
priority= 3;
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
};
@@ -532,7 +591,8 @@ class Json_schema_unevaluated_properties :
{
priority= 4;
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
};
@@ -550,9 +610,11 @@ class Json_schema_pattern_properties : public Json_schema_keyword
List<st_pattern_to_property> pattern_properties;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -576,17 +638,21 @@ class Json_schema_pattern_properties : public Json_schema_keyword
}
}
}
bool validate_as_alternate(const json_engine_t *je, const uchar *k_start,
const uchar *k_end) override;
bool validate_as_alternate(const json_engine_t *je,
const uchar *k_start,
const uchar *k_end,
MEM_ROOT *current_mem_root) override;
};
class Json_schema_max_prop : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -595,9 +661,11 @@ class Json_schema_max_prop : public Json_schema_keyword
class Json_schema_min_prop : public Json_schema_keyword
{
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -609,9 +677,11 @@ class Json_schema_required : public Json_schema_keyword
List <String> required_properties;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -629,9 +699,11 @@ class Json_schema_dependent_required : public Json_schema_keyword
List<st_dependent_keywords> dependent_required;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -645,9 +717,11 @@ class Json_schema_logic : public Json_schema_keyword
List <List_schema_keyword> schema_items;
Json_schema_keyword *alternate_choice1, *alternate_choice2;
public:
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -664,7 +738,9 @@ class Json_schema_logic : public Json_schema_keyword
alternate_choice1= schema1;
alternate_choice2= schema2;
}
bool check_validation(const json_engine_t *je, const uchar *k_start= NULL,
bool check_validation(const json_engine_t *je,
MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL);
};
@@ -677,7 +753,8 @@ class Json_schema_not : public Json_schema_logic
{
logic_flag= HAS_NOT;
}
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -739,9 +816,11 @@ class Json_schema_conditional : public Json_schema_keyword
then_cond= NULL;
else_cond= NULL;
}
bool validate(const json_engine_t *je, const uchar *k_start= NULL,
bool validate(const json_engine_t *je, MEM_ROOT *current_mem_root,
const uchar *k_start= NULL,
const uchar *k_end= NULL) override;
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -775,7 +854,8 @@ class Json_schema_then : public Json_schema_conditional
class Json_schema_media_string : public Json_schema_keyword
{
public:
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
@@ -784,13 +864,15 @@ class Json_schema_media_string : public Json_schema_keyword
class Json_schema_reference : public Json_schema_keyword
{
public:
bool handle_keyword(THD *thd, json_engine_t *je,
bool handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
const char* key_start,
const char* key_end,
List<Json_schema_keyword> *all_keywords) override;
};
bool create_object_and_handle_keyword(THD *thd, json_engine_t *je,
bool create_object_and_handle_keyword(THD *thd, MEM_ROOT *current_mem_root,
json_engine_t *je,
List<Json_schema_keyword> *keyword_list,
List<Json_schema_keyword> *all_keywords);
const uchar *get_key_name_for_property(const void *key_name, size_t *length,

View File

@@ -59,7 +59,9 @@ const uchar *get_key_name(const void *key_name_, size_t *length, my_bool)
}
void json_get_normalized_string(json_engine_t *je, String *res,
int *error)
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))
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

@@ -25,5 +25,7 @@ bool json_key_equals(const char* key, LEX_CSTRING val, int key_len);
bool json_assign_type(uint *curr_type, json_engine_t *je);
const uchar *get_key_name(const void *key_name, size_t *length, my_bool);
void json_get_normalized_string(json_engine_t *je, String *res,
int *error);
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,13 @@ public:
buf->length(0);
return TRUE;
}
int ha_rnd_end()
{
DBUG_ENTER("ha_json_table::ha_rnd_end");
if (mem_root_inited)
free_root(&current_mem_root, MYF(0));
DBUG_RETURN(handler::ha_rnd_end());
}
};
@@ -358,6 +372,13 @@ int ha_json_table::rnd_init(bool scan)
(const uchar *) m_js->ptr(), (const uchar *) m_js->end());
}
mem_root_dynamic_array_init(current_thd->mem_root, PSI_INSTRUMENT_MEM,
&array_counters, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_thd->mem_root, PSI_INSTRUMENT_MEM,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
DBUG_RETURN(0);
}
@@ -427,6 +448,19 @@ bool Json_table_nested_path::check_error(const char *str)
return false; // Ok
}
void Json_table_nested_path::init_json_engine()
{
mem_root_dynamic_array_init(current_thd->mem_root, PSI_INSTRUMENT_MEM,
&m_engine.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_thd->mem_root, PSI_INSTRUMENT_MEM,
&m_cur_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(current_thd->mem_root, PSI_INSTRUMENT_MEM,
&m_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
}
int ha_json_table::rnd_next(uchar *buf)
{
@@ -472,7 +506,7 @@ int ha_json_table::rnd_next(uchar *buf)
int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
{
MY_BITMAP *orig_map= dbug_tmp_use_all_columns(table, &table->write_set);
MY_BITMAP *orig_map= dbug_tmp_use_all_columns(table, &table->write_set);
int error= 0;
Counting_error_handler er_handler;
Field **f= table->field;
@@ -538,13 +572,14 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
case Json_table_column::PATH:
case Json_table_column::EXISTS_PATH:
{
json_engine_t je;
json_path_step_t *cur_step;
int array_counters[JSON_DEPTH_LIMIT];
int not_found;
const uchar* node_start;
const uchar* node_end;
mem_root_dynamic_array_reset(&array_counters);
mem_root_dynamic_array_reset(&je.stack);
/*
Get the JSON context node that we will need to evaluate PATH or
EXISTS against:
@@ -564,8 +599,8 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
json_scan_start(&je, m_js->charset(), node_start, node_end);
cur_step= jc->m_path.steps;
not_found= json_find_path(&je, &jc->m_path, &cur_step, array_counters) ||
cur_step= (json_path_step_t*)(jc->m_path.steps.buffer);
not_found= json_find_path(&je, &jc->m_path, &cur_step, &array_counters) ||
json_read_value(&je);
if (jc->m_column_type == Json_table_column::EXISTS_PATH)
@@ -608,7 +643,7 @@ int ha_json_table::fill_column_values(THD *thd, uchar * buf, uchar *pos)
JSON_PATH_ARRAY_RANGE) &&
(json_scan_next(&je) ||
!json_find_path(&je, &jc->m_path, &cur_step,
array_counters)))
&array_counters)))
{
error= jc->m_on_error.respond(jc, *f,
ER_JSON_TABLE_MULTIPLE_MATCHES);
@@ -899,6 +934,10 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
{
set(ctype);
m_explicit_cs= cs;
mem_root_dynamic_array_init(thd->mem_root, PSI_INSTRUMENT_MEM,
&m_path.steps, sizeof(json_path_step_t), NULL,
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)))
{
@@ -924,6 +963,10 @@ int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
int Json_table_column::set(THD *thd, enum_type ctype, const LEX_CSTRING &path,
const Lex_column_charset_collation_attrs_st &cl)
{
mem_root_dynamic_array_init(thd->mem_root, PSI_INSTRUMENT_MEM,
&m_path.steps, sizeof(json_path_step_t), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
if (cl.is_empty() || cl.is_contextually_typed_collate_default())
return set(thd, ctype, path, nullptr);
@@ -1000,6 +1043,10 @@ int Json_table_column::print(THD *thd, Field **f, String *str)
int Json_table_nested_path::set_path(THD *thd, const LEX_CSTRING &path)
{
mem_root_dynamic_array_init(thd->mem_root, PSI_INSTRUMENT_MEM,
&m_path.steps, sizeof(json_path_step_t), NULL,
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

@@ -57,13 +57,16 @@ public:
/*** Construction interface ***/
Json_table_nested_path():
m_null(TRUE), m_nested(NULL), m_next_nested(NULL)
{}
{
init_json_engine();
}
int set_path(THD *thd, const LEX_CSTRING &path);
/*** Methods for performing a scan ***/
void scan_start(CHARSET_INFO *i_cs, const uchar *str, const uchar *end);
int scan_next();
void init_json_engine();
bool check_error(const char *str);
/*** Members for getting the values we've scanned to ***/

View File

@@ -761,8 +761,13 @@ bool Histogram_json_hb::parse(MEM_ROOT *mem_root, const char *db_name,
double total_size;
int end_element;
bool end_assigned;
DBUG_ENTER("Histogram_json_hb::parse");
mem_root_dynamic_array_init(mem_root, PSI_INSTRUMENT_MEM,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
json_scan_start(&je, &my_charset_utf8mb4_bin,
(const uchar*)hist_data,
(const uchar*)hist_data+hist_data_len);
@@ -812,7 +817,9 @@ bool Histogram_json_hb::parse(MEM_ROOT *mem_root, const char *db_name,
{
// Some unknown member. Skip it.
if (json_skip_key(&je))
{
return 1;
}
}
}

View File

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

View File

@@ -1821,13 +1821,27 @@ class User_table_json: public User_table
int value_len;
const char *value_start;
enum json_types value_type;
json_engine_t temp_je;
MEM_ROOT current_mem_root;
init_alloc_root(PSI_INSTRUMENT_MEM, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&temp_je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
String str, *res= m_table->field[2]->val_str(&str);
if (!res || !res->length())
(res= &str)->set(STRING_WITH_LEN("{}"), m_table->field[2]->charset());
value_type= json_get_object_key(res->ptr(), res->end(), key,
&value_start, &value_len);
if (value_type == JSV_BAD_JSON)
{
free_root(&current_mem_root, MYF(0));
return value_type; // invalid
}
StringBuffer<JSON_SIZE> json(res->charset());
json.copy(res->ptr(), value_start - res->ptr(), res->charset());
if (value_type == JSV_NOTHING)
@@ -1846,8 +1860,9 @@ class User_table_json: public User_table
if (!value_type && string)
json.append('"');
json.append(value_start, res->end() - value_start);
DBUG_ASSERT(json_valid(json.ptr(), json.length(), json.charset()));
DBUG_ASSERT((json_valid(json.ptr(), json.length(), json.charset(), &temp_je)));
m_table->field[2]->store(json.ptr(), json.length(), json.charset());
free_root(&current_mem_root, MYF(0));
return value_type;
}
bool set_str_value(const char *key, const char *val, size_t vlen) const

View File

@@ -4794,6 +4794,7 @@ void thd_increment_bytes_sent(void *thd, size_t length)
}
}
my_bool thd_net_is_killed(THD *thd)
{
return thd && thd->killed ? 1 : 0;

File diff suppressed because it is too large Load Diff

View File

@@ -644,87 +644,88 @@ json_norm_append_to_object(struct json_norm_value *val,
static int
json_norm_parse(struct json_norm_value *root, json_engine_t *je)
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;
struct json_norm_value *stack[JSON_DEPTH_LIMIT];
int err= 0;
size_t current = 0;
int err = 0;
DYNAMIC_STRING key;
struct json_norm_value* root_ptr = root;
err= init_dynamic_string(&key, NULL, 0, 0);
// Set the root pointer in the stack
mem_root_dynamic_array_set_val(stack, &root_ptr, current);
err = init_dynamic_string(&key, NULL, 0, 0);
if (err)
{
goto json_norm_parse_end;
memset(stack, 0x00, sizeof(stack));
current= 0;
stack[current]= root;
}
do {
switch (je->state)
{
case JST_KEY:
{
const uchar *key_start= je->s.c_str;
const uchar *key_start = je->s.c_str;
const uchar *key_end;
struct json_norm_value* new_val_ptr= NULL;
struct json_norm_value** curr_val_ptr =
(struct json_norm_value**)(stack->buffer) + current;
struct json_norm_value* curr_val = *curr_val_ptr;
DBUG_ASSERT(curr_val->type == JSON_VALUE_OBJECT);
DBUG_ASSERT(stack[current]->type == JSON_VALUE_OBJECT);
do
{
key_end= je->s.c_str;
key_end = je->s.c_str;
} while (json_read_keyname_chr(je) == 0);
/* we have the key name */
/* reset the dynstr: */
dynstr_trunc(&key, key.length);
dynstr_append_mem(&key, (char *)key_start, (key_end - key_start));
dynstr_append_mem(&key, (char*)key_start, (key_end - key_start));
/* After reading the key, we have a follow-up value. */
err= json_read_value(je);
err = json_read_value(je);
if (err)
goto json_norm_parse_end;
err= json_norm_append_to_object(stack[current], &key, je);
err = json_norm_append_to_object(curr_val, &key, je);
if (err)
goto json_norm_parse_end;
if (je->value_type == JSON_VALUE_ARRAY ||
je->value_type == JSON_VALUE_OBJECT)
{
struct json_norm_kv *kv;
err= ((current + 1) == JSON_DEPTH_LIMIT);
if (err)
goto json_norm_parse_end;
kv= json_norm_object_get_last_element(&stack[current]->value.object);
stack[++current]= &kv->value;
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_resize_and_set_val(stack, &new_val_ptr, ++current);
}
break;
}
case JST_VALUE:
{
struct json_norm_array *current_arr= &stack[current]->value.array;
err= json_read_value(je);
struct json_norm_value** curr_val_ptr =
(struct json_norm_value**)(stack->buffer) + current;
struct json_norm_value* curr_val = *curr_val_ptr;
struct json_norm_array* current_arr = &curr_val->value.array;
err = json_read_value(je);
if (err)
goto json_norm_parse_end;
DBUG_ASSERT(stack[current]->type == JSON_VALUE_ARRAY);
DBUG_ASSERT(curr_val->type == JSON_VALUE_ARRAY);
err= json_norm_append_to_array(stack[current], je);
err = json_norm_append_to_array(curr_val, je);
if (err)
goto json_norm_parse_end;
if (je->value_type == JSON_VALUE_ARRAY ||
je->value_type == JSON_VALUE_OBJECT)
{
err= ((current + 1) == JSON_DEPTH_LIMIT);
if (err)
goto json_norm_parse_end;
stack[++current]= json_norm_array_get_last_element(current_arr);
struct json_norm_value* element =
json_norm_array_get_last_element(current_arr);
mem_root_dynamic_array_resize_and_set_val(stack, &element, ++current);
}
break;
}
case JST_OBJ_START:
@@ -736,14 +737,14 @@ json_norm_parse(struct json_norm_value *root, json_engine_t *je)
--current;
break;
case JST_ARRAY_START:
/* parser found an array (the '[' in JSON) */
/* parser found an array (the '[' in JSON) */
break;
case JST_ARRAY_END:
/* parser found the end of the array (the ']' in JSON) */
/* pop stack */
--current;
break;
};
}
} while (json_scan_next(je) == 0);
json_norm_parse_end:
@@ -751,40 +752,47 @@ json_norm_parse_end:
return err;
}
static int
json_norm_build(struct json_norm_value *root,
const char *s, size_t size, CHARSET_INFO *cs)
const char *s, size_t size, CHARSET_INFO *cs,
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;
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);
err= json_norm_parse(root, je, current_mem_root, stack);
if (err)
{
return err;
}
}
return err;
}
int
json_normalize(DYNAMIC_STRING *result,
const char *s, size_t size, CHARSET_INFO *cs)
const char *s, size_t size, CHARSET_INFO *cs,
MEM_ROOT *current_mem_root,
json_engine_t *temp_je,
MEM_ROOT_DYNAMIC_ARRAY *stack)
{
int err= 0;
uint convert_err= 0;
@@ -827,13 +835,14 @@ json_normalize(DYNAMIC_STRING *result,
}
if (!json_valid(in, in_size, &my_charset_utf8mb4_bin))
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);
err= json_norm_build(&root, in, in_size,
&my_charset_utf8mb4_bin, current_mem_root, temp_je, stack);
if (err)
goto json_normalize_end;

View File

@@ -38,28 +38,28 @@ 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;
bzero(result, sizeof(*result));
if (json_scan_start(&je, ci, s_e(j)))
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)
{
return;
}
break;
case JST_VALUE:
result->n_values++;
@@ -73,9 +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);
result->error= je.s.error;
result->error= je->s.error;
}
@@ -89,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");
@@ -111,18 +111,24 @@ 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;
if (json_path_setup(&p, ci, s_e(p0)))
return;
ok(p.last_step - p.steps == 4 &&
p.steps[0].type == JSON_PATH_ARRAY_WILD &&
p.steps[1].type == JSON_PATH_KEY &&
p.steps[2].type == JSON_PATH_ARRAY && p.steps[2].n_item == 12 &&
p.steps[3].type == JSON_PATH_KEY_WILD &&
p.steps[4].type == JSON_PATH_ARRAY_WILD,
json_path_step_t *initial_step= NULL;
initial_step= (json_path_step_t*)(p->steps.buffer);
if (json_path_setup(p, ci, s_e(p0)))
goto error;
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 &&
(initial_step+3)->type == JSON_PATH_KEY_WILD &&
(initial_step+4)->type == JSON_PATH_ARRAY_WILD,
"path");
error:
return;
}
@@ -134,53 +140,75 @@ 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;
json_path_step_t *cur_step;
MEM_ROOT_DYNAMIC_ARRAY *cur_step;
int n_matches, scal_values;
int array_counters[JSON_DEPTH_LIMIT];
json_path_step_t *tmp_ptr= NULL;
if (json_scan_start(&je, ci, s_e(fj0)) ||
json_path_setup(&p, ci, s_e(fp0)))
return;
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;
while (json_find_path(&je, &p, &cur_step, array_counters) == 0)
tmp_ptr= (json_path_step_t*)(cur_step->buffer);
while (json_find_path(je, p, &tmp_ptr, array_counters) == 0)
{
n_matches++;
if (json_read_value(&je))
return;
if (json_value_scalar(&je))
if (json_read_value(je))
goto end;
if (json_value_scalar(je))
{
scal_values++;
if (json_scan_next(&je))
return;
if (json_scan_next(je))
goto end;
}
else
{
if (json_skip_level(&je) || json_scan_next(&je))
return;
if (json_skip_level(je) || json_scan_next(je))
goto end;
}
}
ok(n_matches == 3, "search");
end:
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_INSTRUMENT_MEM, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&array_counters, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&je.stack, sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&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,16 +21,17 @@
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;
MEM_ROOT current_mem_root;
CHARSET_INFO *cs= &my_charset_utf8mb4_general_ci;
init_dynamic_string(&result, NULL, 0, 0);
err= json_normalize(&result, in, strlen(in), cs);
err= json_normalize(&result, in, strlen(in), cs, &current_mem_root, je, stack);
ok(err == 0, "normalize err: %d", err);
@@ -43,36 +44,40 @@ check_json_normalize(const char *in, const char *expected)
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;
CHARSET_INFO *cs= &my_charset_utf8mb4_general_ci;
init_alloc_root(PSI_INSTRUMENT_MEM, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
init_dynamic_string(&result, NULL, 0, 0);
ok(json_normalize(&result, STRING_WITH_LEN(""), cs) != 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) != 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) != 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) != 0,
ok(json_normalize(&result, NULL, 0, cs, &current_mem_root, je, stack) != 0,
"expected normalized error");
dynstr_free(&result);
}
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"
@@ -80,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"
@@ -94,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"
@@ -140,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"
@@ -154,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"
@@ -184,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);
}
@@ -194,24 +199,27 @@ 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 };
const char latin[] = { 0x22, 0xCA, 0x22, 0x00 };
DYNAMIC_STRING result;
MEM_ROOT current_mem_root;
CHARSET_INFO *cs_utf8= &my_charset_utf8mb4_bin;
CHARSET_INFO *cs_latin= &my_charset_latin1;
init_dynamic_string(&result, NULL, 0, 0);
err= json_normalize(&result, utf8, strlen(utf8), cs_utf8);
ok(err == 0, "normalize err: %d", err);
init_alloc_root(PSI_INSTRUMENT_MEM, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
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);
ok(err == 0, "normalize err: %d", err);
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);
}
@@ -243,8 +251,20 @@ check_number_normalize(const char *in, const char *expected)
int
main(int argc, char** argv)
{
MY_INIT(argv[0]);
MEM_ROOT current_mem_root;
MEM_ROOT_DYNAMIC_ARRAY stack;
json_engine_t je;
init_alloc_root(PSI_INSTRUMENT_MEM, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&je.stack,
sizeof(int), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&stack,
sizeof(struct json_norm_value*), NULL,
JSON_DEPTH_DEFAULT, JSON_DEPTH_INC, MYF(0));
plan(88);
diag("Testing json_normalization.");
@@ -268,15 +288,17 @@ main(int argc, char** argv)
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));
my_end(MY_CHECK_ERROR);
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_INSTRUMENT_MEM, &current_mem_root,
BLOCK_SIZE_JSON_DYN_ARRAY, 0, MYF(0));
mem_root_dynamic_array_init(&current_mem_root, PSI_INSTRUMENT_MEM,
&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();
}