diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:33:02 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:33:02 +0000 |
commit | 4fa488fb0159c629483b7994aa84e73926b132b9 (patch) | |
tree | 182a19db69cdcb92be54cc6a5b0b9bfab28f80fd /sql/item_jsonfunc.cc | |
parent | Adding debian version 1:10.11.6-2. (diff) | |
download | mariadb-4fa488fb0159c629483b7994aa84e73926b132b9.tar.xz mariadb-4fa488fb0159c629483b7994aa84e73926b132b9.zip |
Merging upstream version 1:10.11.7.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sql/item_jsonfunc.cc')
-rw-r--r-- | sql/item_jsonfunc.cc | 72 |
1 files changed, 56 insertions, 16 deletions
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index 590fde88..97d7b89f 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -911,7 +911,7 @@ static int alloc_tmp_paths(THD *thd, uint n_paths, { if (*tmp_paths == 0) { - MEM_ROOT *root= thd->stmt_arena->mem_root; + MEM_ROOT *root= thd->active_stmt_arena_to_use()->mem_root; *paths= (json_path_with_flags *) alloc_root(root, sizeof(json_path_with_flags) * n_paths); @@ -943,21 +943,47 @@ static void mark_constant_paths(json_path_with_flags *p, } -bool Item_json_str_multipath::fix_fields(THD *thd, Item **ref) +Item_json_str_multipath::~Item_json_str_multipath() { - return alloc_tmp_paths(thd, get_n_paths(), &paths, &tmp_paths) || - Item_str_func::fix_fields(thd, ref); + if (tmp_paths) + { + for (uint i= n_paths; i>0; i--) + tmp_paths[i-1].free(); + } } -void Item_json_str_multipath::cleanup() +bool Item_json_str_multipath::fix_fields(THD *thd, Item **ref) { - if (tmp_paths) + if (!tmp_paths) { - for (uint i= get_n_paths(); i>0; i--) - tmp_paths[i-1].free(); + /* + Remember the number of paths and allocate required memory on first time + the method fix_fields() is invoked. For prepared statements the method + fix_fields can be called several times for the same item because its + clean up is performed every item a prepared statement finishing its + execution. In result, the data member fixed is reset and the method + fix_field() is invoked on next time the same prepared statement be + executed. On the other side, any memory allocations on behalf of + the prepared statement must be performed only once on its first execution. + The data member tmp_path is kind a guard to do these activities only once + on first time the method fix_field() is called. + */ + n_paths= get_n_paths(); + + if (alloc_tmp_paths(thd, n_paths, &paths, &tmp_paths)) + return true; } - Item_str_func::cleanup(); + +#ifdef PROTECT_STATEMENT_MEMROOT + /* + Check that the number of paths remembered on first run of a statement + never changed later. + */ + DBUG_ASSERT(n_paths == get_n_paths()); +#endif + + return Item_str_func::fix_fields(thd, ref); } @@ -1498,10 +1524,19 @@ return_null: bool Item_func_json_contains_path::fix_fields(THD *thd, Item **ref) { - return alloc_tmp_paths(thd, arg_count-2, &paths, &tmp_paths) || - (p_found= (bool *) alloc_root(thd->mem_root, - (arg_count-2)*sizeof(bool))) == NULL || - Item_int_func::fix_fields(thd, ref); + /* + See comments on Item_json_str_multipath::fix_fields regarding + the aim of the condition 'if (!tmp_paths)'. + */ + if (!tmp_paths) + { + if (alloc_tmp_paths(thd, arg_count-2, &paths, &tmp_paths) || + (p_found= (bool *) alloc_root(thd->active_stmt_arena_to_use()->mem_root, + (arg_count-2)*sizeof(bool))) == NULL) + return true; + } + + return Item_int_func::fix_fields(thd, ref); } @@ -1514,8 +1549,7 @@ bool Item_func_json_contains_path::fix_length_and_dec(THD *thd) return Item_bool_func::fix_length_and_dec(thd); } - -void Item_func_json_contains_path::cleanup() +Item_func_json_contains_path::~Item_func_json_contains_path() { if (tmp_paths) { @@ -1523,7 +1557,6 @@ void Item_func_json_contains_path::cleanup() tmp_paths[i-1].free(); tmp_paths= 0; } - Item_int_func::cleanup(); } @@ -4088,6 +4121,13 @@ int Arg_comparator::compare_e_json_str_basic(Item *j, Item *s) return MY_TEST(sortcmp(res1, res2, compare_collation()) == 0); } +bool Item_func_json_arrayagg::fix_fields(THD *thd, Item **ref) +{ + bool res= Item_func_group_concat::fix_fields(thd, ref); + m_tmp_json.set_charset(collation.collation); + return res; +} + String *Item_func_json_arrayagg::get_str_from_item(Item *i, String *tmp) { |