mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
10.0-base merge (roles)
This commit is contained in:
@@ -10541,6 +10541,86 @@ restart:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Remove pushdown conditions that are already checked by the scan phase
|
||||
of BNL/BNLH joins.
|
||||
|
||||
@note
|
||||
If the single-table condition for this table will be used by a
|
||||
blocked join to pre-filter this table's rows, there is no need
|
||||
to re-check the same single-table condition for each joined record.
|
||||
|
||||
This method removes from JOIN_TAB::select_cond and JOIN_TAB::select::cond
|
||||
all top-level conjuncts that also appear in in JOIN_TAB::cache_select::cond.
|
||||
*/
|
||||
|
||||
void JOIN_TAB::remove_redundant_bnl_scan_conds()
|
||||
{
|
||||
if (!(select_cond && cache_select && cache &&
|
||||
(cache->get_join_alg() == JOIN_CACHE::BNL_JOIN_ALG ||
|
||||
cache->get_join_alg() == JOIN_CACHE::BNLH_JOIN_ALG)))
|
||||
return;
|
||||
|
||||
/*
|
||||
select->cond is not processed separately. This method assumes it is always
|
||||
the same as select_cond.
|
||||
*/
|
||||
DBUG_ASSERT(!select || !select->cond ||
|
||||
(select->cond == select_cond));
|
||||
|
||||
if (is_cond_and(select_cond))
|
||||
{
|
||||
List_iterator<Item> pushed_cond_li(*((Item_cond*) select_cond)->argument_list());
|
||||
Item *pushed_item;
|
||||
Item_cond_and *reduced_select_cond= new Item_cond_and;
|
||||
|
||||
if (is_cond_and(cache_select->cond))
|
||||
{
|
||||
List_iterator<Item> scan_cond_li(*((Item_cond*) cache_select->cond)->argument_list());
|
||||
Item *scan_item;
|
||||
while ((pushed_item= pushed_cond_li++))
|
||||
{
|
||||
bool found= false;
|
||||
scan_cond_li.rewind();
|
||||
while ((scan_item= scan_cond_li++))
|
||||
{
|
||||
if (pushed_item->eq(scan_item, 0))
|
||||
{
|
||||
found= true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
reduced_select_cond->add(pushed_item);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((pushed_item= pushed_cond_li++))
|
||||
{
|
||||
if (!pushed_item->eq(cache_select->cond, 0))
|
||||
reduced_select_cond->add(pushed_item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
JOIN_CACHE::check_match uses JOIN_TAB::select->cond instead of
|
||||
JOIN_TAB::select_cond. set_cond() sets both pointers.
|
||||
*/
|
||||
if (reduced_select_cond->argument_list()->is_empty())
|
||||
set_cond(NULL);
|
||||
else if (reduced_select_cond->argument_list()->elements == 1)
|
||||
set_cond(reduced_select_cond->argument_list()->head());
|
||||
else
|
||||
{
|
||||
reduced_select_cond->quick_fix_field();
|
||||
set_cond(reduced_select_cond);
|
||||
}
|
||||
}
|
||||
else if (select_cond->eq(cache_select->cond, 0))
|
||||
set_cond(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Plan refinement stage: do various setup things for the executor
|
||||
@@ -10790,6 +10870,15 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
|
||||
abort();
|
||||
/* purecov: end */
|
||||
}
|
||||
|
||||
tab->remove_redundant_bnl_scan_conds();
|
||||
DBUG_EXECUTE("where",
|
||||
char buff[256];
|
||||
String str(buff,sizeof(buff),system_charset_info);
|
||||
str.length(0);
|
||||
str.append(tab->table? tab->table->alias.c_ptr() :"<no_table_name>");
|
||||
str.append(" final_pushdown_cond");
|
||||
print_where(tab->select_cond, str.c_ptr_safe(), QT_ORDINARY););
|
||||
}
|
||||
uint n_top_tables= join->join_tab_ranges.head()->end -
|
||||
join->join_tab_ranges.head()->start;
|
||||
@@ -23177,7 +23266,8 @@ int JOIN::save_explain_data_intern(Explain_query *output, bool need_tmp_table,
|
||||
eta->push_extra(ET_RANGE_CHECKED_FOR_EACH_RECORD);
|
||||
eta->range_checked_map= tab->keys;
|
||||
}
|
||||
else if (tab->select->cond)
|
||||
else if (tab->select->cond ||
|
||||
(tab->cache_select && tab->cache_select->cond))
|
||||
{
|
||||
const COND *pushed_cond= tab->table->file->pushed_cond;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user