Skip to content

Commit 7826e01

Browse files
author
Tor Didriksen
committed
Bug#19855522 ASSERTION `N < M_SIZE' FAILED. | ABORT IN BOUNDS_CHECKED_ARRAY
create_distinct_group() may need some extra space, so do a similar counting in setup_ref_array() to have enough space in st_select_lex::ref_pointer_array Also: shrinking an existing ref_pointer_array, as introduced by WL#5953 - Optimize away useless subquery clauses has to be reversed. The '*' wildcards are fixed in the prepare phase, but not in the execute phase.
1 parent 94862f7 commit 7826e01

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

sql/sql_lex.cc

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2521,6 +2521,28 @@ bool st_select_lex::setup_ref_array(THD *thd)
25212521
// find_order_in_list() may need some extra space, so multiply by two.
25222522
order_group_num*= 2;
25232523

2524+
// create_distinct_group() may need some extra space
2525+
const bool select_distinct= MY_TEST(options & SELECT_DISTINCT);
2526+
if (select_distinct)
2527+
{
2528+
uint bitcount= 0;
2529+
Item *item;
2530+
List_iterator<Item> li(item_list);
2531+
while ((item= li++))
2532+
{
2533+
/*
2534+
Same test as in create_distinct_group, when it pushes new items to the
2535+
end of ref_pointer_array. An extra test for 'fixed' which, at this
2536+
stage, will be true only for columns inserted for a '*' wildcard.
2537+
*/
2538+
if (item->fixed &&
2539+
item->type() == Item::FIELD_ITEM &&
2540+
item->field_type() == MYSQL_TYPE_BIT)
2541+
++bitcount;
2542+
}
2543+
order_group_num+= bitcount;
2544+
}
2545+
25242546
/*
25252547
We have to create array in prepared statement memory if it is
25262548
prepared statement
@@ -2543,23 +2565,14 @@ bool st_select_lex::setup_ref_array(THD *thd)
25432565
order_group_num));
25442566
if (!ref_pointer_array.is_null() && ref_pointer_array.size() >= n_elems)
25452567
{
2546-
/*
2547-
The Query may have been permanently transformed by removal of
2548-
ORDER BY or GROUP BY. Memory has already been allocated, but by
2549-
reducing the size of ref_pointer_array a tight bound is
2550-
maintained by Bounds_checked_array
2551-
*/
2552-
if (ref_pointer_array.size() > n_elems)
2553-
ref_pointer_array.resize(n_elems);
2554-
25552568
/*
25562569
We need to take 'n_sum_items' into account when allocating the array,
25572570
and this may actually increase during the optimization phase due to
25582571
MIN/MAX rewrite in Item_in_subselect::single_value_transformer.
25592572
In the usual case we can reuse the array from the prepare phase.
25602573
If we need a bigger array, we must allocate a new one.
25612574
*/
2562-
if (ref_pointer_array.size() == n_elems)
2575+
if (ref_pointer_array.size() >= n_elems)
25632576
return false;
25642577
}
25652578
/*

sql/sql_optimizer.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10054,6 +10054,7 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
1005410054
additional hidden field for grouping because later it will be
1005510055
converted to a LONG field. Original field will remain of the
1005610056
BIT type and will be returned to a client.
10057+
@note setup_ref_array() needs to account for the extra space.
1005710058
*/
1005810059
Item_field *new_item= new Item_field(thd, (Item_field*)item);
1005910060
int el= all_fields.elements;

0 commit comments

Comments
 (0)