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;
|
max_equal_elems= 0;
|
||||||
ref_pointer_array.reset();
|
ref_pointer_array.reset();
|
||||||
select_n_where_fields= 0;
|
select_n_where_fields= 0;
|
||||||
|
order_group_num= 0;
|
||||||
select_n_reserved= 0;
|
select_n_reserved= 0;
|
||||||
select_n_having_items= 0;
|
select_n_having_items= 0;
|
||||||
n_sum_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))
|
if (!((options & SELECT_DISTINCT) && !group_list.elements))
|
||||||
hidden_bit_fields= 0;
|
hidden_bit_fields= 0;
|
||||||
|
|
||||||
// find_order_in_list() may need some extra space, so multiply by two.
|
if (!order_group_num)
|
||||||
order_group_num*= 2;
|
order_group_num= order_group_num_arg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We have to create array in prepared statement memory if it is a
|
find_order_in_list() may need some extra space,
|
||||||
prepared statement
|
so multiply order_group_num by 2
|
||||||
*/
|
*/
|
||||||
Query_arena *arena= thd->stmt_arena;
|
uint n= n_sum_items +
|
||||||
const size_t n_elems= (n_sum_items +
|
n_child_sum_items +
|
||||||
n_child_sum_items +
|
item_list.elements +
|
||||||
item_list.elements +
|
select_n_reserved +
|
||||||
select_n_reserved +
|
select_n_having_items +
|
||||||
select_n_having_items +
|
select_n_where_fields +
|
||||||
select_n_where_fields +
|
order_group_num * 2 +
|
||||||
order_group_num +
|
hidden_bit_fields +
|
||||||
hidden_bit_fields +
|
fields_in_window_functions;
|
||||||
fields_in_window_functions) * (size_t) 5;
|
return n;
|
||||||
DBUG_ASSERT(n_elems % 5 == 0);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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())
|
if (!ref_pointer_array.is_null())
|
||||||
{
|
return false;
|
||||||
/*
|
Item **array= static_cast<Item**>(thd->stmt_arena->alloc(sizeof(Item*) *
|
||||||
We need to take 'n_sum_items' into account when allocating the array,
|
n_elems));
|
||||||
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));
|
|
||||||
if (likely(array != NULL))
|
if (likely(array != NULL))
|
||||||
ref_pointer_array= Ref_ptr_array(array, n_elems);
|
ref_pointer_array= Ref_ptr_array(array, n_elems);
|
||||||
|
|
||||||
return array == NULL;
|
return array == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,6 +1176,8 @@ public:
|
|||||||
and all inner subselects.
|
and all inner subselects.
|
||||||
*/
|
*/
|
||||||
uint select_n_where_fields;
|
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 */
|
/* reserved for exists 2 in */
|
||||||
uint select_n_reserved;
|
uint select_n_reserved;
|
||||||
/*
|
/*
|
||||||
@ -1416,6 +1418,7 @@ public:
|
|||||||
init_select();
|
init_select();
|
||||||
}
|
}
|
||||||
bool setup_ref_array(THD *thd, uint order_group_num);
|
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(THD *thd, String *str, enum_query_type query_type);
|
||||||
void print_item_list(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);
|
void print_set_clause(THD *thd, String *str, enum_query_type query_type);
|
||||||
|
Reference in New Issue
Block a user