mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.
This commit is contained in:
@ -1039,4 +1039,14 @@ count(distinct case when id<=63 then id end)
|
|||||||
63
|
63
|
||||||
drop table tb;
|
drop table tb;
|
||||||
SET @@tmp_table_size= @tmp_table_size_save;
|
SET @@tmp_table_size= @tmp_table_size_save;
|
||||||
|
#
|
||||||
|
# MDEV-14695: Assertion `n < m_size' failed in Bounds_checked_array<Element_type>::operator
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (b1 BIT, b2 BIT, b3 BIT, b4 BIT , b5 BIT, b6 BIT);
|
||||||
|
INSERT INTO t1 VALUES (1,0,0,1,0,1),(0,1,0,0,1,0);
|
||||||
|
SELECT DISTINCT b1+'0', b2+'0', b3+'0', b4+'0', b5+'0', b6 +'0' FROM t1;
|
||||||
|
b1+'0' b2+'0' b3+'0' b4+'0' b5+'0' b6 +'0'
|
||||||
|
1 0 0 1 0 1
|
||||||
|
0 1 0 0 1 0
|
||||||
|
DROP TABLE t1;
|
||||||
End of 5.5 tests
|
End of 5.5 tests
|
||||||
|
@ -790,4 +790,12 @@ drop table tb;
|
|||||||
|
|
||||||
SET @@tmp_table_size= @tmp_table_size_save;
|
SET @@tmp_table_size= @tmp_table_size_save;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-14695: Assertion `n < m_size' failed in Bounds_checked_array<Element_type>::operator
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (b1 BIT, b2 BIT, b3 BIT, b4 BIT , b5 BIT, b6 BIT);
|
||||||
|
INSERT INTO t1 VALUES (1,0,0,1,0,1),(0,1,0,0,1,0);
|
||||||
|
SELECT DISTINCT b1+'0', b2+'0', b3+'0', b4+'0', b5+'0', b6 +'0' FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
--echo End of 5.5 tests
|
--echo End of 5.5 tests
|
||||||
|
@ -6919,7 +6919,7 @@ static bool setup_natural_join_row_types(THD *thd,
|
|||||||
|
|
||||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||||
List<Item> *sum_func_list,
|
List<Item> *sum_func_list,
|
||||||
uint wild_num)
|
uint wild_num, uint *hidden_bit_fields)
|
||||||
{
|
{
|
||||||
if (!wild_num)
|
if (!wild_num)
|
||||||
return(0);
|
return(0);
|
||||||
@ -6960,7 +6960,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
|||||||
else if (insert_fields(thd, ((Item_field*) item)->context,
|
else if (insert_fields(thd, ((Item_field*) item)->context,
|
||||||
((Item_field*) item)->db_name,
|
((Item_field*) item)->db_name,
|
||||||
((Item_field*) item)->table_name, &it,
|
((Item_field*) item)->table_name, &it,
|
||||||
any_privileges))
|
any_privileges, hidden_bit_fields))
|
||||||
{
|
{
|
||||||
if (arena)
|
if (arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
@ -7425,7 +7425,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table,
|
|||||||
bool
|
bool
|
||||||
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
||||||
const char *table_name, List_iterator<Item> *it,
|
const char *table_name, List_iterator<Item> *it,
|
||||||
bool any_privileges)
|
bool any_privileges, uint *hidden_bit_fields)
|
||||||
{
|
{
|
||||||
Field_iterator_table_ref field_iterator;
|
Field_iterator_table_ref field_iterator;
|
||||||
bool found;
|
bool found;
|
||||||
@ -7545,6 +7545,9 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
|
|||||||
else
|
else
|
||||||
it->after(item); /* Add 'item' to the SELECT list. */
|
it->after(item); /* Add 'item' to the SELECT list. */
|
||||||
|
|
||||||
|
if (item->type() == Item::FIELD_ITEM && item->field_type() == MYSQL_TYPE_BIT)
|
||||||
|
(*hidden_bit_fields)++;
|
||||||
|
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
/*
|
/*
|
||||||
Set privilege information for the fields of newly created views.
|
Set privilege information for the fields of newly created views.
|
||||||
|
@ -154,11 +154,12 @@ bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
|
|||||||
enum trg_event_type event);
|
enum trg_event_type event);
|
||||||
bool insert_fields(THD *thd, Name_resolution_context *context,
|
bool insert_fields(THD *thd, Name_resolution_context *context,
|
||||||
const char *db_name, const char *table_name,
|
const char *db_name, const char *table_name,
|
||||||
List_iterator<Item> *it, bool any_privileges);
|
List_iterator<Item> *it, bool any_privileges,
|
||||||
|
uint *hidden_bit_fields);
|
||||||
void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
|
void make_leaves_list(THD *thd, List<TABLE_LIST> &list, TABLE_LIST *tables,
|
||||||
bool full_table_list, TABLE_LIST *boundary);
|
bool full_table_list, TABLE_LIST *boundary);
|
||||||
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
|
||||||
List<Item> *sum_func_list, uint wild_num);
|
List<Item> *sum_func_list, uint wild_num, uint * hidden_bit_fields);
|
||||||
bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||||
List<Item> &item, enum_mark_columns mark_used_columns,
|
List<Item> &item, enum_mark_columns mark_used_columns,
|
||||||
List<Item> *sum_func_list, List<Item> *pre_fix,
|
List<Item> *sum_func_list, List<Item> *pre_fix,
|
||||||
|
@ -760,7 +760,8 @@ l
|
|||||||
select_lex->leaf_tables, FALSE,
|
select_lex->leaf_tables, FALSE,
|
||||||
DELETE_ACL, SELECT_ACL, TRUE))
|
DELETE_ACL, SELECT_ACL, TRUE))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num)) ||
|
if ((wild_num && setup_wild(thd, table_list, field_list, NULL, wild_num,
|
||||||
|
&select_lex->hidden_bit_fields)) ||
|
||||||
setup_fields(thd, Ref_ptr_array(),
|
setup_fields(thd, Ref_ptr_array(),
|
||||||
field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
|
field_list, MARK_COLUMNS_READ, NULL, NULL, 0) ||
|
||||||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
|
||||||
|
@ -2126,6 +2126,7 @@ void st_select_lex::init_query()
|
|||||||
select_n_having_items= 0;
|
select_n_having_items= 0;
|
||||||
n_sum_items= 0;
|
n_sum_items= 0;
|
||||||
n_child_sum_items= 0;
|
n_child_sum_items= 0;
|
||||||
|
hidden_bit_fields= 0;
|
||||||
subquery_in_having= explicit_limit= 0;
|
subquery_in_having= explicit_limit= 0;
|
||||||
is_item_list_lookup= 0;
|
is_item_list_lookup= 0;
|
||||||
first_execution= 1;
|
first_execution= 1;
|
||||||
@ -2673,6 +2674,10 @@ 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 (!((options & SELECT_DISTINCT) && !group_list.elements))
|
||||||
|
hidden_bit_fields= 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;
|
||||||
|
|
||||||
@ -2687,7 +2692,8 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
|
|||||||
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) * 5;
|
order_group_num +
|
||||||
|
hidden_bit_fields) * 5;
|
||||||
if (!ref_pointer_array.is_null())
|
if (!ref_pointer_array.is_null())
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -862,6 +862,11 @@ public:
|
|||||||
uint select_n_where_fields;
|
uint select_n_where_fields;
|
||||||
/* reserved for exists 2 in */
|
/* reserved for exists 2 in */
|
||||||
uint select_n_reserved;
|
uint select_n_reserved;
|
||||||
|
/*
|
||||||
|
it counts the number of bit fields in the SELECT list. These are used when DISTINCT is
|
||||||
|
converted to a GROUP BY involving BIT fields.
|
||||||
|
*/
|
||||||
|
uint hidden_bit_fields;
|
||||||
enum_parsing_place parsing_place; /* where we are parsing expression */
|
enum_parsing_place parsing_place; /* where we are parsing expression */
|
||||||
enum_parsing_place context_analysis_place; /* where we are in prepare */
|
enum_parsing_place context_analysis_place; /* where we are in prepare */
|
||||||
bool with_sum_func; /* sum function indicator */
|
bool with_sum_func; /* sum function indicator */
|
||||||
|
@ -799,7 +799,9 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
|||||||
select_lex != select_lex->master_unit()->global_parameters())
|
select_lex != select_lex->master_unit()->global_parameters())
|
||||||
real_og_num+= select_lex->order_list.elements;
|
real_og_num+= select_lex->order_list.elements;
|
||||||
|
|
||||||
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num))
|
DBUG_ASSERT(select_lex->hidden_bit_fields == 0);
|
||||||
|
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num,
|
||||||
|
&select_lex->hidden_bit_fields))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
if (select_lex->setup_ref_array(thd, real_og_num))
|
if (select_lex->setup_ref_array(thd, real_og_num))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
@ -1474,6 +1474,7 @@ bool st_select_lex::cleanup()
|
|||||||
}
|
}
|
||||||
inner_refs_list.empty();
|
inner_refs_list.empty();
|
||||||
exclude_from_table_unique_test= FALSE;
|
exclude_from_table_unique_test= FALSE;
|
||||||
|
hidden_bit_fields= 0;
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user