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:
@@ -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;
|
||||
|
Reference in New Issue
Block a user