Commit 504802f3 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-7846: postreview fix

parent 54b99817
......@@ -1442,6 +1442,12 @@ bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg)
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
DBUG_ENTER("Item_in_optimizer::fix_left");
/*
Here we will store pointer on place of main storage of left expression.
For usual IN (ALL/ANY) it is subquery left_expr.
For other cases (MAX/MIN optimization, non-transformed EXISTS (10.0))
it is args[0].
*/
Item **ref0= args;
if (args[1]->type() == Item::SUBSELECT_ITEM &&
((Item_subselect *)args[1])->is_in_predicate())
......@@ -1455,12 +1461,17 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
next execution we need to copy args[1]->left_expr again.
*/
ref0= &(((Item_in_subselect *)args[1])->left_expr);
args[0]= ((Item_in_subselect *)args[1])->left_expr;
}
if ((!(*ref0)->fixed && (*ref0)->fix_fields(thd, ref0)) ||
(!cache && !(cache= Item_cache::get_cache(*ref0))))
DBUG_RETURN(1);
/*
During fix_field() expression could be substituted.
So we copy changes before use
*/
if (args[0] != (*ref0))
current_thd->change_item_tree(args, (*ref0));
args[0]= (*ref0);
DBUG_PRINT("info", ("actual fix fields"));
cache->setup(args[0]);
......
......@@ -449,6 +449,11 @@ protected:
Item **having_item);
public:
Item *left_expr;
/*
Important for PS/SP: left_expr_orig is the item that left_expr originally
pointed at. That item is allocated on the statement arena, while
left_expr could later be changed to something on the execution arena.
*/
Item *left_expr_orig;
/* Priority of this predicate in the convert-to-semi-join-nest process. */
int sj_convert_priority;
......
......@@ -1592,6 +1592,15 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
if (subq_pred->left_expr->cols() == 1)
{
nested_join->sj_outer_expr_list.push_back(subq_pred->left_expr);
/*
Create Item_func_eq. Note that
1. this is done on the statement, not execution, arena
2. if it's a PS then this happens only once - on the first execution.
On following re-executions, the item will be fix_field-ed normally.
3. Thus it should be created as if it was fix_field'ed, in particular
all pointers to items in the execution arena should be protected
with thd->change_item_tree
*/
Item_func_eq *item_eq=
new Item_func_eq(subq_pred->left_expr_orig, subq_lex->ref_pointer_array[0]);
if (subq_pred->left_expr_orig != subq_pred->left_expr)
......
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