summaryrefslogtreecommitdiff
path: root/sql/item_subselect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_subselect.cc')
-rw-r--r--sql/item_subselect.cc401
1 files changed, 227 insertions, 174 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index fa398dc6e21..227d84dd213 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -48,9 +48,9 @@ const char *exists_outer_expr_name= "<exists outer expr>";
int check_and_do_in_subquery_rewrites(JOIN *join);
-Item_subselect::Item_subselect():
- Item_result_field(), Used_tables_and_const_cache(),
- value_assigned(0), own_engine(0), thd(0), old_engine(0),
+Item_subselect::Item_subselect(THD *thd_arg):
+ Item_result_field(thd_arg), Used_tables_and_const_cache(),
+ value_assigned(0), own_engine(0), thd(0), old_engine(0),
have_to_be_excluded(0),
inside_first_fix_fields(0), done_first_fix_fields(FALSE),
expr_cache(0), forced_const(FALSE), substitution(0), engine(0), eliminated(FALSE),
@@ -478,6 +478,7 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
{
List_iterator_fast<Ref_to_outside> it(upper_refs);
Ref_to_outside *upper;
+ DBUG_ENTER("recalc_used_tables");
used_tables_cache= 0;
while ((upper= it++))
@@ -537,6 +538,8 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
he has done const table detection, and that will be our chance to update
const_tables_cache.
*/
+ DBUG_PRINT("exit", ("used_tables_cache: %llx", used_tables_cache));
+ DBUG_VOID_RETURN;
}
@@ -875,7 +878,7 @@ bool Item_subselect::const_item() const
Item *Item_subselect::get_tmp_table_item(THD *thd_arg)
{
if (!with_sum_func && !const_item())
- return new Item_field(result_field);
+ return new (thd->mem_root) Item_field(thd_arg, result_field);
return copy_or_same(thd_arg);
}
@@ -896,7 +899,7 @@ void Item_subselect::update_used_tables()
void Item_subselect::print(String *str, enum_query_type query_type)
{
- if (query_type == QT_EXPLAIN)
+ if (query_type & QT_ITEM_SUBSELECT_ID_ONLY)
{
str->append("(subquery#");
if (unit && unit->first_select())
@@ -922,12 +925,11 @@ void Item_subselect::print(String *str, enum_query_type query_type)
}
-Item_singlerow_subselect::Item_singlerow_subselect(THD *thd_arg, st_select_lex *select_lex)
- :Item_subselect(), value(0)
+Item_singlerow_subselect::Item_singlerow_subselect(THD *thd, st_select_lex *select_lex):
+ Item_subselect(thd), value(0)
{
DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect");
- init(select_lex, new (thd_arg->mem_root) select_singlerow_subselect(thd_arg,
- this));
+ init(select_lex, new (thd->mem_root) select_singlerow_subselect(thd, this));
maybe_null= 1;
max_columns= UINT_MAX;
DBUG_VOID_RETURN;
@@ -953,16 +955,16 @@ Item_singlerow_subselect::invalidate_and_restore_select_lex()
DBUG_RETURN(result);
}
-Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
+Item_maxmin_subselect::Item_maxmin_subselect(THD *thd,
Item_subselect *parent,
st_select_lex *select_lex,
- bool max_arg)
- :Item_singlerow_subselect(), was_values(TRUE)
+ bool max_arg):
+ Item_singlerow_subselect(thd), was_values(TRUE)
{
DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
max= max_arg;
init(select_lex,
- new (thd_param->mem_root) select_max_min_finder_subselect(thd_param,
+ new (thd->mem_root) select_max_min_finder_subselect(thd,
this, max_arg, parent->substype() == Item_subselect::ALL_SUBS));
max_columns= 1;
maybe_null= 1;
@@ -975,12 +977,6 @@ Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
used_tables_cache= parent->get_used_tables_cache();
const_item_cache= parent->const_item();
- /*
- this subquery always creates during preparation, so we can assign
- thd here
- */
- thd= thd_param;
-
DBUG_VOID_RETURN;
}
@@ -1020,7 +1016,7 @@ void Item_maxmin_subselect::no_rows_in_result()
*/
if (parsing_place != SELECT_LIST || const_item())
return;
- value= Item_cache::get_cache(new Item_null());
+ value= Item_cache::get_cache(thd, new (thd->mem_root) Item_null(thd));
null_value= 0;
was_values= 0;
make_const();
@@ -1038,7 +1034,7 @@ void Item_singlerow_subselect::no_rows_in_result()
*/
if (parsing_place != SELECT_LIST || const_item())
return;
- value= Item_cache::get_cache(new Item_null());
+ value= Item_cache::get_cache(thd, new (thd->mem_root) Item_null(thd));
reset();
make_const();
}
@@ -1105,7 +1101,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
if (thd->lex->describe)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
- sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
+ sprintf(warn_buff, ER_THD(thd, ER_SELECT_REDUCED),
+ select_lex->select_number);
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff);
}
@@ -1191,17 +1188,22 @@ void Item_singlerow_subselect::fix_length_and_dec()
this item - otherwise
*/
-Item* Item_singlerow_subselect::expr_cache_insert_transformer(uchar *thd_arg)
+Item* Item_singlerow_subselect::expr_cache_insert_transformer(THD *tmp_thd,
+ uchar *unused)
{
- THD *thd= (THD*) thd_arg;
DBUG_ENTER("Item_singlerow_subselect::expr_cache_insert_transformer");
+ DBUG_ASSERT(thd == tmp_thd);
+
if (expr_cache)
DBUG_RETURN(expr_cache);
- if (expr_cache_is_needed(thd) &&
- (expr_cache= set_expr_cache(thd)))
+ if (expr_cache_is_needed(tmp_thd) &&
+ (expr_cache= set_expr_cache(tmp_thd)))
+ {
+ init_expr_cache_tracker(tmp_thd);
DBUG_RETURN(expr_cache);
+ }
DBUG_RETURN(this);
}
@@ -1345,13 +1347,13 @@ bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate)
}
-Item_exists_subselect::Item_exists_subselect(THD *thd_arg,
+Item_exists_subselect::Item_exists_subselect(THD *thd,
st_select_lex *select_lex):
- Item_subselect(), upper_not(NULL), abort_on_null(0),
+ Item_subselect(thd), upper_not(NULL), abort_on_null(0),
emb_on_expr_nest(NULL), optimizer(0), exists_transformed(0)
{
DBUG_ENTER("Item_exists_subselect::Item_exists_subselect");
- init(select_lex, new (thd_arg->mem_root) select_exists_subselect(thd_arg, this));
+ init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
max_columns= UINT_MAX;
null_value= FALSE; //can't be NULL
maybe_null= 0; //can't be NULL
@@ -1382,9 +1384,9 @@ bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
return(0);
}
-Item_in_subselect::Item_in_subselect(THD *thd_arg, Item * left_exp,
+Item_in_subselect::Item_in_subselect(THD *thd, Item * left_exp,
st_select_lex *select_lex):
- Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
+ Item_exists_subselect(thd), left_expr_cache(0), first_execution(TRUE),
in_strategy(SUBS_NOT_TRANSFORMED),
pushed_cond_guards(NULL), is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
is_flattenable_semijoin(FALSE), is_registered_semijoin(FALSE),
@@ -1394,8 +1396,7 @@ Item_in_subselect::Item_in_subselect(THD *thd_arg, Item * left_exp,
DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy));
left_expr= left_exp;
func= &eq_creator;
- init(select_lex, new (thd_arg->mem_root) select_exists_subselect(thd_arg,
- this));
+ init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
max_columns= UINT_MAX;
maybe_null= 1;
reset();
@@ -1409,17 +1410,16 @@ int Item_in_subselect::get_identifier()
return engine->get_identifier();
}
-Item_allany_subselect::Item_allany_subselect(THD *thd_arg, Item * left_exp,
+Item_allany_subselect::Item_allany_subselect(THD *thd, Item * left_exp,
chooser_compare_func_creator fc,
st_select_lex *select_lex,
- bool all_arg)
- :Item_in_subselect(), func_creator(fc), all(all_arg)
+ bool all_arg):
+ Item_in_subselect(thd), func_creator(fc), all(all_arg)
{
DBUG_ENTER("Item_allany_subselect::Item_allany_subselect");
left_expr= left_exp;
func= func_creator(all_arg);
- init(select_lex, new (thd_arg->mem_root) select_exists_subselect(thd_arg,
- this));
+ init(select_lex, new (thd->mem_root) select_exists_subselect(thd, this));
max_columns= 1;
abort_on_null= 0;
reset();
@@ -1451,7 +1451,7 @@ void Item_exists_subselect::fix_length_and_dec()
an IN always requires LIMIT 1)
*/
thd->change_item_tree(&unit->global_parameters()->select_limit,
- new Item_int((int32) 1));
+ new (thd->mem_root) Item_int(thd, (int32) 1));
DBUG_PRINT("info", ("Set limit to 1"));
DBUG_VOID_RETURN;
}
@@ -1487,17 +1487,21 @@ void Item_in_subselect::fix_length_and_dec()
this item - otherwise
*/
-Item* Item_exists_subselect::expr_cache_insert_transformer(uchar *thd_arg)
+Item* Item_exists_subselect::expr_cache_insert_transformer(THD *tmp_thd,
+ uchar *unused)
{
- THD *thd= (THD*) thd_arg;
DBUG_ENTER("Item_exists_subselect::expr_cache_insert_transformer");
+ DBUG_ASSERT(thd == tmp_thd);
if (expr_cache)
DBUG_RETURN(expr_cache);
- if (substype() == EXISTS_SUBS && expr_cache_is_needed(thd) &&
- (expr_cache= set_expr_cache(thd)))
+ if (substype() == EXISTS_SUBS && expr_cache_is_needed(tmp_thd) &&
+ (expr_cache= set_expr_cache(tmp_thd)))
+ {
+ init_expr_cache_tracker(tmp_thd);
DBUG_RETURN(expr_cache);
+ }
DBUG_RETURN(this);
}
@@ -1779,12 +1783,13 @@ Item_in_subselect::single_value_transformer(JOIN *join)
of the statement. Thus one of 'substitution' arguments
can be broken in case of PS.
*/
- substitution= func->create(thd->mem_root, left_expr, where_item);
+ substitution= func->create(thd, left_expr, where_item);
have_to_be_excluded= 1;
if (thd->lex->describe)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
- sprintf(warn_buff, ER(ER_SELECT_REDUCED), select_lex->select_number);
+ sprintf(warn_buff, ER_THD(thd, ER_SELECT_REDUCED),
+ select_lex->select_number);
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff);
}
@@ -1817,7 +1822,7 @@ Item_in_subselect::single_value_transformer(JOIN *join)
As far as Item_in_optimizer does not substitute itself on fix_fields
we can use same item for all selects.
*/
- expr= new Item_direct_ref(&select_lex->context,
+ expr= new (thd->mem_root) Item_direct_ref(thd, &select_lex->context,
(Item**)optimizer->get_cache(),
(char *)"<no matter>",
(char *)in_left_expr_name);
@@ -1855,7 +1860,6 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
if (!test_strategy(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE))
DBUG_RETURN(false);
Item **place= optimizer->arguments() + 1;
- THD *thd= join->thd;
SELECT_LEX *select_lex= join->select_lex;
Item *subs;
@@ -1886,7 +1890,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
(ALL && (> || =>)) || (ANY && (< || =<))
for ALL condition is inverted
*/
- item= new Item_sum_max(*select_lex->ref_pointer_array);
+ item= new (thd->mem_root) Item_sum_max(thd, *select_lex->ref_pointer_array);
}
else
{
@@ -1894,7 +1898,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
(ALL && (< || =<)) || (ANY && (> || =>))
for ALL condition is inverted
*/
- item= new Item_sum_min(*select_lex->ref_pointer_array);
+ item= new (thd->mem_root) Item_sum_min(thd, *select_lex->ref_pointer_array);
}
if (upper_item)
upper_item->set_sum_test(item);
@@ -1935,7 +1939,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
else
{
Item_maxmin_subselect *item;
- subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
+ subs= item= new (thd->mem_root) Item_maxmin_subselect(thd, this, select_lex, func->l_op());
if (upper_item)
upper_item->set_sub_test(item);
/*
@@ -1948,7 +1952,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
where we want to evaluate the sub query even if f1 would be null.
*/
- subs= func->create_swap(thd->mem_root, *(optimizer->get_cache()), subs);
+ subs= func->create_swap(thd, *(optimizer->get_cache()), subs);
thd->change_item_tree(place, subs);
if (subs->fix_fields(thd, &subs))
DBUG_RETURN(true);
@@ -2021,7 +2025,7 @@ bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
*/
bool
-Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
+Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
Item **where_item,
Item **having_item)
{
@@ -2031,7 +2035,6 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
*/
Item* join_having= join->having ? join->having : join->tmp_having;
-
DBUG_ENTER("Item_in_subselect::create_single_in_to_exists_cond");
*where_item= NULL;
@@ -2040,8 +2043,9 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
if (join_having || select_lex->with_sum_func ||
select_lex->group_list.elements)
{
- Item *item= func->create(thd->mem_root, expr,
+ Item *item= func->create(thd, expr,
new (thd->mem_root) Item_ref_null_helper(
+ thd,
&select_lex->context,
this,
select_lex->
@@ -2054,7 +2058,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
within a trig_cond.
*/
- item= new Item_func_trig_cond(item, get_cond_guard(0));
+ item= new (thd->mem_root) Item_func_trig_cond(thd, item, get_cond_guard(0));
}
if (!join_having)
@@ -2072,13 +2076,13 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
Item *having= item;
Item *orig_item= item;
- item= func->create(thd->mem_root, expr, item);
+ item= func->create(thd, expr, item);
if (!abort_on_null && orig_item->maybe_null)
{
- having= new (thd->mem_root) Item_is_not_null_test(this, having);
+ having= new (thd->mem_root) Item_is_not_null_test(thd, this, having);
if (left_expr->maybe_null)
{
- if (!(having= new (thd->mem_root) Item_func_trig_cond(having,
+ if (!(having= new (thd->mem_root) Item_func_trig_cond(thd, having,
get_cond_guard(0))))
DBUG_RETURN(true);
}
@@ -2087,8 +2091,8 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
DBUG_RETURN(true);
*having_item= having;
- item= new (thd->mem_root) Item_cond_or(item,
- new (thd->mem_root) Item_func_isnull(orig_item));
+ item= new (thd->mem_root) Item_cond_or(thd, item,
+ new (thd->mem_root) Item_func_isnull(thd, orig_item));
}
/*
If we may encounter NULL IN (SELECT ...) and care whether subquery
@@ -2096,7 +2100,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
*/
if (!abort_on_null && left_expr->maybe_null)
{
- if (!(item= new (thd->mem_root) Item_func_trig_cond(item,
+ if (!(item= new (thd->mem_root) Item_func_trig_cond(thd, item,
get_cond_guard(0))))
DBUG_RETURN(true);
}
@@ -2116,8 +2120,8 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
if (select_lex->master_unit()->is_union())
{
Item *new_having=
- func->create(thd->mem_root, expr,
- new (thd->mem_root) Item_ref_null_helper(
+ func->create(thd, expr,
+ new (thd->mem_root) Item_ref_null_helper(thd,
&select_lex->context,
this,
select_lex->ref_pointer_array,
@@ -2125,7 +2129,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN * join,
(char *)"<result>"));
if (!abort_on_null && left_expr->maybe_null)
{
- if (!(new_having= new (thd->mem_root) Item_func_trig_cond(new_having,
+ if (!(new_having= new (thd->mem_root) Item_func_trig_cond(thd, new_having,
get_cond_guard(0))))
DBUG_RETURN(true);
}
@@ -2298,48 +2302,56 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
check_cols(left_expr->element_index(i)->cols()))
DBUG_RETURN(true);
Item *item_eq=
- new Item_func_eq(new
- Item_direct_ref(&select_lex->context,
- (*optimizer->get_cache())->
- addr(i),
- (char *)"<no matter>",
- (char *)in_left_expr_name),
- new
- Item_ref(&select_lex->context,
- select_lex->ref_pointer_array + i,
+ new (thd->mem_root)
+ Item_func_eq(thd, new (thd->mem_root)
+ Item_direct_ref(thd, &select_lex->context,
+ (*optimizer->get_cache())->
+ addr(i),
+ (char *)"<no matter>",
+ (char *)in_left_expr_name),
+ new (thd->mem_root)
+ Item_ref(thd, &select_lex->context,
+ select_lex->ref_pointer_array + i,
+ (char *)"<no matter>",
+ (char *)"<list ref>"));
+ Item *item_isnull=
+ new (thd->mem_root)
+ Item_func_isnull(thd,
+ new (thd->mem_root)
+ Item_ref(thd, &select_lex->context,
+ select_lex->ref_pointer_array+i,
(char *)"<no matter>",
(char *)"<list ref>"));
- Item *item_isnull=
- new Item_func_isnull(new
- Item_ref(&select_lex->context,
- select_lex->ref_pointer_array+i,
- (char *)"<no matter>",
- (char *)"<list ref>"));
- Item *col_item= new Item_cond_or(item_eq, item_isnull);
+ Item *col_item= new (thd->mem_root)
+ Item_cond_or(thd, item_eq, item_isnull);
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
- if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
+ if (!(col_item= new (thd->mem_root)
+ Item_func_trig_cond(thd, col_item, get_cond_guard(i))))
DBUG_RETURN(true);
}
- *having_item= and_items(*having_item, col_item);
+ *having_item= and_items(thd, *having_item, col_item);
Item *item_nnull_test=
- new Item_is_not_null_test(this,
- new Item_ref(&select_lex->context,
- select_lex->
- ref_pointer_array + i,
- (char *)"<no matter>",
- (char *)"<list ref>"));
+ new (thd->mem_root)
+ Item_is_not_null_test(thd, this,
+ new (thd->mem_root)
+ Item_ref(thd, &select_lex->context,
+ select_lex->
+ ref_pointer_array + i,
+ (char *)"<no matter>",
+ (char *)"<list ref>"));
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
if (!(item_nnull_test=
- new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
+ new (thd->mem_root)
+ Item_func_trig_cond(thd, item_nnull_test, get_cond_guard(i))))
DBUG_RETURN(true);
}
- item_having_part2= and_items(item_having_part2, item_nnull_test);
+ item_having_part2= and_items(thd, item_having_part2, item_nnull_test);
item_having_part2->top_level_item();
}
- *having_item= and_items(*having_item, item_having_part2);
+ *having_item= and_items(thd, *having_item, item_having_part2);
}
else
{
@@ -2354,54 +2366,59 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
if (select_lex->ref_pointer_array[i]->
check_cols(left_expr->element_index(i)->cols()))
DBUG_RETURN(true);
- item=
- new Item_func_eq(new
- Item_direct_ref(&select_lex->context,
- (*optimizer->get_cache())->
- addr(i),
- (char *)"<no matter>",
- (char *)in_left_expr_name),
- new
- Item_direct_ref(&select_lex->context,
- select_lex->
- ref_pointer_array+i,
- (char *)"<no matter>",
- (char *)"<list ref>"));
+ item= new (thd->mem_root)
+ Item_func_eq(thd,
+ new (thd->mem_root)
+ Item_direct_ref(thd, &select_lex->context,
+ (*optimizer->get_cache())->
+ addr(i),
+ (char *)"<no matter>",
+ (char *)in_left_expr_name),
+ new (thd->mem_root)
+ Item_direct_ref(thd, &select_lex->context,
+ select_lex->
+ ref_pointer_array+i,
+ (char *)"<no matter>",
+ (char *)"<list ref>"));
if (!abort_on_null && select_lex->ref_pointer_array[i]->maybe_null)
{
Item *having_col_item=
- new Item_is_not_null_test(this,
- new
- Item_ref(&select_lex->context,
- select_lex->ref_pointer_array + i,
- (char *)"<no matter>",
- (char *)"<list ref>"));
+ new (thd->mem_root)
+ Item_is_not_null_test(thd, this,
+ new (thd->mem_root)
+ Item_ref(thd, &select_lex->context,
+ select_lex->ref_pointer_array + i,
+ (char *)"<no matter>",
+ (char *)"<list ref>"));
- item_isnull= new
- Item_func_isnull(new
- Item_direct_ref(&select_lex->context,
+ item_isnull= new (thd->mem_root)
+ Item_func_isnull(thd,
+ new (thd->mem_root)
+ Item_direct_ref(thd, &select_lex->context,
select_lex->
ref_pointer_array+i,
(char *)"<no matter>",
(char *)"<list ref>"));
- item= new Item_cond_or(item, item_isnull);
+ item= new (thd->mem_root) Item_cond_or(thd, item, item_isnull);
if (left_expr->element_index(i)->maybe_null)
{
- if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
+ if (!(item= new (thd->mem_root)
+ Item_func_trig_cond(thd, item, get_cond_guard(i))))
DBUG_RETURN(true);
- if (!(having_col_item=
- new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
+ if (!(having_col_item= new (thd->mem_root)
+ Item_func_trig_cond(thd, having_col_item, get_cond_guard(i))))
DBUG_RETURN(true);
}
- *having_item= and_items(*having_item, having_col_item);
+ *having_item= and_items(thd, *having_item, having_col_item);
}
if (!abort_on_null && left_expr->element_index(i)->maybe_null)
{
- if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
+ if (!(item= new (thd->mem_root)
+ Item_func_trig_cond(thd, item, get_cond_guard(i))))
DBUG_RETURN(true);
}
- *where_item= and_items(*where_item, item);
+ *where_item= and_items(thd, *where_item, item);
}
}
@@ -2531,7 +2548,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
and_args->disjoin((List<Item> *) &join_arg->cond_equal->current_level);
}
- where_item= and_items(join_arg->conds, where_item);
+ where_item= and_items(thd, join_arg->conds, where_item);
if (!where_item->fixed && where_item->fix_fields(thd, 0))
DBUG_RETURN(true);
// TIMOUR TODO: call optimize_cond() for the new where clause
@@ -2548,7 +2565,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
Item_equal *elem;
while ((elem= li++))
{
- and_args->push_back(elem);
+ and_args->push_back(elem, thd->mem_root);
}
}
}
@@ -2556,7 +2573,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
if (having_item)
{
Item* join_having= join_arg->having ? join_arg->having:join_arg->tmp_having;
- having_item= and_items(join_having, having_item);
+ having_item= and_items(thd, join_having, having_item);
if (fix_having(having_item, select_lex))
DBUG_RETURN(true);
// TIMOUR TODO: call optimize_cond() for the new having clause
@@ -2565,7 +2582,8 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
join_arg->having= select_lex->having;
}
join_arg->thd->change_item_tree(&unit->global_parameters()->select_limit,
- new Item_int((int32) 1));
+ new (thd->mem_root)
+ Item_int(thd, (int32) 1));
unit->select_limit_cnt= 1;
DBUG_RETURN(false);
@@ -2592,7 +2610,7 @@ bool Item_exists_subselect::select_prepare_to_be_in()
Query_arena *arena, backup;
bool result;
arena= thd->activate_stmt_arena_if_needed(&backup);
- result= (!(optimizer= new Item_in_optimizer(new Item_int(1), this)));
+ result= (!(optimizer= new (thd->mem_root) Item_in_optimizer(thd, new (thd->mem_root) Item_int(thd, 1), this)));
if (arena)
thd->restore_active_arena(arena, &backup);
if (result)
@@ -2805,20 +2823,24 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
it.replace(local_field);
else
{
- first_select->item_list.push_back(local_field);
+ first_select->item_list.push_back(local_field, thd->mem_root);
first_select->join->all_fields.elements++;
}
first_select->ref_pointer_array[i]= (Item *)local_field;
/* remove the parts from condition */
if (!upper_not || !local_field->maybe_null)
- *eq_ref= new Item_int(1);
+ *eq_ref= new (thd->mem_root) Item_int(thd, 1);
else
{
- *eq_ref= new Item_func_isnotnull(
- new Item_field(thd,
- ((Item_field*)(local_field->real_item()))->context,
- ((Item_field*)(local_field->real_item()))->field));
+ *eq_ref= new (thd->mem_root)
+ Item_func_isnotnull(thd,
+ new (thd->mem_root)
+ Item_field(thd,
+ ((Item_field*)(local_field->
+ real_item()))->context,
+ ((Item_field*)(local_field->
+ real_item()))->field));
if((*eq_ref)->fix_fields(thd, (Item **)eq_ref))
{
res= TRUE;
@@ -2827,7 +2849,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
}
outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp);
outer_exp->update_used_tables();
- outer.push_back(outer_exp);
+ outer.push_back(outer_exp, thd->mem_root);
}
}
@@ -2838,7 +2860,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
left_exp= outer_exp;
else
{
- if (!(left_exp= new Item_row(outer)))
+ if (!(left_exp= new (thd->mem_root) Item_row(thd, outer)))
{
res= TRUE;
goto out;
@@ -2850,7 +2872,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
first_select->select_limit= NULL;
if (!(in_subs= new (thd->mem_root) Item_in_subselect(thd, left_exp,
- first_select)))
+ first_select)))
{
res= TRUE;
goto out;
@@ -2880,10 +2902,11 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
As far as Item_ref_in_optimizer do not substitute itself on fix_fields
we can use same item for all selects.
*/
- in_subs->expr= new Item_direct_ref(&first_select->context,
- (Item**)optimizer->get_cache(),
- (char *)"<no matter>",
- (char *)in_left_expr_name);
+ in_subs->expr= new (thd->mem_root)
+ Item_direct_ref(thd, &first_select->context,
+ (Item**)optimizer->get_cache(),
+ (char *)"<no matter>",
+ (char *)in_left_expr_name);
if (in_subs->fix_fields(thd, optimizer->arguments() + 1))
{
res= TRUE;
@@ -2945,14 +2968,17 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
if (eqs.elements() == 1)
{
exp= (optimizer->arguments()[0]->maybe_null ?
- (Item*)
- new Item_cond_and(
- new Item_func_isnotnull(
- new Item_direct_ref(&unit->outer_select()->context,
- optimizer->arguments(),
- (char *)"<no matter>",
- (char *)exists_outer_expr_name)),
- optimizer) :
+ (Item*) new (thd->mem_root)
+ Item_cond_and(thd,
+ new (thd->mem_root)
+ Item_func_isnotnull(thd,
+ new (thd->mem_root)
+ Item_direct_ref(thd,
+ &unit->outer_select()->context,
+ optimizer->arguments(),
+ (char *)"<no matter>",
+ (char *)exists_outer_expr_name)),
+ optimizer) :
(Item *)optimizer);
}
else
@@ -2968,18 +2994,21 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg)
if (optimizer->arguments()[0]->maybe_null)
{
and_list->
- push_front(
- new Item_func_isnotnull(
- new Item_direct_ref(&unit->outer_select()->context,
- optimizer->arguments()[0]->addr(i),
- (char *)"<no matter>",
- (char *)exists_outer_expr_name)));
+ push_front(new (thd->mem_root)
+ Item_func_isnotnull(thd,
+ new (thd->mem_root)
+ Item_direct_ref(thd,
+ &unit->outer_select()->context,
+ optimizer->arguments()[0]->addr(i),
+ (char *)"<no matter>",
+ (char *)exists_outer_expr_name)),
+ thd->mem_root);
}
}
if (and_list->elements > 0)
{
- and_list->push_front(optimizer);
- exp= new Item_cond_and(*and_list);
+ and_list->push_front(optimizer, thd->mem_root);
+ exp= new (thd->mem_root) Item_cond_and(thd, *and_list);
}
else
exp= optimizer;
@@ -3054,7 +3083,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join)
arena= thd->activate_stmt_arena_if_needed(&backup);
if (!optimizer)
{
- result= (!(optimizer= new Item_in_optimizer(left_expr, this)));
+ result= (!(optimizer= new (thd->mem_root) Item_in_optimizer(thd, left_expr, this)));
if (result)
goto out;
}
@@ -3116,12 +3145,12 @@ void Item_in_subselect::print(String *str, enum_query_type query_type)
Item_subselect::print(str, query_type);
}
-bool Item_exists_subselect::fix_fields(THD *thd_arg, Item **ref)
+bool Item_exists_subselect::fix_fields(THD *thd, Item **ref)
{
DBUG_ENTER("Item_exists_subselect::fix_fields");
if (exists_transformed)
- DBUG_RETURN( !( (*ref)= new Item_int(1)));
- DBUG_RETURN(Item_subselect::fix_fields(thd_arg, ref));
+ DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)));
+ DBUG_RETURN(Item_subselect::fix_fields(thd, ref));
}
@@ -3132,7 +3161,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
DBUG_ENTER("Item_in_subselect::fix_fields");
if (test_strategy(SUBS_SEMI_JOIN))
- DBUG_RETURN( !( (*ref)= new Item_int(1)) );
+ DBUG_RETURN( !( (*ref)= new (thd->mem_root) Item_int(thd, 1)) );
/*
Check if the outer and inner IN operands match in those cases when we
@@ -3283,7 +3312,8 @@ bool Item_in_subselect::init_left_expr_cache()
Cached_item *cur_item_cache= new_Cached_item(thd,
left_expr->element_index(i),
FALSE);
- if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache))
+ if (!cur_item_cache || left_expr_cache->push_front(cur_item_cache,
+ thd->mem_root))
return TRUE;
}
return FALSE;
@@ -3563,9 +3593,9 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item->decimals= sel_item->decimals;
item->unsigned_flag= sel_item->unsigned_flag;
maybe_null= sel_item->maybe_null;
- if (!(row[i]= Item_cache::get_cache(sel_item, sel_item->cmp_type())))
+ if (!(row[i]= Item_cache::get_cache(thd, sel_item, sel_item->cmp_type())))
return;
- row[i]->setup(sel_item);
+ row[i]->setup(thd, sel_item);
//psergey-backport-timours: row[i]->store(sel_item);
}
if (item_list.elements > 1)
@@ -4581,7 +4611,7 @@ subselect_hash_sj_engine::get_strategy_using_data()
void
subselect_hash_sj_engine::choose_partial_match_strategy(
bool has_non_null_key, bool has_covering_null_row,
- MY_BITMAP *partial_match_key_parts)
+ MY_BITMAP *partial_match_key_parts_arg)
{
ulonglong pm_buff_size;
@@ -4632,7 +4662,7 @@ subselect_hash_sj_engine::choose_partial_match_strategy(
{
pm_buff_size= rowid_merge_buff_size(has_non_null_key,
has_covering_null_row,
- partial_match_key_parts);
+ partial_match_key_parts_arg);
if (pm_buff_size > thd->variables.rowid_merge_buff_size)
strategy= PARTIAL_MATCH_SCAN;
}
@@ -4886,7 +4916,7 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
DBUG_ENTER("subselect_hash_sj_engine::make_semi_join_conds");
DBUG_ASSERT(semi_join_conds == NULL);
- if (!(semi_join_conds= new Item_cond_and))
+ if (!(semi_join_conds= new (thd->mem_root) Item_cond_and(thd)))
DBUG_RETURN(TRUE);
if (!(tmp_table_ref= (TABLE_LIST*) thd->alloc(sizeof(TABLE_LIST))))
@@ -4906,14 +4936,17 @@ bool subselect_hash_sj_engine::make_semi_join_conds()
for (uint i= 0; i < item_in->left_expr->cols(); i++)
{
- Item_func_eq *eq_cond; /* New equi-join condition for the current column. */
+ /* New equi-join condition for the current column. */
+ Item_func_eq *eq_cond;
/* Item for the corresponding field from the materialized temp table. */
Item_field *right_col_item;
- if (!(right_col_item= new Item_field(thd, context, tmp_table->field[i])) ||
- !(eq_cond= new Item_func_eq(item_in->left_expr->element_index(i),
- right_col_item)) ||
- (((Item_cond_and*)semi_join_conds)->add(eq_cond)))
+ if (!(right_col_item= new (thd->mem_root)
+ Item_field(thd, context, tmp_table->field[i])) ||
+ !(eq_cond= new (thd->mem_root)
+ Item_func_eq(thd, item_in->left_expr->element_index(i),
+ right_col_item)) ||
+ (((Item_cond_and*)semi_join_conds)->add(eq_cond, thd->mem_root)))
{
delete semi_join_conds;
semi_join_conds= NULL;
@@ -5518,9 +5551,9 @@ bool Ordered_key::init(MY_BITMAP *columns_to_index)
{
if (!bitmap_is_set(columns_to_index, i))
continue;
- cur_tmp_field= new Item_field(tbl->field[i]);
+ cur_tmp_field= new (thd->mem_root) Item_field(thd, tbl->field[i]);
/* Create the predicate (tmp_column[i] < outer_ref[i]). */
- fn_less_than= new Item_func_lt(cur_tmp_field,
+ fn_less_than= new (thd->mem_root) Item_func_lt(thd, cur_tmp_field,
search_key->element_index(i));
fn_less_than->fix_fields(thd, (Item**) &fn_less_than);
key_columns[cur_key_col]= cur_tmp_field;
@@ -5552,9 +5585,9 @@ bool Ordered_key::init(int col_idx)
key_columns= (Item_field**) thd->alloc(sizeof(Item_field*));
compare_pred= (Item_func_lt**) thd->alloc(sizeof(Item_func_lt*));
- key_columns[0]= new Item_field(tbl->field[col_idx]);
+ key_columns[0]= new (thd->mem_root) Item_field(thd, tbl->field[col_idx]);
/* Create the predicate (tmp_column[i] < outer_ref[i]). */
- compare_pred[0]= new Item_func_lt(key_columns[0],
+ compare_pred[0]= new (thd->mem_root) Item_func_lt(thd, key_columns[0],
search_key->element_index(col_idx));
compare_pred[0]->fix_fields(thd, (Item**)&compare_pred[0]);
@@ -6556,3 +6589,23 @@ void subselect_table_scan_engine::cleanup()
{
}
+
+/*
+ Create an execution tracker for the expression cache we're using for this
+ subselect; add the tracker to the query plan.
+*/
+
+void Item_subselect::init_expr_cache_tracker(THD *thd)
+{
+ if(!expr_cache)
+ return;
+
+ Explain_query *qw= thd->lex->explain;
+ DBUG_ASSERT(qw);
+ Explain_node *node= qw->get_node(unit->first_select()->select_number);
+ if (!node)
+ return;
+ DBUG_ASSERT(expr_cache->type() == Item::EXPR_CACHE_ITEM);
+ node->cache_tracker= ((Item_cache_wrapper *)expr_cache)->init_tracker(qw->mem_root);
+}
+