1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge branch '10.11' into 11.0

This commit is contained in:
Sergei Golubchik
2024-05-11 13:23:27 +02:00
820 changed files with 18746 additions and 6295 deletions

View File

@@ -848,37 +848,57 @@ void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex)
if (subq_select_lex->group_list.elements &&
!subq_select_lex->with_sum_func && !subq_select_lex->join->having)
{
/*
Temporary workaround for MDEV-28621: Do not remove GROUP BY expression
if it has any subqueries in it.
*/
bool have_subquery= false;
for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next)
{
/*
Do not remove the item if it is used in select list and then referred
from GROUP BY clause by its name or number. Example:
select (select ... ) as SUBQ ... group by SUBQ
Here SUBQ cannot be removed.
*/
if (!ord->in_field_list)
if ((*ord->item)->with_subquery())
{
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
/*
Remove from the JOIN::all_fields list any reference to the elements
of the eliminated GROUP BY list unless it is 'in_field_list'.
This is needed in order not to confuse JOIN::make_aggr_tables_info()
when it constructs different structure for execution phase.
*/
List_iterator<Item> li(subq_select_lex->join->all_fields);
Item *item;
while ((item= li++))
{
if (item == *ord->item)
li.remove();
}
have_subquery= true;
break;
}
}
subq_select_lex->join->group_list= NULL;
subq_select_lex->group_list.empty();
DBUG_PRINT("info", ("GROUP BY removed"));
if (!have_subquery)
{
for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next)
{
/*
Do not remove the item if it is used in select list and then referred
from GROUP BY clause by its name or number. Example:
select (select ... ) as SUBQ ... group by SUBQ
Here SUBQ cannot be removed.
*/
if (!ord->in_field_list)
{
/*
Not necessary due to workaround for MDEV-28621:
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
*/
/*
Remove from the JOIN::all_fields list any reference to the elements
of the eliminated GROUP BY list unless it is 'in_field_list'.
This is needed in order not to confuse JOIN::make_aggr_tables_info()
when it constructs different structure for execution phase.
*/
List_iterator<Item> li(subq_select_lex->join->all_fields);
Item *item;
while ((item= li++))
{
if (item == *ord->item)
li.remove();
}
}
}
subq_select_lex->join->group_list= NULL;
subq_select_lex->group_list.empty();
DBUG_PRINT("info", ("GROUP BY removed"));
}
}
/*
@@ -3650,7 +3670,7 @@ bool JOIN::make_aggr_tables_info()
distinct in the engine, so we do this for all queries, not only
GROUP BY queries.
*/
if (tables_list && top_join_tab_count && !procedure)
if (tables_list && top_join_tab_count && !only_const_tables() && !procedure)
{
/*
At the moment we only support push down for queries where
@@ -22675,7 +22695,7 @@ create_internal_tmp_table_from_heap(THD *thd, TABLE *table,
if (open_tmp_table(&new_table))
goto err1;
if (table->file->indexes_are_disabled())
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
new_table.file->ha_disable_indexes(key_map(0), false);
table->file->ha_index_or_rnd_end();
if (table->file->ha_rnd_init_with_error(1))
DBUG_RETURN(1);
@@ -33065,7 +33085,26 @@ void JOIN::init_join_cache_and_keyread()
*/
table->mark_index_columns(table->file->keyread, table->read_set);
}
if (tab->cache && tab->cache->init(select_options & SELECT_DESCRIBE))
bool init_for_explain= false;
/*
Can we use lightweight initalization mode just for EXPLAINs? We can if
we're certain that the optimizer will not execute the subquery.
The optimzier will not execute the subquery if it's too expensive. For
the exact criteria, see Item_subselect::is_expensive().
Note that the subquery might be a UNION and we might not yet know if it
is expensive.
What we do know is that if this SELECT is too expensive, then the whole
subquery will be too expensive as well.
So, we can use lightweight initialization (init_for_explain=true) if this
SELECT examines more than @@expensive_subquery_limit rows.
*/
if ((select_options & SELECT_DESCRIBE) &&
get_examined_rows() >= thd->variables.expensive_subquery_limit)
{
init_for_explain= true;
}
if (tab->cache && tab->cache->init(init_for_explain))
revise_cache_usage(tab);
else
tab->remove_redundant_bnl_scan_conds();