1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-8359: WHERE condition referring to inner table of left join can be sargable

Implement a technique mentioned in the MDEV. Under certain conditions,
cond(inner_table.col) can be substituted for cond(outer_table.col) for
the purpose of range analysis.
This commit is contained in:
Sergei Petrunia
2016-10-14 00:05:13 +03:00
parent 9208b87f18
commit b8b1b928ff
3 changed files with 90 additions and 0 deletions

View File

@ -7328,6 +7328,51 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param,
}
}
}
else
{
THD *thd= current_thd;
JOIN *join;
COND_EQUAL *cond_equal;
// todo: also check that the condition has abort_on_null set.
if ((field_item->used_tables() & ~OUTER_REF_TABLE_BIT) &&
thd->lex->current_select &&
(join= thd->lex->current_select->join) &&
(join->outer_join & field_item->used_tables()) &&
(cond_equal= field->table->pos_in_table_list->cond_equal) &&
field_item->used_tables() & not_null_tables())
{
// Ok this is a table that's inner w.r.t some outer join
// And it has a multiple equality
List_iterator<Item_equal> li(cond_equal->current_level);
Item_equal *cur_item_eq;
while ((cur_item_eq= li++))
{
// If the multiple equality contains fields from
// - the table we're doing range analysis for
// - the table that we have a field from
// and field that we have is also there
if ((cur_item_eq->used_tables() & (param->current_table |
field->table->map)) &&
cur_item_eq->contains(field))
{
// Find fields in the table we're from
Item_equal_fields_iterator it(*cur_item_eq);
while (it++)
{
Field *f= it.get_curr_field();
if (f->table == param->table)
{
if (!((ref_tables | f->table->map) & param_comp))
{
tree= get_func_mm_tree(param, f, value);
ftree= !ftree ? tree : tree_and(param, ftree, tree);
}
}
}
}
}
}
}
DBUG_RETURN(ftree);
}