1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merge branch '10.5' into bb-10.5-release

This commit is contained in:
Oleksandr Byelkin
2022-02-09 08:57:41 +01:00
21 changed files with 241 additions and 68 deletions

View File

@ -1589,7 +1589,8 @@ bool JOIN::prepare_stage2()
#endif
if (select_lex->olap == ROLLUP_TYPE && rollup_init())
goto err;
if (alloc_func_list())
if (alloc_func_list() ||
make_sum_func_list(all_fields, fields_list, false))
goto err;
res= FALSE;
@ -2204,7 +2205,21 @@ JOIN::optimize_inner()
If all items were resolved by opt_sum_query, there is no need to
open any tables.
*/
if ((res=opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds)))
/*
The following resetting and restoring of sum_funcs is needed to
go around a bug in spider where it assumes that
make_sum_func_list() has not been called yet and do logical
choices based on this if special handling of min/max functions should
be done. We disable this special handling while we are trying to find
out if we can replace MIN/MAX values with constants.
*/
Item_sum **save_func_sums= sum_funcs, *tmp_sum_funcs= 0;
sum_funcs= &tmp_sum_funcs;
res= opt_sum_query(thd, select_lex->leaf_tables, all_fields, conds);
sum_funcs= save_func_sums;
if (res)
{
DBUG_ASSERT(res >= 0);
if (res == HA_ERR_KEY_NOT_FOUND)
@ -2776,13 +2791,15 @@ int JOIN::optimize_stage2()
calc_group_buffer(this, group_list);
}
if (test_if_subpart(group_list, order) ||
(!group_list && tmp_table_param.sum_func_count))
{
/*
We can ignore ORDER BY if it's a prefix of the GROUP BY list
(as MariaDB is by default sorting on GROUP BY) or
if there is no GROUP BY and aggregate functions are used
(as the result will only contain one row).
*/
if (order && (test_if_subpart(group_list, order) ||
(!group_list && tmp_table_param.sum_func_count)))
order=0;
if (is_indexed_agg_distinct(this, NULL))
sort_and_group= 0;
}
// Can't use sort on head table if using join buffering
if (full_join || hash_join)
@ -2814,7 +2831,6 @@ int JOIN::optimize_stage2()
if (select_lex->have_window_funcs())
simple_order= FALSE;
/*
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
whose columns are required to be returned in a sorted order, then
@ -3548,7 +3564,7 @@ bool JOIN::make_aggr_tables_info()
// for the first table
if (group_list || tmp_table_param.sum_func_count)
{
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true))
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true))
DBUG_RETURN(true);
if (prepare_sum_aggregators(sum_funcs,
!join_tab->is_using_agg_loose_index_scan()))
@ -3658,7 +3674,7 @@ bool JOIN::make_aggr_tables_info()
last_tab->all_fields= &tmp_all_fields3;
last_tab->fields= &tmp_fields_list3;
}
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true, true))
if (make_sum_func_list(*curr_all_fields, *curr_fields_list, true))
DBUG_RETURN(true);
if (prepare_sum_aggregators(sum_funcs,
!join_tab ||
@ -3854,8 +3870,6 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
}
else
{
if (make_sum_func_list(all_fields, fields_list, false))
goto err;
if (prepare_sum_aggregators(sum_funcs,
!join_tab->is_using_agg_loose_index_scan()))
goto err;
@ -7097,8 +7111,7 @@ void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
to loose index scan.
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
Check if the query is a subject to AGGFN(DISTINCT) using loose index scan
(QUICK_GROUP_MIN_MAX_SELECT).
Optionally (if out_args is supplied) will push the arguments of
AGGFN(DISTINCT) to the list
@ -7131,14 +7144,11 @@ is_indexed_agg_distinct(JOIN *join, List<Item_field> *out_args)
Item_sum **sum_item_ptr;
bool result= false;
if (join->table_count != 1 || /* reference more than 1 table */
if (join->table_count != 1 || /* reference more than 1 table */
join->select_distinct || /* or a DISTINCT */
join->select_lex->olap == ROLLUP_TYPE) /* Check (B3) for ROLLUP */
return false;
if (join->make_sum_func_list(join->all_fields, join->fields_list, true))
return false;
Bitmap<MAX_FIELDS> first_aggdistinct_fields;
bool first_aggdistinct_fields_initialized= false;
for (sum_item_ptr= join->sum_funcs; *sum_item_ptr; sum_item_ptr++)
@ -7240,16 +7250,23 @@ add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
while ((item= select_items_it++))
item->walk(&Item::collect_item_field_processor, 0, &indexed_fields);
}
else if (join->tmp_table_param.sum_func_count &&
is_indexed_agg_distinct(join, &indexed_fields))
else if (!join->tmp_table_param.sum_func_count ||
!is_indexed_agg_distinct(join, &indexed_fields))
{
join->sort_and_group= 1;
}
else
/*
There where no GROUP BY fields and also either no aggregate
functions or not all aggregate functions where used with the
same DISTINCT (or MIN() / MAX() that works similarly).
Nothing to do there.
*/
return;
}
if (indexed_fields.elements == 0)
{
/* There where no index we could use to satisfy the GROUP BY */
return;
}
/* Intersect the keys of all group fields. */
cur_item= indexed_fields_it++;
@ -25693,16 +25710,13 @@ bool JOIN::alloc_func_list()
bool JOIN::make_sum_func_list(List<Item> &field_list,
List<Item> &send_result_set_metadata,
bool before_group_by, bool recompute)
bool before_group_by)
{
List_iterator_fast<Item> it(field_list);
Item_sum **func;
Item *item;
DBUG_ENTER("make_sum_func_list");
if (*sum_funcs && !recompute)
DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */
func= sum_funcs;
while ((item=it++))
{
@ -25849,7 +25863,7 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
Change all funcs to be fields in tmp table.
@param thd THD pointer
@param ref_pointer_array array of pointers to top elements of filed list
@param ref_pointer_array array of pointers to top elements of field list
@param res_selected_fields new list of items of select item list
@param res_all_fields new list of all items
@param elements number of elements in select item list