1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Fix LP BUG#611622

Fix MySQL BUG#52344 - Subquery materialization: Assertion if subquery in on-clause of outer join

Original fix and comments from Oysten, adjusted for the different
subquery optimization in MariaDB.
"
Problem: If tables of an outer join are constant tables,
the associated on-clause will be evaluated in the optimization
phase. If the on-clause contains a query that is to be
executed with subquery materialization, this will not work
since the infrastructure for such execution is not yet set up.
      
Solution: Do not evaluate on-clause in optimization phase if
is_expensive() returns true for this clause.  This is how the
problem is currently avoided for where-clauses.  This works
because, Item_in_subselect::is_expensive_processor returns true
if query is to be executed with subquery materialization.
"
In addition, after MWL#89, in MariaDB if the IN-EXISTS strategy
is chosen, the in-to-exists predicates are insterted after
join_read_const_table() is called, resulting in evaluation of
the subquery without the in-to-exists predicates.
This commit is contained in:
unknown
2010-11-25 11:43:23 +02:00
parent 0574bc894b
commit 970b46b1dc
3 changed files with 100 additions and 11 deletions

View File

@ -10599,16 +10599,6 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
}
}
else if (cond->const_item() && !cond->is_expensive())
/*
DontEvaluateMaterializedSubqueryTooEarly:
TODO:
Excluding all expensive functions is too restritive we should exclude only
materialized IN subquery predicates because they can't yet be evaluated
here (they need additional initialization that is done later on).
The proper way to exclude the subqueries would be to walk the cond tree and
check for materialized subqueries there.
*/
{
*cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
return (COND*) 0;
@ -13527,7 +13517,14 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
DBUG_RETURN(error);
}
}
if (*tab->on_expr_ref && !table->null_row)
/*
Evaluate an on-expression only if it is not considered expensive.
This mainly prevents executing subqueries in optimization phase.
This is necessary since proper setup for such execution has not been
done at this stage.
*/
if (*tab->on_expr_ref && !table->null_row &&
!(*tab->on_expr_ref)->is_expensive())
{
#if !defined(DBUG_OFF) && defined(NOT_USING_ITEM_EQUAL)
/*