Skip to content

Commit 6f4534e

Browse files
committed
MDEV-14695: Assertion `n < m_size' failed in Bounds_checked_array<Element_type>::operator
In this issue we hit the assert because we are adding addition fields to the field JOIN::all_fields list. This is done because HEAP tables can't index BIT fields so we need to use an additional hidden field for grouping because later it will be converted to a LONG field. Original field will remain of the BIT type and will be returned. This happens when we convert DISTINCT to GROUP BY. The solution is to take into account the number of such hidden fields that would be added to the field JOIN::all_fields list while calculating the size of the ref_pointer_array.
1 parent d9f9cd1 commit 6f4534e

File tree

9 files changed

+45
-8
lines changed

9 files changed

+45
-8
lines changed

mysql-test/r/distinct.result

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,4 +1039,14 @@ count(distinct case when id<=63 then id end)
10391039
63
10401040
drop table tb;
10411041
SET @@tmp_table_size= @tmp_table_size_save;
1042+
#
1043+
# MDEV-14695: Assertion `n < m_size' failed in Bounds_checked_array<Element_type>::operator
1044+
#
1045+
CREATE TABLE t1 (b1 BIT, b2 BIT, b3 BIT, b4 BIT , b5 BIT, b6 BIT);
1046+
INSERT INTO t1 VALUES (1,0,0,1,0,1),(0,1,0,0,1,0);
1047+
SELECT DISTINCT b1+'0', b2+'0', b3+'0', b4+'0', b5+'0', b6 +'0' FROM t1;
1048+
b1+'0' b2+'0' b3+'0' b4+'0' b5+'0' b6 +'0'
1049+
1 0 0 1 0 1
1050+
0 1 0 0 1 0
1051+
DROP TABLE t1;
10421052
End of 5.5 tests

mysql-test/t/distinct.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,4 +790,12 @@ drop table tb;
790790

791791
SET @@tmp_table_size= @tmp_table_size_save;
792792

793+
--echo #
794+
--echo # MDEV-14695: Assertion `n < m_size' failed in Bounds_checked_array<Element_type>::operator
795+
--echo #
796+
797+
CREATE TABLE t1 (b1 BIT, b2 BIT, b3 BIT, b4 BIT , b5 BIT, b6 BIT);
798+
INSERT INTO t1 VALUES (1,0,0,1,0,1),(0,1,0,0,1,0);
799+
SELECT DISTINCT b1+'0', b2+'0', b3+'0', b4+'0', b5+'0', b6 +'0' FROM t1;
800+
DROP TABLE t1;
793801
--echo End of 5.5 tests

