MWL#90: Address review feedback part #19: More comments

This commit is contained in:
Sergey Petrunya 2011-04-05 14:33:15 +04:00
parent 151207134b
commit 81c6f73ff2

View File

@ -364,11 +364,14 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
(Subquery is correlated to the immediate outer query && (Subquery is correlated to the immediate outer query &&
Subquery !contains {GROUP BY, ORDER BY [LIMIT], Subquery !contains {GROUP BY, ORDER BY [LIMIT],
aggregate functions}) && subquery predicate is not under "NOT IN")) aggregate functions}) && subquery predicate is not under "NOT IN"))
6. No execution method was already chosen (by a prepared statement).
(*) The subquery must be part of a SELECT statement. The current (*) The subquery must be part of a SELECT statement. The current
condition also excludes multi-table update statements. condition also excludes multi-table update statements.
A note about prepared statements: we want the if-branch to be taken on
PREPARE and each EXECUTE. The rewrites are only done once, but we need
join->sj_subselects list to be populated for every EXECUTE.
Determine whether we will perform subquery materialization before Determine whether we will perform subquery materialization before
calling the IN=>EXISTS transformation, so that we know whether to calling the IN=>EXISTS transformation, so that we know whether to
perform the whole transformation or only that part of it which wraps perform the whole transformation or only that part of it which wraps
@ -534,6 +537,20 @@ bool make_in_exists_conversion(THD *thd, JOIN *join, Item_in_subselect *item)
DBUG_ENTER("make_in_exists_conversion"); DBUG_ENTER("make_in_exists_conversion");
JOIN *child_join= item->unit->first_select()->join; JOIN *child_join= item->unit->first_select()->join;
Item_subselect::trans_res res; Item_subselect::trans_res res;
/*
We're going to finalize IN->EXISTS conversion.
Normally, IN->EXISTS conversion takes place inside the
Item_subselect::fix_fields() call, where item_subselect->fixed==FALSE (as
fix_fields() haven't finished yet) and item_subselect->changed==FALSE (as
the conversion haven't been finalized)
At the end of Item_subselect::fix_fields() we had to set fixed=TRUE,
changed=TRUE (the only other option would have been to return error).
So, now we have to set these back for the duration of select_transformer()
call.
*/
item->changed= 0; item->changed= 0;
item->fixed= 0; item->fixed= 0;
@ -566,6 +583,10 @@ bool make_in_exists_conversion(THD *thd, JOIN *join, Item_in_subselect *item)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
item->substitution= NULL; item->substitution= NULL;
/*
If this is a prepared statement, repeat the above operation for
prep_where (or prep_on_expr).
*/
if (!thd->stmt_arena->is_conventional()) if (!thd->stmt_arena->is_conventional())
{ {
tree= (item->emb_on_expr_nest == (TABLE_LIST*)NO_JOIN_NEST)? tree= (item->emb_on_expr_nest == (TABLE_LIST*)NO_JOIN_NEST)?
@ -753,6 +774,11 @@ skip_conversion:
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
(*in_subq)->substitution= NULL; (*in_subq)->substitution= NULL;
/*
If this is a prepared statement, repeat the above operation for
prep_where (or prep_on_expr). Subquery-to-semijoin conversion is
done once for prepared statement.
*/
if (!thd->stmt_arena->is_conventional()) if (!thd->stmt_arena->is_conventional())
{ {
tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)? tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?