From 53870ac06f6f546a8b94a2260e114c8ed1cfe667 Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Thu, 22 May 2025 15:42:12 +0530 Subject: [PATCH] json_depth --- utils/funcexp/func_json_array_append.cpp | 9 ++++++++ utils/funcexp/func_json_array_insert.cpp | 24 +++++++++++++++----- utils/funcexp/func_json_contains.cpp | 14 ++++++++++++ utils/funcexp/func_json_contains_path.cpp | 20 ++++++++++++++++- utils/funcexp/func_json_depth.cpp | 5 +++++ utils/funcexp/func_json_equals.cpp | 18 +++++++++++++-- utils/funcexp/func_json_exists.cpp | 11 +++++++++ utils/funcexp/func_json_extract.cpp | 20 ++++++++++++++++- utils/funcexp/func_json_format.cpp | 6 +++++ utils/funcexp/func_json_insert.cpp | 25 +++++++++++++++++---- utils/funcexp/func_json_keys.cpp | 12 ++++++++++ utils/funcexp/func_json_length.cpp | 9 ++++++++ utils/funcexp/func_json_merge.cpp | 9 ++++++++ utils/funcexp/func_json_merge_patch.cpp | 8 +++++++ utils/funcexp/func_json_normalize.cpp | 13 ++++++++++- utils/funcexp/func_json_overlaps.cpp | 11 +++++++++ utils/funcexp/func_json_remove.cpp | 23 +++++++++++++++---- utils/funcexp/func_json_search.cpp | 27 +++++++++++++++++++---- utils/funcexp/func_json_type.cpp | 4 ++++ utils/funcexp/func_json_unquote.cpp | 6 +++++ utils/funcexp/func_json_valid.cpp | 9 +++++++- utils/funcexp/func_json_value.cpp | 24 ++++++++++++++++---- utils/funcexp/jsonhelpers.cpp | 2 +- utils/funcexp/jsonhelpers.h | 11 +++++++-- 24 files changed, 290 insertions(+), 30 deletions(-) diff --git a/utils/funcexp/func_json_array_append.cpp b/utils/funcexp/func_json_array_append.cpp index e038e37f17..f5f5f0dcbc 100644 --- a/utils/funcexp/func_json_array_append.cpp +++ b/utils/funcexp/func_json_array_append.cpp @@ -30,11 +30,16 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b const CHARSET_INFO* cs = getCharset(fp[0]); json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; const uchar* arrEnd; size_t strRestLen; string retJS; retJS.reserve(js.length() + padding); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSPaths(paths, fp, 1, 2); utils::NullString tmpJS(js); @@ -44,6 +49,10 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b const size_t jsLen = tmpJS.length(); JSONPath& path = paths[j]; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + if (!path.parsed && parseJSPath(path, row, fp[i], false)) goto error; diff --git a/utils/funcexp/func_json_array_insert.cpp b/utils/funcexp/func_json_array_insert.cpp index 9e6c5186a0..40ad14cb0d 100644 --- a/utils/funcexp/func_json_array_insert.cpp +++ b/utils/funcexp/func_json_array_insert.cpp @@ -1,6 +1,8 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" +#include "my_sys.h" using namespace execplan; #include "rowgroup.h" @@ -30,11 +32,17 @@ string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, b const CHARSET_INFO* cs = getCharset(fp[0]); json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; string retJS; retJS.reserve(js.length() + 8); + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; initJSPaths(paths, fp, 1, 2); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + utils::NullString tmpJS(js); for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++) { @@ -43,19 +51,23 @@ string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, b JSONPath& path = paths[j]; if (!path.parsed) { - if (parseJSPath(path, row, fp[i]) || path.p.last_step - 1 < path.p.steps || - path.p.last_step->type != JSON_PATH_ARRAY) + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + json_path_step_t *last_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&path.p.steps, path.p.last_step_idx)), + *initial_step= (json_path_step_t*)path.p.steps.buffer; + if (parseJSPath(path, row, fp[i]) || (last_step - 1) < initial_step || + last_step->type != JSON_PATH_ARRAY) { if (path.p.s.error == 0) path.p.s.error = SHOULD_END_WITH_ARRAY; goto error; } - path.p.last_step--; + path.p.last_step_idx--; } initJSEngine(jsEg, cs, tmpJS); - path.currStep = path.p.steps; int jsErr = 0; if (locateJSPath(jsEg, path, &jsErr)) @@ -82,7 +94,9 @@ string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, b while (json_scan_next(&jsEg) == 0 && jsEg.state != JST_ARRAY_END) { DBUG_ASSERT(jsEg.state == JST_VALUE); - if (itemSize == path.p.last_step[1].n_item) + if (itemSize == (((json_path_step_t*) + (mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx)))[1].n_item)) { itemPos = (const char*)jsEg.s.c_str; break; diff --git a/utils/funcexp/func_json_contains.cpp b/utils/funcexp/func_json_contains.cpp index f399ddc602..c57aa36333 100644 --- a/utils/funcexp/func_json_contains.cpp +++ b/utils/funcexp/func_json_contains.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" #include "rowgroup.h" using namespace execplan; using namespace rowgroup; @@ -160,6 +161,9 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& /*type*/) { bool isNullJS = false, isNullVal = false; + int jsEg_stack[JSON_DEPTH_LIMIT], valEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + const auto& js = fp[0]->data()->getStrVal(row, isNullJS); const auto& val = fp[1]->data()->getStrVal(row, isNullVal); if (isNullJS || isNullVal) @@ -182,10 +186,17 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, } json_engine_t jsEg; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); if (fp.size() > 2) { + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + if (!path.parsed && parseJSPath(path, row, fp[2], false)) goto error; @@ -194,6 +205,9 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, } json_engine_t valEg; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &valEg.stack, sizeof(int), &valEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(valEg, getCharset(fp[1]), arg2Val); if (json_read_value(&jsEg) || json_read_value(&valEg)) diff --git a/utils/funcexp/func_json_contains_path.cpp b/utils/funcexp/func_json_contains_path.cpp index 35106ac2f1..0d46487a9f 100644 --- a/utils/funcexp/func_json_contains_path.cpp +++ b/utils/funcexp/func_json_contains_path.cpp @@ -65,12 +65,17 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul if (paths.size() == 0) hasFound.assign(argSize, false); + vector> p_steps_arr(paths.size(), vector(32)); + for (size_t i = 2; i < fp.size(); i++) { JSONPath& path = paths[i - 2]; if (!path.parsed) { + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps_arr[i-4], + JSON_DEPTH_LIMIT, 0, MYF(0)); if (parseJSPath(path, row, fp[i])) { isNull = true; @@ -83,7 +88,17 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul } json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; json_path_t p; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)js.data(), (const uchar*)js.data() + js.size(), &p); @@ -99,8 +114,11 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul while (json_get_path_next(&jsEg, &p) == 0) { #ifdef MYSQL_GE_1009 + json_path_step_t *last_step= (json_path_step_t*) + (mem_root_dynamic_array_get_val(&p.steps, + p.last_step_idx)); if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && - json_skip_array_and_count(&jsEg, arrayCounters + (p.last_step - p.steps))) + json_skip_array_and_count(&jsEg, arrayCounters + (last_step - (json_path_step_t*)p.steps.buffer))) { result = true; break; diff --git a/utils/funcexp/func_json_depth.cpp b/utils/funcexp/func_json_depth.cpp index 66bcc22c9f..c607b52edf 100644 --- a/utils/funcexp/func_json_depth.cpp +++ b/utils/funcexp/func_json_depth.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -28,8 +29,12 @@ int64_t Func_json_depth::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& i int depth = 0, currDepth = 0; bool incDepth = true; + int jsEg_stack[JSON_DEPTH_LIMIT]; json_engine_t jsEg; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); do diff --git a/utils/funcexp/func_json_equals.cpp b/utils/funcexp/func_json_equals.cpp index 0e0270cc2b..8cf8c75d49 100644 --- a/utils/funcexp/func_json_equals.cpp +++ b/utils/funcexp/func_json_equals.cpp @@ -27,9 +27,20 @@ CalpontSystemCatalog::ColType Func_json_equals::operationType(FunctionParm& fp, bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& /*type*/) { + json_engine_t je; + MEM_ROOT_DYNAMIC_ARRAY array; + int je_stack[JSON_DEPTH_LIMIT], buffer_array[JSON_DEPTH_LIMIT]; + // auto release the DYNAMIC_STRING using DynamicString = unique_ptr; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &je.stack, sizeof(int), &je_stack, + JSON_DEPTH_DEFAULT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &array, sizeof(int), &buffer_array, + JSON_DEPTH_DEFAULT, 0, MYF(0)); + DynamicString str1{new DYNAMIC_STRING(), dynstr_free}; if (init_dynamic_string(str1.get(), NULL, 0, 0)) { @@ -56,13 +67,16 @@ bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, const string_view js2 = js2_ns.unsafeStringRef(); bool result = false; - if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0]))) + if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0]), NULL, &je, &array)) { isNull = true; return result; } - if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1]))) + memset(je_stack, 0, sizeof(je_stack)); + memset(buffer_array, 0, sizeof(buffer_array)); + + if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1]), NULL, &je, &array)) { isNull = true; return result; diff --git a/utils/funcexp/func_json_exists.cpp b/utils/funcexp/func_json_exists.cpp index f7a3325eeb..3e8c909d91 100644 --- a/utils/funcexp/func_json_exists.cpp +++ b/utils/funcexp/func_json_exists.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" #include "rowgroup.h" using namespace execplan; using namespace rowgroup; @@ -30,8 +31,18 @@ bool Func_json_exists::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, int jsErr = 0; json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + if (!path.parsed && parseJSPath(path, row, fp[1])) goto error; diff --git a/utils/funcexp/func_json_extract.cpp b/utils/funcexp/func_json_extract.cpp index f2975a8eed..d642868660 100644 --- a/utils/funcexp/func_json_extract.cpp +++ b/utils/funcexp/func_json_extract.cpp @@ -22,7 +22,9 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t return 1; const char* rawJS = js.str(); json_engine_t jsEg, savJSEg; + int jsEg_stack[JSON_DEPTH_LIMIT], savJSEg_stack[JSON_DEPTH_LIMIT]; json_path_t p; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; const uchar* value; bool notFirstVal = false; size_t valLen; @@ -37,10 +39,25 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t string tmp; initJSPaths(paths, fp, 1, 1); + vector> p_steps_arr(paths.size(), vector(32)); + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &savJSEg.stack, sizeof(int), &savJSEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); for (size_t i = 1; i < argSize; i++) { JSONPath& path = paths[i - 1]; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps_arr[i-1], + JSON_DEPTH_LIMIT, 0, MYF(0)); path.p.types_used = JSON_PATH_KEY_NULL; if (!path.parsed && parseJSPath(path, row, fp[i])) return 1; @@ -71,8 +88,9 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t while (json_get_path_next(&jsEg, &p) == 0) { #ifdef MYSQL_GE_1009 + json_path_step_t *last_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&p.steps, p.last_step_idx)); if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && - json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps))) + json_skip_array_and_count(&jsEg, arrayCounter + (last_step - (json_path_step_t*)(p.steps.buffer)))) return 1; #endif diff --git a/utils/funcexp/func_json_format.cpp b/utils/funcexp/func_json_format.cpp index 73f88fdab4..b9c324a886 100644 --- a/utils/funcexp/func_json_format.cpp +++ b/utils/funcexp/func_json_format.cpp @@ -47,7 +47,13 @@ string Func_json_format::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i } json_engine_t jsEg; + int jsEg_stack [JSON_DEPTH_LIMIT]; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); + string ret; if (doFormat(&jsEg, ret, fmt, tabSize)) { diff --git a/utils/funcexp/func_json_insert.cpp b/utils/funcexp/func_json_insert.cpp index 1a59d974e8..527609fae3 100644 --- a/utils/funcexp/func_json_insert.cpp +++ b/utils/funcexp/func_json_insert.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -29,6 +30,8 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i const bool isInsertMode = mode == INSERT || mode == SET; const bool isReplaceMode = mode == REPLACE || mode == SET; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + int jsEg_stack[JSON_DEPTH_LIMIT]; json_engine_t jsEg; @@ -46,8 +49,15 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i { const char* rawJS = tmpJS.str(); const size_t jsLen = tmpJS.length(); + json_path_step_t *curr_last_step= nullptr; JSONPath& path = paths[j]; + + memset(&p_steps[0], 0, sizeof(p_steps)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + const json_path_step_t* lastStep; const char* valEnd; @@ -56,14 +66,21 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (parseJSPath(path, row, fp[i], false)) goto error; - path.p.last_step--; + path.p.last_step_idx--; } + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, cs, tmpJS); - if (path.p.last_step < path.p.steps) + + if (((json_path_step_t*)(mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx))) < (json_path_step_t*)(path.p.steps.buffer)) goto v_found; - if (path.p.last_step >= path.p.steps && locateJSPath(jsEg, path, &jsErr)) + curr_last_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx)); + if (curr_last_step >= (json_path_step_t*)(path.p.steps.buffer) && locateJSPath(jsEg, path, &jsErr)) { if (jsErr) goto error; @@ -73,7 +90,7 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (json_read_value(&jsEg)) goto error; - lastStep = path.p.last_step + 1; + lastStep = curr_last_step + 1; if (lastStep->type & JSON_PATH_ARRAY) { IntType itemSize = 0; diff --git a/utils/funcexp/func_json_keys.cpp b/utils/funcexp/func_json_keys.cpp index 8634fce500..5a99b9eb02 100644 --- a/utils/funcexp/func_json_keys.cpp +++ b/utils/funcexp/func_json_keys.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -61,10 +62,21 @@ string Func_json_keys::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN IntType keySize = 0; string ret; json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); + if (fp.size() > 1) { + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + if (!path.parsed && parseJSPath(path, row, fp[1], false)) goto error; diff --git a/utils/funcexp/func_json_length.cpp b/utils/funcexp/func_json_length.cpp index 474e8bbca7..eaa02bcfe5 100644 --- a/utils/funcexp/func_json_length.cpp +++ b/utils/funcexp/func_json_length.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -28,13 +29,21 @@ int64_t Func_json_length::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& return 0; json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; int length = 0; int err; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); if (fp.size() > 1) { + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_DEFAULT, 0, MYF(0)); if (!path.parsed && parseJSPath(path, row, fp[1], false)) goto error; diff --git a/utils/funcexp/func_json_merge.cpp b/utils/funcexp/func_json_merge.cpp index 3d4b241bbe..42298e0531 100644 --- a/utils/funcexp/func_json_merge.cpp +++ b/utils/funcexp/func_json_merge.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -224,6 +225,14 @@ string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is const CHARSET_INFO* js1CS = getCharset(fp[0]); json_engine_t jsEg1, jsEg2; + int jsEg1_stack[JSON_DEPTH_LIMIT], jsEg2_stack[JSON_DEPTH_LIMIT]; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg1.stack, sizeof(int), &jsEg1_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg2.stack, sizeof(int), &jsEg2_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); utils::NullString tmpJS(js); string retJS; diff --git a/utils/funcexp/func_json_merge_patch.cpp b/utils/funcexp/func_json_merge_patch.cpp index 250c11736a..f348c4e8eb 100644 --- a/utils/funcexp/func_json_merge_patch.cpp +++ b/utils/funcexp/func_json_merge_patch.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -276,6 +277,7 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo isNull = false; json_engine_t jsEg1, jsEg2; + int jsEg1_stack[JSON_DEPTH_LIMIT], jsEg2_stack[JSON_DEPTH_LIMIT]; jsEg1.s.error = jsEg2.s.error = 0; utils::NullString tmpJS(js); @@ -290,6 +292,9 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo goto next; } + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg2.stack, sizeof(int), &jsEg2_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg2, getCharset(fp[i]), js2); if (hasNullArg) @@ -304,6 +309,9 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo goto next; } + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg1.stack, sizeof(int), &jsEg1_stack, + JSON_DEPTH_DEFAULT, 0, MYF(0)); initJSEngine(jsEg1, getCharset(fp[0]), tmpJS); if (doMergePatch(retJS, &jsEg1, &jsEg2, isEmpty)) { diff --git a/utils/funcexp/func_json_normalize.cpp b/utils/funcexp/func_json_normalize.cpp index 0470f8a809..35c34aa427 100644 --- a/utils/funcexp/func_json_normalize.cpp +++ b/utils/funcexp/func_json_normalize.cpp @@ -25,6 +25,17 @@ CalpontSystemCatalog::ColType Func_json_normalize::operationType( string Func_json_normalize::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isNull, execplan::CalpontSystemCatalog::ColType& /*type*/) { + json_engine_t je; + MEM_ROOT_DYNAMIC_ARRAY array; + int je_stack[JSON_DEPTH_LIMIT], buffer_array[JSON_DEPTH_LIMIT]; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &je.stack, sizeof(int), &je_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &array, sizeof(int), &buffer_array, + JSON_DEPTH_LIMIT, 0, MYF(0)); + const auto js_ns = fp[0]->data()->getStrVal(row, isNull); if (isNull) return ""; @@ -36,7 +47,7 @@ string Func_json_normalize::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool if (init_dynamic_string(str.get(), NULL, 0, 0)) goto error; - if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0]))) + if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0]), NULL, &je, &array)) goto error; return str->str; diff --git a/utils/funcexp/func_json_overlaps.cpp b/utils/funcexp/func_json_overlaps.cpp index b8933a79b0..4758b0abda 100644 --- a/utils/funcexp/func_json_overlaps.cpp +++ b/utils/funcexp/func_json_overlaps.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" #include "rowgroup.h" using namespace execplan; using namespace rowgroup; @@ -279,12 +280,22 @@ bool Func_json_overlaps::getBoolVal(Row& row, FunctionParm& fp, bool& /*isNull*/ CalpontSystemCatalog::ColType& /*type*/) { bool isNullJS1 = false, isNullJS2 = false; + int jsEg1_stack[JSON_DEPTH_LIMIT], jsEg2_stack[JSON_DEPTH_LIMIT]; + const auto js1 = fp[0]->data()->getStrVal(row, isNullJS1); const auto js2 = fp[1]->data()->getStrVal(row, isNullJS2); if (isNullJS1 || isNullJS2) return false; json_engine_t jsEg1, jsEg2; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg1.stack, sizeof(int), &jsEg1_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg2.stack, sizeof(int), &jsEg2_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + initJSEngine(jsEg1, getCharset(fp[0]), js1); initJSEngine(jsEg2, getCharset(fp[1]), js2); diff --git a/utils/funcexp/func_json_remove.cpp b/utils/funcexp/func_json_remove.cpp index ca9e958eab..7d96311363 100644 --- a/utils/funcexp/func_json_remove.cpp +++ b/utils/funcexp/func_json_remove.cpp @@ -28,7 +28,14 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (isNull) return ""; + int jsEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + json_engine_t jsEg; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + int jsErr = 0; json_string_t keyName; @@ -43,19 +50,27 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i { const char* rawJS = tmpJS.str(); const size_t jsLen = tmpJS.length(); + json_path_step_t *curr_last_step= nullptr; JSONPath& path = paths[j]; const json_path_step_t* lastStep; const char *remStart = nullptr, *remEnd = nullptr; IntType itemSize = 0; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), p_steps, + JSON_DEPTH_DEFAULT, 0, MYF(0)); + if (!path.parsed) { if (parseJSPath(path, row, fp[i], false)) goto error; - path.p.last_step--; - if (path.p.last_step < path.p.steps) + path.p.last_step_idx--; + curr_last_step= (json_path_step_t*) + (mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx)); + if (curr_last_step < (json_path_step_t*)(path.p.steps.buffer)) { path.p.s.error = TRIVIAL_PATH_NOT_ALLOWED; goto error; @@ -64,7 +79,7 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i initJSEngine(jsEg, cs, tmpJS); - if (path.p.last_step < path.p.steps) + if (curr_last_step < (json_path_step_t*)(path.p.steps.buffer)) goto v_found; if (locateJSPath(jsEg, path, &jsErr) && jsErr) @@ -73,7 +88,7 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (json_read_value(&jsEg)) goto error; - lastStep = path.p.last_step + 1; + lastStep = curr_last_step + 1; if (lastStep->type & JSON_PATH_ARRAY) { if (jsEg.value_type != JSON_VALUE_ARRAY) diff --git a/utils/funcexp/func_json_search.cpp b/utils/funcexp/func_json_search.cpp index dea9214ab6..a47e9e96aa 100644 --- a/utils/funcexp/func_json_search.cpp +++ b/utils/funcexp/func_json_search.cpp @@ -15,17 +15,20 @@ using namespace joblist; #include "jsonhelpers.h" using namespace funcexp::helpers; +#include "my_sys.h" + namespace { -static bool appendJSPath(string& ret, const json_path_t* p) +static bool appendJSPath(string& ret, json_path_t* p) { const json_path_step_t* c; + json_path_step_t *last_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&p->steps, p->last_step_idx)); try { ret.append("\"$"); - for (c = p->steps + 1; c <= p->last_step; c++) + for (c = ((json_path_step_t*)(p->steps.buffer)) + 1; c <= last_step; c++) { if (c->type & JSON_PATH_KEY) { @@ -133,7 +136,9 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i } json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; json_path_t p, savPath; + json_path_step_t savPath_steps[JSON_DEPTH_LIMIT], p_steps[JSON_DEPTH_LIMIT]; const CHARSET_INFO* cs = getCharset(fp[0]); #ifdef MYSQL_GE_1009 @@ -143,12 +148,23 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i int pathFound = 0; initJSPaths(paths, fp, 4, 1); + vector> p_steps_arr(paths.size(), vector(32)); + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &savPath.steps, sizeof(json_path_step_t), &savPath_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); for (size_t i = 4; i < fp.size(); i++) { JSONPath& path = paths[i - 4]; if (!path.parsed) { + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &path.p.steps, sizeof(json_path_step_t), &p_steps_arr[i-4], + JSON_DEPTH_LIMIT, 0, MYF(0)); if (parseJSPath(path, row, fp[i])) goto error; #ifdef MYSQL_GE_1009 @@ -157,13 +173,17 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i } } + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); + json_get_path_start(&jsEg, cs, (const uchar*)js.str(), (const uchar*)js.end(), &p); while (json_get_path_next(&jsEg, &p) == 0) { #ifdef MYSQL_GE_1009 if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && - json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps))) + json_skip_array_and_count(&jsEg, arrayCounter + (((json_path_step_t*)(mem_root_dynamic_array_get_val(&p.steps, p.last_step_idx))) - (json_path_step_t*)p.steps.buffer))) goto error; #endif @@ -180,7 +200,6 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (pathFound == 1) { savPath = p; - savPath.last_step = savPath.steps + (p.last_step - p.steps); } else { diff --git a/utils/funcexp/func_json_type.cpp b/utils/funcexp/func_json_type.cpp index be248a7942..d82cb2ed88 100644 --- a/utils/funcexp/func_json_type.cpp +++ b/utils/funcexp/func_json_type.cpp @@ -28,7 +28,11 @@ string Func_json_type::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN json_engine_t jsEg; string result; + int jsEg_stack[JSON_DEPTH_LIMIT]; + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, getCharset(fp[0]), js); if (json_read_value(&jsEg)) diff --git a/utils/funcexp/func_json_unquote.cpp b/utils/funcexp/func_json_unquote.cpp index 35f11694cf..5fcd371ffa 100644 --- a/utils/funcexp/func_json_unquote.cpp +++ b/utils/funcexp/func_json_unquote.cpp @@ -1,5 +1,6 @@ #include "functor_json.h" #include "functioncolumn.h" +#include "json_lib.h" #include "jsonhelpers.h" using namespace execplan; @@ -27,9 +28,14 @@ std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, b return ""; json_engine_t jsEg; + int jsEg_stack[JSON_DEPTH_LIMIT]; int strLen; const CHARSET_INFO* cs = type.getCharset(); + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &jsEg.stack, sizeof(int), &jsEg_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); initJSEngine(jsEg, cs, js); json_read_value(&jsEg); diff --git a/utils/funcexp/func_json_valid.cpp b/utils/funcexp/func_json_valid.cpp index 8d118c75f0..2e6b652132 100644 --- a/utils/funcexp/func_json_valid.cpp +++ b/utils/funcexp/func_json_valid.cpp @@ -25,10 +25,17 @@ CalpontSystemCatalog::ColType Func_json_valid::operationType(FunctionParm& fp, bool Func_json_valid::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& /*type*/) { + int je_stack[JSON_DEPTH_LIMIT]; + json_engine_t je; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &je.stack, sizeof(int), &je_stack, + JSON_DEPTH_DEFAULT, 0, MYF(0)); + const auto js = fp[0]->data()->getStrVal(row, isNull); if (isNull) return false; - return json_valid(js.unsafeStringRef().data(), js.unsafeStringRef().size(), getCharset(fp[0])); + return json_valid(js.unsafeStringRef().data(), js.unsafeStringRef().size(), getCharset(fp[0]), &je); } } // namespace funcexp diff --git a/utils/funcexp/func_json_value.cpp b/utils/funcexp/func_json_value.cpp index 7bc2ee4dcd..4594fbdc71 100644 --- a/utils/funcexp/func_json_value.cpp +++ b/utils/funcexp/func_json_value.cpp @@ -1,6 +1,7 @@ #include "functor_json.h" #include "functioncolumn.h" #include "constantcolumn.h" +#include "json_lib.h" using namespace execplan; #include "rowgroup.h" @@ -62,6 +63,10 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP execplan::SPTP& funcParamPath) { bool isNullJS = false, isNullPath = false; + MEM_ROOT_DYNAMIC_ARRAY array; + IntType arrayCounters[JSON_DEPTH_LIMIT]; + int je_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; const utils::NullString& js = funcParamJS->data()->getStrVal(row, isNullJS); const utils::NullString& sjsp = funcParamPath->data()->getStrVal(row, isNullPath); @@ -70,21 +75,32 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP int error = 0; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &p.steps, sizeof(json_path_step_t), &p_steps, + JSON_DEPTH_LIMIT, 0, MYF(0)); if (json_path_setup(&p, getCharset(funcParamPath), (const uchar*)sjsp.str(), (const uchar*)sjsp.end())) return true; + JSONEgWrapper je(getCharset(funcParamJS), reinterpret_cast(js.str()), reinterpret_cast(js.end())); + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &je.stack, sizeof(int), &je_stack, + JSON_DEPTH_LIMIT, 0, MYF(0)); - currStep = p.steps; + currStep = (json_path_step_t*)p.steps.buffer; + + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &array, sizeof(int), &arrayCounters, + JSON_DEPTH_LIMIT, 0, MYF(0)); do { if (error) return true; - - IntType arrayCounters[JSON_DEPTH_LIMIT]; - if (json_find_path(&je, &p, &currStep, arrayCounters)) + if (json_find_path(&je, &p, &currStep, &array)) return true; if (json_read_value(&je)) diff --git a/utils/funcexp/jsonhelpers.cpp b/utils/funcexp/jsonhelpers.cpp index 99862d184a..fe9726df02 100644 --- a/utils/funcexp/jsonhelpers.cpp +++ b/utils/funcexp/jsonhelpers.cpp @@ -335,7 +335,7 @@ int cmpPartJSPath(const json_path_step_t* a, const json_path_step_t* aEnd, const int cmpJSPath(const json_path_t* a, const json_path_t* b, enum json_value_types vt, const int* arraySize) { - return cmpPartJSPath(a->steps + 1, a->last_step, b->steps + 1, b->last_step, vt, arraySize); + return cmpPartJSPath((json_path_step_t*)a->steps.buffer + 1, NULL, (json_path_step_t*)b->steps.buffer + 1, NULL, vt, arraySize); } int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards) diff --git a/utils/funcexp/jsonhelpers.h b/utils/funcexp/jsonhelpers.h index 7e11c574fc..63209f89c8 100644 --- a/utils/funcexp/jsonhelpers.h +++ b/utils/funcexp/jsonhelpers.h @@ -63,8 +63,14 @@ using IntType = uint; inline static int locateJSPath(json_engine_t& jsEg, JSONPath& path, int* jsErr = nullptr) { IntType arrayCounters[JSON_DEPTH_LIMIT]; - path.currStep = path.p.steps; - if (json_find_path(&jsEg, &path.p, &path.currStep, arrayCounters)) + MEM_ROOT_DYNAMIC_ARRAY array; + + mem_root_dynamic_array_init(NULL, PSI_INSTRUMENT_MEM | MY_INIT_BUFFER_USED | MY_BUFFER_NO_RESIZE, + &array, sizeof(int), &arrayCounters, + JSON_DEPTH_DEFAULT, 0, MYF(0)); + + path.currStep = (json_path_step_t*)path.p.steps.buffer; + if (json_find_path(&jsEg, &path.p, &path.currStep, &array)) { if (jsErr && jsEg.s.error) *jsErr = 1; @@ -90,6 +96,7 @@ inline const CHARSET_INFO* getCharset(execplan::SPTP& parm) inline void initJSEngine(json_engine_t& jsEg, const CHARSET_INFO* jsCS, const utils::NullString& js) { json_scan_start(&jsEg, jsCS, (const uchar*)js.str(), (const uchar*)js.end()); + memset(jsEg.stack.buffer, 0, JSON_DEPTH_LIMIT*jsEg.stack.size_of_element); } int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards = true);