Commit 80cccd41 authored by sergefp@mysql.com's avatar sergefp@mysql.com

BUG#21477 "memory overruns for certain kinds of subqueries":

make st_select_lex::setup_ref_array() take into account that 
Item_sum-descendant objects located within descendant SELECTs
may be added into ref_pointer_array.
parent f0793773
...@@ -290,7 +290,9 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): ...@@ -290,7 +290,9 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
void Item_sum::mark_as_sum_func() void Item_sum::mark_as_sum_func()
{ {
current_thd->lex->current_select->with_sum_func= 1; SELECT_LEX *cur_select= current_thd->lex->current_select;
cur_select->n_sum_items++;
cur_select->with_sum_func= 1;
with_sum_func= 1; with_sum_func= 1;
} }
......
...@@ -1521,10 +1521,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) ...@@ -1521,10 +1521,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
*/ */
Query_arena *arena= thd->stmt_arena; Query_arena *arena= thd->stmt_arena;
return (ref_pointer_array= return (ref_pointer_array=
(Item **)arena->alloc(sizeof(Item*) * (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
(item_list.elements + item_list.elements +
select_n_having_items + select_n_having_items +
order_group_num)* 5)) == 0; order_group_num)*5)) == 0;
} }
......
...@@ -548,6 +548,12 @@ public: ...@@ -548,6 +548,12 @@ public:
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
/* TRUE when having fix field called in processing of this SELECT */ /* TRUE when having fix field called in processing of this SELECT */
bool having_fix_field; bool having_fix_field;
/* Number of Item_sum-derived objects in this SELECT */
uint n_sum_items;
/* Number of Item_sum-derived objects in children and descendant SELECTs */
uint n_child_sum_items;
/* explicit LIMIT clause was used */ /* explicit LIMIT clause was used */
bool explicit_limit; bool explicit_limit;
/* /*
...@@ -640,7 +646,7 @@ public: ...@@ -640,7 +646,7 @@ public:
bool test_limit(); bool test_limit();
friend void lex_start(THD *thd, uchar *buf, uint length); friend void lex_start(THD *thd, uchar *buf, uint length);
st_select_lex() {} st_select_lex() : n_sum_items(0), n_child_sum_items(0) {}
void make_empty_select() void make_empty_select()
{ {
init_query(); init_query();
......
...@@ -8927,8 +8927,10 @@ subselect_end: ...@@ -8927,8 +8927,10 @@ subselect_end:
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->pop_context(); lex->pop_context();
SELECT_LEX *child= lex->current_select;
lex->current_select = lex->current_select->return_after_parsing(); lex->current_select = lex->current_select->return_after_parsing();
lex->nest_level--; lex->nest_level--;
lex->current_select->n_child_sum_items += child->n_sum_items;
}; };
/************************************************************************** /**************************************************************************
......
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