Commit 525856cd authored by Sergey Petrunya's avatar Sergey Petrunya

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

parent 6a66ad87
...@@ -364,11 +364,14 @@ int check_and_do_in_subquery_rewrites(JOIN *join) ...@@ -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) ...@@ -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) ...@@ -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 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) ...@@ -753,6 +774,11 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
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)?
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment