mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Auto-merge from mysql-trunk.
This commit is contained in:
@ -1126,9 +1126,8 @@ JOIN::optimize()
|
||||
}
|
||||
}
|
||||
|
||||
if (conds &&!outer_join && const_table_map != found_const_table_map &&
|
||||
(select_options & SELECT_DESCRIBE) &&
|
||||
select_lex->master_unit() == &thd->lex->unit) // upper level SELECT
|
||||
if (conds && const_table_map != found_const_table_map &&
|
||||
(select_options & SELECT_DESCRIBE))
|
||||
{
|
||||
conds=new Item_int((longlong) 0,1); // Always false
|
||||
}
|
||||
@ -1145,13 +1144,13 @@ JOIN::optimize()
|
||||
elements may be lost during further having
|
||||
condition transformation in JOIN::exec.
|
||||
*/
|
||||
if (having && !having->with_sum_func)
|
||||
if (having && const_table_map)
|
||||
{
|
||||
COND *const_cond= make_cond_for_table(having, const_table_map, 0);
|
||||
DBUG_EXECUTE("where", print_where(const_cond, "const_having_cond",
|
||||
QT_ORDINARY););
|
||||
if (const_cond && !const_cond->val_int())
|
||||
having->update_used_tables();
|
||||
having= remove_eq_conds(thd, having, &having_value);
|
||||
if (having_value == Item::COND_FALSE)
|
||||
{
|
||||
having= new Item_int((longlong) 0,1);
|
||||
zero_result_cause= "Impossible HAVING noticed after reading const tables";
|
||||
error= 0;
|
||||
DBUG_RETURN(0);
|
||||
@ -3006,8 +3005,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
||||
s->quick=select->quick;
|
||||
s->needed_reg=select->needed_reg;
|
||||
select->quick=0;
|
||||
if (records == 0 && s->table->reginfo.impossible_range &&
|
||||
(s->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT))
|
||||
if (records == 0 && s->table->reginfo.impossible_range)
|
||||
{
|
||||
/*
|
||||
Impossible WHERE or ON expression
|
||||
@ -5162,6 +5160,11 @@ greedy_search(JOIN *join,
|
||||
if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
|
||||
read_time, search_depth, prune_level))
|
||||
DBUG_RETURN(TRUE);
|
||||
/*
|
||||
'best_read < DBL_MAX' means that optimizer managed to find
|
||||
some plan and updated 'best_positions' array accordingly.
|
||||
*/
|
||||
DBUG_ASSERT(join->best_read < DBL_MAX);
|
||||
|
||||
if (size_remain <= search_depth)
|
||||
{
|
||||
@ -8942,8 +8945,14 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
|
||||
we still make the inner tables dependent on the outer tables.
|
||||
It would be enough to set dependency only on one outer table
|
||||
for them. Yet this is really a rare case.
|
||||
Note:
|
||||
RAND_TABLE_BIT mask should not be counted as it
|
||||
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() & ~prev_used_tables))
|
||||
if (!((prev_table->on_expr->used_tables() & ~RAND_TABLE_BIT) &
|
||||
~prev_used_tables))
|
||||
prev_table->dep_tables|= used_tables;
|
||||
}
|
||||
}
|
||||
@ -9199,6 +9208,46 @@ static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
|
||||
/**
|
||||
Nested joins perspective: Remove the last table from the join order.
|
||||
|
||||
The algorithm is the reciprocal of check_interleaving_with_nj(), hence
|
||||
parent join nest nodes are updated only when the last table in its child
|
||||
node is removed. The ASCII graphic below will clarify.
|
||||
|
||||
%A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
|
||||
represented by the below join nest tree.
|
||||
|
||||
@verbatim
|
||||
NJ1
|
||||
_/ / \
|
||||
_/ / NJ2
|
||||
_/ / / \
|
||||
/ / / \
|
||||
t1 x [ (t2 x t3) x (t4 x t5) ]
|
||||
@endverbatim
|
||||
|
||||
At the point in time when check_interleaving_with_nj() adds the table t5 to
|
||||
the query execution plan, QEP, it also directs the node named NJ2 to mark
|
||||
the table as covered. NJ2 does so by incrementing its @c counter
|
||||
member. Since all of NJ2's tables are now covered by the QEP, the algorithm
|
||||
proceeds up the tree to NJ1, incrementing its counter as well. All join
|
||||
nests are now completely covered by the QEP.
|
||||
|
||||
restore_prev_nj_state() does the above in reverse. As seen above, the node
|
||||
NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
|
||||
that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
|
||||
completely covers NJ2. The removal of t5 from the partial plan will first
|
||||
decrement NJ2's counter to 1. It will then detect that NJ2 went from being
|
||||
completely to partially covered, and hence the algorithm must continue
|
||||
upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
|
||||
will however not influence NJ1 since it did not un-cover the last table in
|
||||
NJ2.
|
||||
|
||||
SYNOPSIS
|
||||
restore_prev_nj_state()
|
||||
last join table to remove, it is assumed to be the last in current
|
||||
partial join order.
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
Remove the last table from the partial join order and update the nested
|
||||
joins counters and join->cur_embedding_map. It is ok to call this
|
||||
function for the first table in join order (for which
|
||||
@ -9212,19 +9261,20 @@ static void restore_prev_nj_state(JOIN_TAB *last)
|
||||
{
|
||||
TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
|
||||
JOIN *join= last->join;
|
||||
while (last_emb)
|
||||
for (;last_emb != NULL; last_emb= last_emb->embedding)
|
||||
{
|
||||
if (!(--last_emb->nested_join->counter))
|
||||
join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
|
||||
else if (last_emb->nested_join->join_list.elements-1 ==
|
||||
last_emb->nested_join->counter)
|
||||
{
|
||||
join->cur_embedding_map|= last_emb->nested_join->nj_map;
|
||||
NESTED_JOIN *nest= last_emb->nested_join;
|
||||
DBUG_ASSERT(nest->counter > 0);
|
||||
|
||||
bool was_fully_covered= nest->is_fully_covered();
|
||||
|
||||
if (--nest->counter == 0)
|
||||
join->cur_embedding_map&= ~nest->nj_map;
|
||||
|
||||
if (!was_fully_covered)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
last_emb= last_emb->embedding;
|
||||
|
||||
join->cur_embedding_map|= nest->nj_map;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user