MDEV-32225 Test case from opt_tvc.test fails with statement memory protection
Memory for type holders of the columns of a table value constructor must be allocated only once. Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
parent
1ee0d09a2b
commit
ab9b1461a0
@ -227,7 +227,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
|
|||||||
|
|
||||||
List_item *first_elem= li++;
|
List_item *first_elem= li++;
|
||||||
uint cnt= first_elem->elements;
|
uint cnt= first_elem->elements;
|
||||||
Type_holder *holders;
|
Type_holder *holders= type_holders;
|
||||||
|
|
||||||
if (cnt == 0)
|
if (cnt == 0)
|
||||||
{
|
{
|
||||||
@ -238,32 +238,35 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl,
|
|||||||
if (fix_fields_for_tvc(thd, li))
|
if (fix_fields_for_tvc(thd, li))
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
|
|
||||||
if (!(holders= new (thd->stmt_arena->mem_root) Type_holder[cnt]) ||
|
if (!holders)
|
||||||
join_type_handlers_for_tvc(thd, li, holders, cnt) ||
|
|
||||||
get_type_attributes_for_tvc(thd, li, holders,
|
|
||||||
lists_of_values.elements, cnt))
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
|
|
||||||
List_iterator_fast<Item> it(*first_elem);
|
|
||||||
Item *item;
|
|
||||||
Query_arena *arena, backup;
|
|
||||||
arena=thd->activate_stmt_arena_if_needed(&backup);
|
|
||||||
|
|
||||||
sl->item_list.empty();
|
|
||||||
for (uint pos= 0; (item= it++); pos++)
|
|
||||||
{
|
{
|
||||||
/* Error's in 'new' will be detected after loop */
|
holders= type_holders= new (thd->stmt_arena->mem_root) Type_holder[cnt];
|
||||||
Item_type_holder *new_holder= new (thd->mem_root)
|
if (!holders ||
|
||||||
Item_type_holder(thd, item, holders[pos].type_handler(),
|
join_type_handlers_for_tvc(thd, li, holders, cnt) ||
|
||||||
&holders[pos]/*Type_all_attributes*/,
|
get_type_attributes_for_tvc(thd, li, holders,
|
||||||
holders[pos].get_maybe_null());
|
lists_of_values.elements, cnt))
|
||||||
sl->item_list.push_back(new_holder);
|
DBUG_RETURN(true);
|
||||||
|
List_iterator_fast<Item> it(*first_elem);
|
||||||
|
Item *item;
|
||||||
|
Query_arena *arena, backup;
|
||||||
|
arena=thd->activate_stmt_arena_if_needed(&backup);
|
||||||
|
|
||||||
|
sl->item_list.empty();
|
||||||
|
for (uint pos= 0; (item= it++); pos++)
|
||||||
|
{
|
||||||
|
/* Error's in 'new' will be detected after loop */
|
||||||
|
Item_type_holder *new_holder= new (thd->mem_root)
|
||||||
|
Item_type_holder(thd, item, holders[pos].type_handler(),
|
||||||
|
&holders[pos]/*Type_all_attributes*/,
|
||||||
|
holders[pos].get_maybe_null());
|
||||||
|
sl->item_list.push_back(new_holder);
|
||||||
|
}
|
||||||
|
if (arena)
|
||||||
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
|
||||||
|
if (unlikely(thd->is_fatal_error))
|
||||||
|
DBUG_RETURN(true); // out of memory
|
||||||
}
|
}
|
||||||
if (arena)
|
|
||||||
thd->restore_active_arena(arena, &backup);
|
|
||||||
|
|
||||||
if (unlikely(thd->is_fatal_error))
|
|
||||||
DBUG_RETURN(true); // out of memory
|
|
||||||
|
|
||||||
result= tmp_result;
|
result= tmp_result;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ class Explain_query;
|
|||||||
class Item_func_in;
|
class Item_func_in;
|
||||||
class st_select_lex_unit;
|
class st_select_lex_unit;
|
||||||
typedef class st_select_lex SELECT_LEX;
|
typedef class st_select_lex SELECT_LEX;
|
||||||
|
class Type_holder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@class table_value_constr
|
@class table_value_constr
|
||||||
@ -38,6 +39,7 @@ public:
|
|||||||
List<List_item> lists_of_values;
|
List<List_item> lists_of_values;
|
||||||
select_result *result;
|
select_result *result;
|
||||||
SELECT_LEX *select_lex;
|
SELECT_LEX *select_lex;
|
||||||
|
Type_holder *type_holders;
|
||||||
|
|
||||||
enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE} have_query_plan;
|
enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE} have_query_plan;
|
||||||
|
|
||||||
@ -46,7 +48,7 @@ public:
|
|||||||
|
|
||||||
table_value_constr(List<List_item> tvc_values, SELECT_LEX *sl,
|
table_value_constr(List<List_item> tvc_values, SELECT_LEX *sl,
|
||||||
ulonglong select_options_arg) :
|
ulonglong select_options_arg) :
|
||||||
lists_of_values(tvc_values), result(0), select_lex(sl),
|
lists_of_values(tvc_values), result(0), select_lex(sl), type_holders(0),
|
||||||
have_query_plan(QEP_NOT_PRESENT_YET), explain(0),
|
have_query_plan(QEP_NOT_PRESENT_YET), explain(0),
|
||||||
select_options(select_options_arg)
|
select_options(select_options_arg)
|
||||||
{ };
|
{ };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user