diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc index 71377d3661d..a351e3fa308 100644 --- a/sql/sql_tvc.cc +++ b/sql/sql_tvc.cc @@ -227,7 +227,7 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, List_item *first_elem= li++; uint cnt= first_elem->elements; - Type_holder *holders; + Type_holder *holders= type_holders; if (cnt == 0) { @@ -238,32 +238,35 @@ bool table_value_constr::prepare(THD *thd, SELECT_LEX *sl, if (fix_fields_for_tvc(thd, li)) DBUG_RETURN(true); - if (!(holders= new (thd->stmt_arena->mem_root) Type_holder[cnt]) || - 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 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++) + if (!holders) { - /* 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); + holders= type_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 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; diff --git a/sql/sql_tvc.h b/sql/sql_tvc.h index 594a77af65c..cdd5f5262df 100644 --- a/sql/sql_tvc.h +++ b/sql/sql_tvc.h @@ -24,6 +24,7 @@ class Explain_query; class Item_func_in; class st_select_lex_unit; typedef class st_select_lex SELECT_LEX; +class Type_holder; /** @class table_value_constr @@ -38,6 +39,7 @@ public: List lists_of_values; select_result *result; SELECT_LEX *select_lex; + Type_holder *type_holders; enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE} have_query_plan; @@ -46,7 +48,7 @@ public: table_value_constr(List tvc_values, SELECT_LEX *sl, 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), select_options(select_options_arg) { };