mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-32245 Test from subselect.test fails with statement memory protection
With this patch st_select_lex::ref_pointer_array is never re-allocated. Approved by Oleksandr Byelkin <sanja@mariadb.com>
This commit is contained in:
@ -2413,6 +2413,7 @@ void st_select_lex::init_query()
|
||||
max_equal_elems= 0;
|
||||
ref_pointer_array.reset();
|
||||
select_n_where_fields= 0;
|
||||
order_group_num= 0;
|
||||
select_n_reserved= 0;
|
||||
select_n_having_items= 0;
|
||||
n_sum_items= 0;
|
||||
@ -2978,46 +2979,40 @@ ulong st_select_lex::get_table_join_options()
|
||||
}
|
||||
|
||||
|
||||
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
|
||||
uint st_select_lex::get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg)
|
||||
{
|
||||
|
||||
if (!((options & SELECT_DISTINCT) && !group_list.elements))
|
||||
hidden_bit_fields= 0;
|
||||
|
||||
// find_order_in_list() may need some extra space, so multiply by two.
|
||||
order_group_num*= 2;
|
||||
if (!order_group_num)
|
||||
order_group_num= order_group_num_arg;
|
||||
|
||||
/*
|
||||
We have to create array in prepared statement memory if it is a
|
||||
prepared statement
|
||||
find_order_in_list() may need some extra space,
|
||||
so multiply order_group_num by 2
|
||||
*/
|
||||
Query_arena *arena= thd->stmt_arena;
|
||||
const size_t n_elems= (n_sum_items +
|
||||
n_child_sum_items +
|
||||
item_list.elements +
|
||||
select_n_reserved +
|
||||
select_n_having_items +
|
||||
select_n_where_fields +
|
||||
order_group_num +
|
||||
hidden_bit_fields +
|
||||
fields_in_window_functions) * (size_t) 5;
|
||||
DBUG_ASSERT(n_elems % 5 == 0);
|
||||
uint n= n_sum_items +
|
||||
n_child_sum_items +
|
||||
item_list.elements +
|
||||
select_n_reserved +
|
||||
select_n_having_items +
|
||||
select_n_where_fields +
|
||||
order_group_num * 2 +
|
||||
hidden_bit_fields +
|
||||
fields_in_window_functions;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
|
||||
{
|
||||
uint n_elems= get_cardinality_of_ref_ptrs_slice(order_group_num) * 5;
|
||||
if (!ref_pointer_array.is_null())
|
||||
{
|
||||
/*
|
||||
We need to take 'n_sum_items' into account when allocating the array,
|
||||
and this may actually increase during the optimization phase due to
|
||||
MIN/MAX rewrite in Item_in_subselect::single_value_transformer.
|
||||
In the usual case we can reuse the array from the prepare phase.
|
||||
If we need a bigger array, we must allocate a new one.
|
||||
*/
|
||||
if (ref_pointer_array.size() >= n_elems)
|
||||
return false;
|
||||
}
|
||||
Item **array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems));
|
||||
return false;
|
||||
Item **array= static_cast<Item**>(thd->stmt_arena->alloc(sizeof(Item*) *
|
||||
n_elems));
|
||||
if (likely(array != NULL))
|
||||
ref_pointer_array= Ref_ptr_array(array, n_elems);
|
||||
|
||||
return array == NULL;
|
||||
}
|
||||
|
||||
|
@ -1176,6 +1176,8 @@ public:
|
||||
and all inner subselects.
|
||||
*/
|
||||
uint select_n_where_fields;
|
||||
/* Total number of elements in group by and order by lists */
|
||||
uint order_group_num;
|
||||
/* reserved for exists 2 in */
|
||||
uint select_n_reserved;
|
||||
/*
|
||||
@ -1416,6 +1418,7 @@ public:
|
||||
init_select();
|
||||
}
|
||||
bool setup_ref_array(THD *thd, uint order_group_num);
|
||||
uint get_cardinality_of_ref_ptrs_slice(uint order_group_num_arg);
|
||||
void print(THD *thd, String *str, enum_query_type query_type);
|
||||
void print_item_list(THD *thd, String *str, enum_query_type query_type);
|
||||
void print_set_clause(THD *thd, String *str, enum_query_type query_type);
|
||||
|
Reference in New Issue
Block a user