Commit 4e259476 authored by Igor Babaev's avatar Igor Babaev

MDEV-32259 Test from win.test fails with statement memory protection

The function setup_windows() called at the prepare phase of processing a
select builds a list of all window specifications used in the select. This list
is built on the statement memory and it must be done only once.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
parent b0763f50
...@@ -2441,6 +2441,7 @@ void st_select_lex::init_query() ...@@ -2441,6 +2441,7 @@ void st_select_lex::init_query()
m_custom_agg_func_used= false; m_custom_agg_func_used= false;
window_specs.empty(); window_specs.empty();
window_funcs.empty(); window_funcs.empty();
is_win_spec_list_built= false;
tvc= 0; tvc= 0;
in_tvc= false; in_tvc= false;
versioned_tables= 0; versioned_tables= 0;
......
...@@ -1530,6 +1530,7 @@ class st_select_lex: public st_select_lex_node ...@@ -1530,6 +1530,7 @@ class st_select_lex: public st_select_lex_node
bool no_to_clones); bool no_to_clones);
List<Window_spec> window_specs; List<Window_spec> window_specs;
bool is_win_spec_list_built;
void prepare_add_window_spec(THD *thd); void prepare_add_window_spec(THD *thd);
bool add_window_def(THD *thd, LEX_CSTRING *win_name, LEX_CSTRING *win_ref, bool add_window_def(THD *thd, LEX_CSTRING *win_name, LEX_CSTRING *win_ref,
SQL_I_List<ORDER> win_partition_list, SQL_I_List<ORDER> win_partition_list,
......
...@@ -207,27 +207,33 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables, ...@@ -207,27 +207,33 @@ setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
DBUG_ENTER("setup_windows"); DBUG_ENTER("setup_windows");
List_iterator<Window_spec> it(win_specs); List_iterator<Window_spec> it(win_specs);
/* if (!thd->lex->current_select->is_win_spec_list_built)
Move all unnamed specifications after the named ones.
We could have avoided it if we had built two separate lists for
named and unnamed specifications.
*/
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
uint i = 0;
uint elems= win_specs.elements;
while ((win_spec= it++) && i++ < elems)
{ {
if (win_spec->name() == NULL)
/*
Move all unnamed specifications after the named ones.
We could have avoided it if we had built two separate lists for
named and unnamed specifications.
*/
Query_arena *arena, backup;
arena= thd->activate_stmt_arena_if_needed(&backup);
uint i = 0;
uint elems= win_specs.elements;
while ((win_spec= it++) && i++ < elems)
{ {
it.remove(); if (win_spec->name() == NULL)
win_specs.push_back(win_spec); {
it.remove();
win_specs.push_back(win_spec);
}
} }
} if (arena)
if (arena) thd->restore_active_arena(arena, &backup);
thd->restore_active_arena(arena, &backup);
it.rewind(); it.rewind();
thd->lex->current_select->is_win_spec_list_built= true;
}
List_iterator_fast<Window_spec> itp(win_specs); List_iterator_fast<Window_spec> itp(win_specs);
......
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