Commit f4d2b576 authored by Tor Didriksen's avatar Tor Didriksen

Bug#16359402 CRASH WITH AGGREGATES: ASSERTION FAILED: N < M_SIZE

We need to take 'n_sum_items' into the calculation
when allocating the ref_ptr_array.
parent 17ee332d
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -1758,6 +1758,7 @@ void st_select_lex::init_query() ...@@ -1758,6 +1758,7 @@ void st_select_lex::init_query()
cond_count= between_count= with_wild= 0; cond_count= between_count= with_wild= 0;
max_equal_elems= 0; max_equal_elems= 0;
ref_pointer_array= 0; ref_pointer_array= 0;
ref_pointer_array_size= 0;
select_n_where_fields= 0; select_n_where_fields= 0;
select_n_having_items= 0; select_n_having_items= 0;
n_child_sum_items= 0; n_child_sum_items= 0;
...@@ -2134,9 +2135,6 @@ ulong st_select_lex::get_table_join_options() ...@@ -2134,9 +2135,6 @@ ulong st_select_lex::get_table_join_options()
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
{ {
if (ref_pointer_array)
return 0;
// find_order_in_list() may need some extra space, so multiply by two. // find_order_in_list() may need some extra space, so multiply by two.
order_group_num*= 2; order_group_num*= 2;
...@@ -2145,12 +2143,29 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) ...@@ -2145,12 +2143,29 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
prepared statement prepared statement
*/ */
Query_arena *arena= thd->stmt_arena; Query_arena *arena= thd->stmt_arena;
return (ref_pointer_array= const uint n_elems= (n_sum_items +
(Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items + n_child_sum_items +
item_list.elements + item_list.elements +
select_n_having_items + select_n_having_items +
select_n_where_fields + select_n_where_fields +
order_group_num)*5)) == 0; order_group_num) * 5;
if (ref_pointer_array != 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;
}
ref_pointer_array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems));
if (ref_pointer_array != NULL)
ref_pointer_array_size= n_elems;
return ref_pointer_array == NULL;
} }
......
/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -731,6 +731,7 @@ public: ...@@ -731,6 +731,7 @@ public:
Item *select_limit, *offset_limit; /* LIMIT clause parameters */ Item *select_limit, *offset_limit; /* LIMIT clause parameters */
// Arrays of pointers to top elements of all_fields list // Arrays of pointers to top elements of all_fields list
Item **ref_pointer_array; Item **ref_pointer_array;
size_t ref_pointer_array_size; // Number of elements in array.
/* /*
number of items in select_list and HAVING clause used to get number number of items in select_list and HAVING clause used to get number
......
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