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

Merge 11.4 into 11.8

This commit is contained in:
Marko Mäkelä
2025-04-02 14:07:01 +03:00
786 changed files with 10229 additions and 5958 deletions

View File

@@ -15074,6 +15074,36 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
}
/*
Procedure of keys generation for result tables of materialized derived
tables/views.
A key is generated for each equi-join pair {derived_table, some_other_table}.
Each generated key consists of fields of derived table used in equi-join.
Example:
SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
t1 ON tt.f1=t1.f3 and tt.f2.=t1.f4;
In this case for the derived table tt one key will be generated. It will
consist of two parts f1 and f2.
Example:
SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
t1 ON tt.f1=t1.f3 JOIN
t2 ON tt.f2=t2.f4;
In this case for the derived table tt two keys will be generated.
One key over f1 field, and another key over f2 field.
Currently optimizer may choose to use only one such key, thus the second
one will be dropped after range optimizer is finished.
See also JOIN::drop_unused_derived_keys function.
Example:
SELECT * FROM (SELECT * FROM t1 GROUP BY 1) tt JOIN
t1 ON tt.f1=a_function(t1.f3);
In this case for the derived table tt one key will be generated. It will
consist of one field - f1.
*/
static
bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
{
@@ -19757,6 +19787,8 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
prev_table->dep_tables|= used_tables;
if (prev_table->on_expr)
{
/* If the ON expression is still there, it's an outer join */
DBUG_ASSERT(prev_table->outer_join);
prev_table->dep_tables|= table->on_expr_dep_tables;
table_map prev_used_tables= prev_table->nested_join ?
prev_table->nested_join->used_tables :
@@ -19771,11 +19803,59 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
prevents update of inner table dependences.
For example it might happen if RAND() function
is used in JOIN ON clause.
*/
if (!((prev_table->on_expr->used_tables() &
~(OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) &
~prev_used_tables))
*/
table_map prev_on_expr_deps= prev_table->on_expr->used_tables() &
~(OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
prev_on_expr_deps&= ~prev_used_tables;
if (!prev_on_expr_deps)
prev_table->dep_tables|= used_tables;
else
{
/*
Another possible case is when prev_on_expr_deps!=0 but it depends
on a table outside this join nest. SQL name resolution don't allow
this but it is possible when LEFT JOIN is inside a subquery which
is converted into a semi-join nest, Example:
t1 SEMI JOIN (
t2
LEFT JOIN (t3 LEFT JOIN t4 ON t4.col=t1.col) ON expr
) ON ...
here, we would have prev_table=t4, table=t3. The condition
"ON t4.col=t1.col" depends on tables {t1, t4}. To make sure the
optimizer puts t3 before t4 we need to make sure t4.dep_tables
includes t3.
*/
DBUG_ASSERT(table->embedding == prev_table->embedding);
if (table->embedding)
{
/*
Find what are the "peers" of "table" in the join nest. Normally,
it is table->embedding->nested_join->used_tables, but here we are
in the process of recomputing that value.
So, we walk the join list and collect the bitmap of peers:
*/
table_map peers= 0;
List_iterator_fast<TABLE_LIST> li(*join_list);
TABLE_LIST *peer;
while ((peer= li++))
{
table_map curmap= peer->nested_join
? peer->nested_join->used_tables
: peer->get_map();
peers|= curmap;
}
/*
If prev_table doesn't depend on any of its peers, add a
dependency on nearest peer, that is, on 'table'.
*/
if (!(prev_on_expr_deps & peers))
prev_table->dep_tables|= used_tables;
}
}
}
}
prev_table= table;