Commit 4236b120 authored by Yuchen Pei's avatar Yuchen Pei Committed by Sergei Petrunia

MDEV-22534: Decorrelation for IN: workaround for MDEV-31269

Skip the decorrelation of IN subquery if
- we are running in a prepared statement
- any of trivial correlation expressions uses an Item_ref-derived object.
parent f393ecea
...@@ -399,7 +399,7 @@ select ...@@ -399,7 +399,7 @@ select
json_extract(trace, '$**.join_optimization.steps[*].transformation.to') as JS json_extract(trace, '$**.join_optimization.steps[*].transformation.to') as JS
from information_schema.OPTIMIZER_TRACE; from information_schema.OPTIMIZER_TRACE;
JS JS
["decorrelation", "materialization", "semijoin"] ["materialization", "semijoin"]
EXECUTE st2; EXECUTE st2;
a b c a b c
1 r r 1 r r
......
...@@ -2354,6 +2354,8 @@ class Item :public Value_source, ...@@ -2354,6 +2354,8 @@ class Item :public Value_source,
If there is some, sets a bit for this key in the proper key map. If there is some, sets a bit for this key in the proper key map.
*/ */
virtual bool check_index_dependence(void *arg) { return 0; } virtual bool check_index_dependence(void *arg) { return 0; }
virtual bool uses_item_ref_processor(void *arg) { return false; }
/*============== End of Item processor list ======================*/ /*============== End of Item processor list ======================*/
/* /*
...@@ -5801,6 +5803,10 @@ class Item_ref :public Item_ident ...@@ -5801,6 +5803,10 @@ class Item_ref :public Item_ident
return 0; return 0;
return cleanup_processor(arg); return cleanup_processor(arg);
} }
bool uses_item_ref_processor(void *arg) override
{
return true;
}
Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg) override Item *field_transformer_for_having_pushdown(THD *thd, uchar *arg) override
{ return (*ref)->field_transformer_for_having_pushdown(thd, arg); } { return (*ref)->field_transformer_for_having_pushdown(thd, arg); }
Item *remove_item_direct_ref() override Item *remove_item_direct_ref() override
......
...@@ -3096,17 +3096,6 @@ static bool find_inner_outer_equalities(Item **conds, ...@@ -3096,17 +3096,6 @@ static bool find_inner_outer_equalities(Item **conds,
return TRUE; return TRUE;
} }
/* Check whether item tree intersects with the free list */
static bool intersects_free_list(Item *item, THD *thd)
{
for (const Item *to_find= thd->free_list; to_find; to_find= to_find->next)
if (item->walk(&Item::find_item_processor, 1, (void *) to_find))
return true;
return false;
}
/* /*
Prepare exists2in / decorrelation transformation Prepare exists2in / decorrelation transformation
...@@ -3134,15 +3123,17 @@ bool Item_exists_subselect::exists2in_prepare( ...@@ -3134,15 +3123,17 @@ bool Item_exists_subselect::exists2in_prepare(
DBUG_ASSERT(eqs.elements() != 0); DBUG_ASSERT(eqs.elements() != 0);
/* /*
If we are in a ps/sp execution, check for and skip on A workaround to avoid 2nd ps execution segfault (MDEV-31269):
intersection with the temporary free list to avoid 2nd ps execution The transformation we're doing is permanent. Don't apply it if
segfault the involved conditions use Item_ref-based items (which are not
permanent).
*/ */
if (!thd->stmt_arena->is_conventional()) if (!thd->stmt_arena->is_conventional() && substype()==IN_SUBS)
{ {
for (uint i= 0; i < (uint) eqs.elements(); i++) for (uint i= 0; i < (uint) eqs.elements(); i++)
{ {
if (intersects_free_list(*eqs.at(i).eq_ref, thd)) Item *item= *eqs.at(i).eq_ref;
if (item->walk(&Item::uses_item_ref_processor, TRUE, NULL))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
} }
......
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