1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fixed a flaw in the implementation of condition push-down

for materialized views and derived tables: there were no
push-down if the view was defined as union of selects
without aggregation. Added test cases with such unions.

Adjusted result files after the merge of the code for mdev-9197.
This commit is contained in:
Igor Babaev
2016-09-04 20:11:58 -07:00
parent 102fc62990
commit 3b40f78ede
13 changed files with 1034 additions and 23 deletions

View File

@ -480,8 +480,10 @@ unconditional_materialization:
derived->set_materialized_derived();
if (!derived->table || !derived->table->is_created())
res= mysql_derived_create(thd, lex, derived);
#if 0
if (!res)
res= mysql_derived_fill(thd, lex, derived);
#endif
goto exit_merge;
}
@ -1130,6 +1132,22 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
if (!cond)
return false;
st_select_lex_unit *unit= derived->get_unit();
st_select_lex *sl= unit->first_select();
/* Check whether any select of 'unit' allows condition pushdown */
bool any_select_allows_cond_pushdown= false;
for (; sl; sl= sl->next_select())
{
if (sl->cond_pushdown_is_allowed())
{
any_select_allows_cond_pushdown= true;
break;
}
}
if (!any_select_allows_cond_pushdown)
return false;
/* Do not push conditions into recursive with tables */
if (derived->is_recursive_with_table())
return false;
@ -1150,11 +1168,11 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
return false;
}
/* Push extracted_cond into every select of the unit specifying 'derived' */
st_select_lex_unit *unit= derived->get_unit();
st_select_lex *save_curr_select= thd->lex->current_select;
st_select_lex *sl= unit->first_select();
for (; sl; sl= sl->next_select())
{
if (!sl->cond_pushdown_is_allowed())
continue;
thd->lex->current_select= sl;
/*
For each select of the unit except the last one
@ -1164,7 +1182,32 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
extracted_cond->build_clone(thd, thd->mem_root);
if (!extracted_cond_copy)
continue;
if (!sl->join->group_list && !sl->with_sum_func)
{
/* extracted_cond_copy is pushed into where of sl */
extracted_cond_copy= extracted_cond_copy->transform(thd,
&Item::derived_field_transformer_for_where,
(uchar*) sl);
if (extracted_cond_copy)
{
/*
Create the conjunction of the existing where condition of sl
and the pushed condition, take it as the new where condition of sl
and fix this new condition
*/
extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0);
thd->change_item_tree(&sl->join->conds,
and_conds(thd, sl->join->conds,
extracted_cond_copy));
if (sl->join->conds->fix_fields(thd, &sl->join->conds))
goto err;
}
continue;
}
/*
Figure out what can be extracted from the pushed condition
that could be pushed into the where clause of sl
@ -1182,8 +1225,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
*/
if (cond_over_grouping_fields)
cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
&Item::derived_field_transformer_for_where,
(uchar*) sl);
&Item::derived_grouping_field_transformer_for_where,
(uchar*) sl);
if (cond_over_grouping_fields)
{
@ -1200,16 +1243,16 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
*/
cond_over_grouping_fields->walk(&Item::cleanup_processor, 0, 0);
thd->change_item_tree(&sl->join->conds,
and_conds(thd, sl->join->conds,
cond_over_grouping_fields));
and_conds(thd, sl->join->conds,
cond_over_grouping_fields));
if (sl->join->conds->fix_fields(thd, &sl->join->conds))
goto err;
if (!extracted_cond_copy)
continue;
}
/*
Transform the references to the 'derived' columns from the condition
pushed into the having clause of sl to make them usable in the new context
@ -1239,3 +1282,4 @@ err:
thd->lex->current_select= save_curr_select;
return true;
}