sql/sql_base.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6919,7 +6919,7 @@ static bool setup_natural_join_row_types(THD *thd,
69196919

69206920
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
69216921
List<Item> *sum_func_list,
6922-
uint wild_num)
6922+
uint wild_num, uint *hidden_bit_fields)
69236923
{
69246924
if (!wild_num)
69256925
return(0);
@@ -6960,7 +6960,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
69606960
else if (insert_fields(thd, ((Item_field*) item)->context,
69616961
((Item_field*) item)->db_name,
69626962
((Item_field*) item)->table_name, &it,
6963-
any_privileges))
6963+
any_privileges, hidden_bit_fields))
69646964
{
69656965
if (arena)
69666966
thd->restore_active_arena(arena, &backup);
@@ -7425,7 +7425,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
74257425
bool
74267426
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
74277427
const char *table_name, List_iterator<Item> *it,
7428-
bool any_privileges)
7428+
bool any_privileges, uint *hidden_bit_fields)
74297429
{
74307430
Field_iterator_table_ref field_iterator;
74317431
bool found;
@@ -7545,6 +7545,9 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
75457545
else
75467546
it->after(item); /* Add 'item' to the SELECT list. */
75477547

7548+
if (item->type() == Item::FIELD_ITEM && item->field_type() == MYSQL_TYPE_BIT)
7549+
(*hidden_bit_fields)++;
7550+
75487551
#ifndef NO_EMBEDDED_ACCESS_CHECKS
75497552
/*
75507553
Set privilege information for the fields of newly created views.

sql/sql_base.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,12 @@ bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
154154
enum trg_event_type event);
155155
bool insert_fields(THD *thd, Name_resolution_context *context,
156156
const char *db_name, const char *table_name,
157-
List_iterator<Item> *it, bool any_privileges);
157+
List_iterator<Item> *it, bool any_privileges,
158+
uint *hidden_bit_fields);
158159
void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
159160
bool full_table_list, TABLE_LIST *boundary);
160161
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
161-
List<Item> *sum_func_list, uint wild_num);
162+
List<Item> *sum_func_list, uint wild_num, uint * hidden_bit_fields);
162163
bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
163164
List<Item> &item, enum_mark_columns mark_used_columns,
164165
List<Item> *sum_func_list, List<Item> *pre_fix,

sql/sql_delete.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,8 @@ l
760760
select_lex->leaf_tables, FALSE,
761761
DELETE_ACL, SELECT_ACL, TRUE))
762762
DBUG_RETURN(TRUE);
763-
if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num)) ||
763+
if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num,
764+
&select_lex->hidden_bit_fields)) ||
764765
setup_fields(thd, Ref_ptr_array(),
765766
field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
766767
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||

sql/sql_lex.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2126,6 +2126,7 @@ void st_select_lex::init_query()
21262126
select_n_having_items= 0;
21272127
n_sum_items= 0;
21282128
n_child_sum_items= 0;
2129+
hidden_bit_fields= 0;
21292130
subquery_in_having= explicit_limit= 0;
21302131
is_item_list_lookup= 0;
21312132
first_execution= 1;
@@ -2673,6 +2674,10 @@ ulong st_select_lex::get_table_join_options()
26732674

26742675
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
26752676
{
2677+
2678+
if (!((options & SELECT_DISTINCT) && !group_list.elements))
2679+
hidden_bit_fields= 0;
2680+
26762681
// find_order_in_list() may need some extra space, so multiply by two.
26772682
order_group_num*= 2;
26782683

@@ -2687,7 +2692,8 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
26872692
select_n_reserved +
26882693
select_n_having_items +
26892694
select_n_where_fields +
2690-
order_group_num) * 5;
2695+
order_group_num +
2696+
hidden_bit_fields) * 5;
26912697
if (!ref_pointer_array.is_null())
26922698
{
26932699
/*

sql/sql_lex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,11 @@ class st_select_lex: public st_select_lex_node
862862
uint select_n_where_fields;
863863
/* reserved for exists 2 in */
864864
uint select_n_reserved;
865+
/*
866+
it counts the number of bit fields in the SELECT list. These are used when DISTINCT is
867+
converted to a GROUP BY involving BIT fields.
868+
*/
869+
uint hidden_bit_fields;
865870
enum_parsing_place parsing_place; /* where we are parsing expression */
866871
enum_parsing_place context_analysis_place; /* where we are in prepare */
867872
bool with_sum_func; /* sum function indicator */

sql/sql_select.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,9 @@ JOIN::prepare(TABLE_LIST *tables_init,
799799
select_lex != select_lex->master_unit()->global_parameters())
800800
real_og_num+= select_lex->order_list.elements;
801801

802-
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num))
802+
DBUG_ASSERT(select_lex->hidden_bit_fields == 0);
803+
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num,
804+
&select_lex->hidden_bit_fields))
803805
DBUG_RETURN(-1);
804806
if (select_lex->setup_ref_array(thd, real_og_num))
805807
DBUG_RETURN(-1);

sql/sql_union.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,6 +1474,7 @@ bool st_select_lex::cleanup()
14741474
}
14751475
inner_refs_list.empty();
14761476
exclude_from_table_unique_test= FALSE;
1477+
hidden_bit_fields= 0;
14771478
DBUG_RETURN(error);
14781479
}
14791480

0 commit comments

Comments
 (0)