summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc34
1 files changed, 34 insertions, 0 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 62e76922c0e..a77443f40ef 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1420,6 +1420,7 @@ bool Item_in_optimizer::is_top_level_item()
void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
+ DBUG_ASSERT(fixed);
/* This will re-calculate attributes of our Item_in_subselect: */
Item_bool_func::fix_after_pullout(new_parent, ref);
@@ -1443,6 +1444,33 @@ bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg)
}
+void Item_in_optimizer::print(String *str, enum_query_type query_type)
+{
+ restore_first_argumet();
+ Item_func::print(str, query_type);
+}
+
+
+/**
+ "Restore" first argument before fix_fields() call (after it is harmless).
+
+ @Note: Main pointer to left part of IN/ALL/ANY subselect is subselect's
+ lest_expr (see Item_in_optimizer::fix_left) so changes made during
+ fix_fields will be rolled back there which can make
+ Item_in_optimizer::args[0] unusable on second execution before fix_left()
+ call. This call fix the pointer.
+*/
+
+void Item_in_optimizer::restore_first_argumet()
+{
+ if (args[1]->type() == Item::SUBSELECT_ITEM &&
+ ((Item_subselect *)args[1])->is_in_predicate())
+ {
+ args[0]= ((Item_in_subselect *)args[1])->left_expr;
+ }
+}
+
+
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
DBUG_ENTER("Item_in_optimizer::fix_left");
@@ -1588,6 +1616,8 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
{
THD *thd= (THD*) thd_arg;
DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
+ DBUG_ASSERT(fixed);
+
if (args[1]->type() != Item::SUBSELECT_ITEM)
DBUG_RETURN(this); // MAX/MIN transformed => do nothing
@@ -1611,6 +1641,7 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
void Item_in_optimizer::get_cache_parameters(List<Item> &parameters)
{
+ DBUG_ASSERT(fixed);
/* Add left expression to the list of the parameters of the subquery */
if (args[0]->cols() == 1)
parameters.add_unique(args[0], &cmp_items);
@@ -1842,6 +1873,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument
{
Item *new_item;
+ DBUG_ASSERT(fixed);
DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare());
DBUG_ASSERT(arg_count == 2);
@@ -1893,6 +1925,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument
bool Item_in_optimizer::is_expensive_processor(uchar *arg)
{
+ DBUG_ASSERT(fixed);
return args[0]->is_expensive_processor(arg) ||
args[1]->is_expensive_processor(arg);
}
@@ -1900,6 +1933,7 @@ bool Item_in_optimizer::is_expensive_processor(uchar *arg)
bool Item_in_optimizer::is_expensive()
{
+ DBUG_ASSERT(fixed);
return args[0]->is_expensive() || args[1]->is_expensive();
}