Commit 2f30b340 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug #14409015 MEMORY LEAK WHEN REFERENCING OUTER FIELD IN HAVING

When resolving outer fields, Item_field::fix_outer_fields()
creates new Item_refs for each execution of a prepared statement, so
these must be allocated in the runtime memroot. The memroot switching
before resolving JOIN::having causes these to be allocated in the
statement root, leaking memory for each PS execution.


sql/item_subselect.cc:
  addon, fix for 11829691, item could be created in
  runtime memroot, so we need to use real_item instead.
parent eede4140
...@@ -6010,7 +6010,12 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) ...@@ -6010,7 +6010,12 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
if (from_field != not_found_field) if (from_field != not_found_field)
{ {
Item_field* fld; Item_field* fld;
if (!(fld= new Item_field(thd, last_checked_context, from_field))) Query_arena backup, *arena;
arena= thd->activate_stmt_arena_if_needed(&backup);
fld= new Item_field(thd, last_checked_context, from_field);
if (arena)
thd->restore_active_arena(arena, &backup);
if (!fld)
goto error; goto error;
thd->change_item_tree(reference, fld); thd->change_item_tree(reference, fld);
mark_as_dependent(thd, last_checked_context->select_lex, mark_as_dependent(thd, last_checked_context->select_lex,
......
...@@ -1135,7 +1135,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -1135,7 +1135,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
} }
else else
{ {
Item *item= (Item*) select_lex->item_list.head(); Item *item= (Item*) select_lex->item_list.head()->real_item();
if (select_lex->table_list.elements) if (select_lex->table_list.elements)
{ {
......
...@@ -528,8 +528,6 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -528,8 +528,6 @@ JOIN::prepare(Item ***rref_pointer_array,
if (having) if (having)
{ {
Query_arena backup, *arena;
arena= thd->activate_stmt_arena_if_needed(&backup);
nesting_map save_allow_sum_func= thd->lex->allow_sum_func; nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
thd->where="having clause"; thd->where="having clause";
thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level; thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
...@@ -539,8 +537,6 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -539,8 +537,6 @@ JOIN::prepare(Item ***rref_pointer_array,
having->check_cols(1))); having->check_cols(1)));
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
select_lex->having= having; select_lex->having= having;
if (arena)
thd->restore_active_arena(arena, &backup);
if (having_fix_rc || thd->is_error()) if (having_fix_rc || thd->is_error())
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment