diff --git a/utils/funcexp/func_json_array_append.cpp b/utils/funcexp/func_json_array_append.cpp index c88d3f1fa..b482dba4a 100644 --- a/utils/funcexp/func_json_array_append.cpp +++ b/utils/funcexp/func_json_array_append.cpp @@ -28,13 +28,21 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b return ""; const CHARSET_INFO* cs = getCharset(fp[0]); - +#if MYSQL_VERSION_ID >= 120100 + int jsEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; +#endif json_engine_t jsEg; const uchar* arrEnd; size_t strRestLen; string retJS; retJS.reserve(js.length() + padding); +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif initJSPaths(paths, fp, 1, 2); utils::NullString tmpJS(js); @@ -44,6 +52,12 @@ string Func_json_array_append::getStrVal(rowgroup::Row& row, FunctionParm& fp, b const size_t jsLen = tmpJS.length(); JSONPath& path = paths[j]; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 7e62ebb47..04b371b4b 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" @@ -32,9 +34,19 @@ string Func_json_array_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, b json_engine_t jsEg; string retJS; retJS.reserve(js.length() + 8); +#if MYSQL_VERSION_ID >= 120100 + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + int jsEg_stack[JSON_DEPTH_LIMIT]; +#endif initJSPaths(paths, fp, 1, 2); +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + utils::NullString tmpJS(js); for (size_t i = 1, j = 0; i < fp.size(); i += 2, j++) { @@ -43,19 +55,37 @@ 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 || +#if MYSQL_VERSION_ID >= 120100 + 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; +#endif +#if MYSQL_VERSION_ID >= 120100 + if (parseJSPath(path, row, fp[i]) || (last_step - 1) < initial_step || + last_step->type != JSON_PATH_ARRAY) +#else + if (parseJSPath(path, row, fp[i]) || path.p.last_step - 1 < path.p.steps || path.p.last_step->type != JSON_PATH_ARRAY) +#endif { if (path.p.s.error == 0) path.p.s.error = SHOULD_END_WITH_ARRAY; goto error; } +#if MYSQL_VERSION_ID >= 120100 + path.p.last_step_idx--; +#else path.p.last_step--; +#endif } initJSEngine(jsEg, cs, tmpJS); +#if MYSQL_VERSION_ID < 120100 path.currStep = path.p.steps; +#endif int jsErr = 0; if (locateJSPath(jsEg, path, &jsErr)) @@ -82,7 +112,13 @@ 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 MYSQL_VERSION_ID >= 120100 + if (itemSize == (((json_path_step_t*) + (mem_root_dynamic_array_get_val(&path.p.steps, + path.p.last_step_idx)))[1].n_item)) +#else if (itemSize == path.p.last_step[1].n_item) +#endif { 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 f3fabd9a9..5fd4cc05e 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,11 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& type) { bool isNullJS = false, isNullVal = false; +#if MYSQL_VERSION_ID >= 120100 + int jsEg_stack[JSON_DEPTH_LIMIT], valEg_stack[JSON_DEPTH_LIMIT]; + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; +#endif + const auto& js = fp[0]->data()->getStrVal(row, isNullJS); const auto& val = fp[1]->data()->getStrVal(row, isNullVal); if (isNullJS || isNullVal) @@ -182,10 +188,21 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, } json_engine_t jsEg; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif initJSEngine(jsEg, getCharset(fp[0]), js); if (fp.size() > 2) { +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + if (!path.parsed && parseJSPath(path, row, fp[2], false)) goto error; @@ -194,6 +211,11 @@ bool Func_json_contains::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, } json_engine_t valEg; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif 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 51cd4abf3..f9f273408 100644 --- a/utils/funcexp/func_json_contains_path.cpp +++ b/utils/funcexp/func_json_contains_path.cpp @@ -65,12 +65,21 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul if (paths.size() == 0) hasFound.assign(argSize, false); +#if MYSQL_VERSION_ID >= SOME_NUM + vector> p_steps_arr(paths.size(), vector(32)); +#endif + for (size_t i = 2; i < fp.size(); i++) { JSONPath& path = paths[i - 2]; if (!path.parsed) { +#if MYSQL_VERSION_ID >= SOME_NUM + 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)); +#endif if (parseJSPath(path, row, fp[i])) { isNull = true; @@ -84,6 +93,19 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul json_engine_t jsEg; json_path_t p; + +#if MYSQL_VERSION_ID >= SOME_NUM + 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, + &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)); +#endif + json_get_path_start(&jsEg, getCharset(fp[0]), (const uchar*)js.data(), (const uchar*)js.data() + js.size(), &p); @@ -99,12 +121,20 @@ bool Func_json_contains_path::getBoolVal(Row& row, FunctionParm& fp, bool& isNul while (json_get_path_next(&jsEg, &p) == 0) { #ifdef MYSQL_GE_1009 +#if MYSQL_VERSION_ID >= SOME_NUM + 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 + (last_step - (json_path_step_t*)p.steps.buffer))) +#else if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && json_skip_array_and_count(&jsEg, arrayCounters + (p.last_step - p.steps))) { result = true; break; } +#endif #endif for (int restSize = argSize, curr = 0; restSize > 0; restSize--, curr++) diff --git a/utils/funcexp/func_json_depth.cpp b/utils/funcexp/func_json_depth.cpp index 88d52c8cf..7aa5ce13e 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,14 @@ int64_t Func_json_depth::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& i int depth = 0, currDepth = 0; bool incDepth = true; - json_engine_t jsEg; + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif initJSEngine(jsEg, getCharset(fp[0]), js); do diff --git a/utils/funcexp/func_json_equals.cpp b/utils/funcexp/func_json_equals.cpp index fa0cc7db8..b963b04b3 100644 --- a/utils/funcexp/func_json_equals.cpp +++ b/utils/funcexp/func_json_equals.cpp @@ -27,6 +27,19 @@ CalpontSystemCatalog::ColType Func_json_equals::operationType(FunctionParm& fp, bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& type) { +#if MYSQL_VERSION_ID >= 120100 + 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_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)); +#endif + // auto release the DYNAMIC_STRING using DynamicString = unique_ptr; @@ -56,13 +69,27 @@ bool Func_json_equals::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, const string_view js2 = js2_ns.unsafeStringRef(); bool result = false; + +#if MYSQL_VERSION_ID >= 120100 + if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0]), NULL, &je, &array)) +#else if (json_normalize(str1.get(), js1.data(), js1.size(), getCharset(fp[0]))) +#endif { isNull = true; return result; } +#if MYSQL_VERSION_ID >= 120100 + memset(je_stack, 0, sizeof(je_stack)); + memset(buffer_array, 0, sizeof(buffer_array)); +#endif + +#if MYSQL_VERSION_ID >= 120100 + if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1]), NULL, &je, &array)) +#else if (json_normalize(str2.get(), js2.data(), js2.size(), getCharset(fp[1]))) +#endif { isNull = true; return result; diff --git a/utils/funcexp/func_json_exists.cpp b/utils/funcexp/func_json_exists.cpp index b76e86ae8..b1847dc64 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,21 @@ bool Func_json_exists::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, int jsErr = 0; json_engine_t jsEg; - initJSEngine(jsEg, getCharset(fp[0]), js); +#if MYSQL_VERSION_ID >= 120100 + 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)); + + 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)); +#endif + + initJSEngine(jsEg, getCharset(fp[0]), js); 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 1613717e8..c54745ae0 100644 --- a/utils/funcexp/func_json_extract.cpp +++ b/utils/funcexp/func_json_extract.cpp @@ -36,11 +36,35 @@ int Func_json_extract::doExtract(Row& row, FunctionParm& fp, json_value_types* t const size_t argSize = fp.size(); string tmp; + +#if MYSQL_VERSION_ID >= 120100 + int jsEg_stack[JSON_DEPTH_LIMIT], savJSEg_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, + &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)); +#endif + initJSPaths(paths, fp, 1, 1); + vector> p_steps_arr(paths.size(), vector(32)); for (size_t i = 1; i < argSize; i++) { JSONPath& path = paths[i - 1]; + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif path.p.types_used = JSON_PATH_KEY_NULL; if (!path.parsed && parseJSPath(path, row, fp[i])) return 1; @@ -71,8 +95,14 @@ 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 +#if MYSQL_VERSION_ID >= 120100 + 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)))) +#else + if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && + json_skip_array_and_count(&jsEg, arrayCounter + (last_step - (json_path_step_t*)(p.steps.buffer)))) +#endif return 1; #endif diff --git a/utils/funcexp/func_json_format.cpp b/utils/funcexp/func_json_format.cpp index 178474935..de05c8a44 100644 --- a/utils/funcexp/func_json_format.cpp +++ b/utils/funcexp/func_json_format.cpp @@ -47,7 +47,17 @@ string Func_json_format::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i } json_engine_t jsEg; + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 b10a8314c..84a8f9594 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" @@ -30,6 +31,11 @@ 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; +#if MYSQL_VERSION_ID >= 120100 + json_path_step_t p_steps[JSON_DEPTH_LIMIT]; + int jsEg_stack[JSON_DEPTH_LIMIT]; +#endif + json_engine_t jsEg; int jsErr = 0; @@ -46,8 +52,16 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i { const char* rawJS = tmpJS.str(); const size_t jsLen = tmpJS.length(); - JSONPath& path = paths[j]; + +#if MYSQL_VERSION_ID >= 120100 + json_path_step_t *curr_last_step= nullptr; + 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)); +#endif + const json_path_step_t* lastStep; const char* valEnd; @@ -56,14 +70,36 @@ string Func_json_insert::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (parseJSPath(path, row, fp[i], false)) goto error; +#if MYSQL_VERSION_ID >= 120100 + path.p.last_step_idx--; +#else path.p.last_step--; +#endif } +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + initJSEngine(jsEg, cs, tmpJS); + +#if MYSQL_VERSION_ID >= 120100 + 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)) +#else if (path.p.last_step < path.p.steps) +#endif goto v_found; +#if MYSQL_VERSION_ID >= 120100 + 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)) +#else if (path.p.last_step >= path.p.steps && locateJSPath(jsEg, path, &jsErr)) +#endif { if (jsErr) goto error; @@ -73,7 +109,12 @@ 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; +#if MYSQL_VERSION_ID >= 120100 + lastStep = curr_last_step + 1; +#else + lastStep = curr_last_step + 1; +#endif + 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 ac17750b9..a15613719 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,26 @@ string Func_json_keys::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN IntType keySize = 0; string ret; json_engine_t jsEg; + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif initJSEngine(jsEg, getCharset(fp[0]), js); + if (fp.size() > 1) { +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 99763ef72..3a0050db3 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" @@ -31,10 +32,24 @@ int64_t Func_json_length::getIntVal(rowgroup::Row& row, FunctionParm& fp, bool& int length = 0; int err; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + initJSEngine(jsEg, getCharset(fp[0]), js); if (fp.size() > 1) { +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif 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 4041571e7..0ff666b49 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" @@ -225,6 +226,17 @@ string Func_json_merge::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& is json_engine_t jsEg1, jsEg2; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 05561e193..af40c3c7a 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" @@ -277,6 +278,9 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo json_engine_t jsEg1, jsEg2; jsEg1.s.error = jsEg2.s.error = 0; +#if MYSQL_VERSION_ID >= 120100 + int jsEg1_stack[JSON_DEPTH_LIMIT], jsEg2_stack[JSON_DEPTH_LIMIT]; +#endif utils::NullString tmpJS(js); string retJS; @@ -290,6 +294,12 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo goto next; } +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + initJSEngine(jsEg2, getCharset(fp[i]), js2); if (hasNullArg) @@ -304,6 +314,12 @@ string Func_json_merge_patch::getStrVal(rowgroup::Row& row, FunctionParm& fp, bo goto next; } +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 6dbf28d2e..00a91f575 100644 --- a/utils/funcexp/func_json_normalize.cpp +++ b/utils/funcexp/func_json_normalize.cpp @@ -25,6 +25,20 @@ CalpontSystemCatalog::ColType Func_json_normalize::operationType(FunctionParm& f 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; + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + const auto js_ns = fp[0]->data()->getStrVal(row, isNull); if (isNull) return ""; @@ -36,8 +50,12 @@ string Func_json_normalize::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool if (init_dynamic_string(str.get(), NULL, 0, 0)) goto error; +#if MYSQL_VERSION_ID >= 120100 + if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0]), NULL, &je, &array)) +#else if (json_normalize(str.get(), js.data(), js.size(), getCharset(fp[0]))) goto error; +#endif return str->str; diff --git a/utils/funcexp/func_json_overlaps.cpp b/utils/funcexp/func_json_overlaps.cpp index 3df4abc9d..0768c7af0 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,27 @@ bool Func_json_overlaps::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& type) { bool isNullJS1 = false, isNullJS2 = false; + +#if MYSQL_VERSION_ID >= 120100 + int jsEg1_stack[JSON_DEPTH_LIMIT], jsEg2_stack[JSON_DEPTH_LIMIT]; +#endif + 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; + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 98558869c..7d9dcd34d 100644 --- a/utils/funcexp/func_json_remove.cpp +++ b/utils/funcexp/func_json_remove.cpp @@ -30,6 +30,14 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i json_engine_t jsEg; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + int jsErr = 0; json_string_t keyName; const CHARSET_INFO* cs = getCharset(fp[0]); @@ -49,13 +57,28 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i const char *remStart = nullptr, *remEnd = nullptr; IntType itemSize = 0; +#if MYSQL_VERSION_ID >= 120100 + json_path_step_t *curr_last_step= nullptr; + 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)); +#endif + if (!path.parsed) { if (parseJSPath(path, row, fp[i], false)) goto error; - path.p.last_step--; +#if MYSQL_VERSION_ID >= 120100 + 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)) +#else + path.p.last_step--; if (path.p.last_step < path.p.steps) +#endif { path.p.s.error = TRIVIAL_PATH_NOT_ALLOWED; goto error; @@ -64,7 +87,11 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i initJSEngine(jsEg, cs, tmpJS); +#if MYSQL_VERSION_ID >= 120100 + if (curr_last_step < (json_path_step_t*)(path.p.steps.buffer)) +#else if (path.p.last_step < path.p.steps) +#endif goto v_found; if (locateJSPath(jsEg, path, &jsErr) && jsErr) @@ -73,7 +100,12 @@ string Func_json_remove::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i if (json_read_value(&jsEg)) goto error; +#if MYSQL_VERSION_ID >= 120100 + lastStep = curr_last_step + 1; +#else lastStep = path.p.last_step + 1; +#endif + 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 c7cb6830e..0df252a7a 100644 --- a/utils/funcexp/func_json_search.cpp +++ b/utils/funcexp/func_json_search.cpp @@ -15,17 +15,31 @@ using namespace joblist; #include "jsonhelpers.h" using namespace funcexp::helpers; +#include "my_sys.h" + namespace { +#if MYSQL_VERSION_ID >= 120100 +static bool appendJSPath(string& ret, json_path_t* p) +#else static bool appendJSPath(string& ret, const json_path_t* p) +#endif { const json_path_step_t* c; +#if MYSQL_VERSION_ID >= 120100 + json_path_step_t *last_step= (json_path_step_t*)(mem_root_dynamic_array_get_val(&p->steps, p->last_step_idx)); +#endif + try { ret.append("\"$"); +#if MYSQL_VERSION_ID >= 120100 + for (c = ((json_path_step_t*)(p->steps.buffer)) + 1; c <= last_step; c++) +#else for (c = p->steps + 1; c <= p->last_step; c++) +#endif { if (c->type & JSON_PATH_KEY) { @@ -145,13 +159,34 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i #endif int pathFound = 0; +#if MYSQL_VERSION_ID >= 120100 + json_path_step_t savPath_steps[JSON_DEPTH_LIMIT], p_steps[JSON_DEPTH_LIMIT]; + int jsEg_stack[JSON_DEPTH_LIMIT]; +#endif + initJSPaths(paths, fp, 4, 1); +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + for (size_t i = 4; i < fp.size(); i++) { JSONPath& path = paths[i - 4]; if (!path.parsed) { +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif if (parseJSPath(path, row, fp[i])) goto error; #ifdef MYSQL_GE_1009 @@ -160,15 +195,24 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i } } +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 MYSQL_VERSION_ID >= 120100 if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && - json_skip_array_and_count(&jsEg, arrayCounter + (p.last_step - p.steps))) - goto error; + 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))) +#else + if (hasNegPath && jsEg.value_type == JSON_VALUE_ARRAY && + 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))) #endif + goto error; if (json_value_scalar(&jsEg)) { @@ -182,8 +226,11 @@ string Func_json_search::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& i ++pathFound; if (pathFound == 1) { - savPath = p; - savPath.last_step = savPath.steps + (p.last_step - p.steps); + +#if MYSQL_VERSION_ID < 120010 + savPath.last_step = savPath.steps + (p.last_step - p.steps); +#endif + } else { diff --git a/utils/funcexp/func_json_type.cpp b/utils/funcexp/func_json_type.cpp index 333c01179..55f225bea 100644 --- a/utils/funcexp/func_json_type.cpp +++ b/utils/funcexp/func_json_type.cpp @@ -29,6 +29,14 @@ string Func_json_type::getStrVal(rowgroup::Row& row, FunctionParm& fp, bool& isN json_engine_t jsEg; string result; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 5063022fe..71bd8fc95 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; @@ -30,6 +31,14 @@ std::string Func_json_unquote::getStrVal(rowgroup::Row& row, FunctionParm& fp, b int strLen; const CHARSET_INFO* cs = type.getCharset(); + +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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 e0a010d59..3b52378ce 100644 --- a/utils/funcexp/func_json_valid.cpp +++ b/utils/funcexp/func_json_valid.cpp @@ -25,10 +25,18 @@ CalpontSystemCatalog::ColType Func_json_valid::operationType(FunctionParm& fp, bool Func_json_valid::getBoolVal(Row& row, FunctionParm& fp, bool& isNull, CalpontSystemCatalog::ColType& type) { + json_engine_t je; +#if MYSQL_VERSION_ID >= 120100 + int je_stack[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_DEFAULT, 0, MYF(0)); +#endif + 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 265bfc40f..32427fc79 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" @@ -63,6 +64,13 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP { bool isNullJS = false, isNullPath = false; +#if MYSQL_VERSION_ID >= 120100 + 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]; +#endif + const utils::NullString& js = funcParamJS->data()->getStrVal(row, isNullJS); const utils::NullString& sjsp = funcParamPath->data()->getStrVal(row, isNullPath); if (isNullJS || isNullPath) @@ -70,21 +78,44 @@ bool JSONPathWrapper::extract(std::string& ret, rowgroup::Row& row, execplan::SP int error = 0; +#if MYSQL_VERSION_ID >= 120100 + 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)); +#endif + 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())); +#if MYSQL_VERSION_ID >= 120100 + 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 = (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)); +#else currStep = p.steps; +#endif do { if (error) return true; +#if MYSQL_VERSION_ID >= 120100 + if (json_find_path(&je, &p, &currStep, &array)) +#else IntType arrayCounters[JSON_DEPTH_LIMIT]; if (json_find_path(&je, &p, &currStep, arrayCounters)) +#endif return true; if (json_read_value(&je)) diff --git a/utils/funcexp/jsonhelpers.cpp b/utils/funcexp/jsonhelpers.cpp index 042a3f33a..b63d2c6f9 100644 --- a/utils/funcexp/jsonhelpers.cpp +++ b/utils/funcexp/jsonhelpers.cpp @@ -334,7 +334,11 @@ 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) { +#if MYSQL_VERSION_ID >= 120100 + return cmpPartJSPath((json_path_step_t*)a->steps.buffer + 1, NULL, (json_path_step_t*)b->steps.buffer + 1, NULL, vt, arraySize); +#else return cmpPartJSPath(a->steps + 1, a->last_step, b->steps + 1, b->last_step, vt, arraySize); +#endif } 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 ca8b62a66..8e1f00c49 100644 --- a/utils/funcexp/jsonhelpers.h +++ b/utils/funcexp/jsonhelpers.h @@ -64,8 +64,20 @@ using IntType = uint; inline static int locateJSPath(json_engine_t& jsEg, JSONPath& path, int* jsErr = nullptr) { IntType arrayCounters[JSON_DEPTH_LIMIT]; + +#if MYSQL_VERSION_ID >= 120100 + 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)) +#else path.currStep = path.p.steps; if (json_find_path(&jsEg, &path.p, &path.currStep, arrayCounters)) +#endif { if (jsErr && jsEg.s.error) *jsErr = 1; @@ -91,6 +103,9 @@ 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()); +#if MYSQL_VERSION_ID >= 120100 + memset(jsEg.stack.buffer, 0, JSON_DEPTH_LIMIT*jsEg.stack.size_of_element); +#endif } int parseJSPath(JSONPath& path, rowgroup::Row& row, execplan::SPTP& parm, bool wildcards = true);