Commit 2ae8a00b authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

Item tree iterator

fixed dependence of items from reduced subquery
(SCRUM)
parent 5eaaf8e7
......@@ -85,6 +85,15 @@ Item_ident::Item_ident(THD *thd, Item_ident &item):
depended_from(item.depended_from)
{}
bool Item_ident::remove_dependence_processor(byte * arg)
{
DBUG_ENTER("Item_ident::remove_dependence_processor");
if (depended_from == (st_select_lex *) arg)
depended_from= 0;
DBUG_RETURN(1);
}
bool Item::check_cols(uint c)
{
if (c != 1)
......
......@@ -82,6 +82,8 @@ public:
}
};
typedef bool (Item::*Item_processor)(byte *arg);
class Item {
uint loop_id; /* Used to find selfrefering loops */
Item(const Item &); /* Prevent use of these */
......@@ -188,6 +190,13 @@ public:
bool binary() const
{ return charset()->state & MY_CS_BINSORT ? 1 : 0 ; }
virtual bool walk(Item_processor processor, byte *arg)
{
return (this->*processor)(arg);
}
virtual bool remove_dependence_processor(byte * arg) { return 0; }
// Row emulation
virtual uint cols() { return 1; }
virtual Item* el(uint i) { return this; }
......@@ -216,6 +225,8 @@ public:
// Constructor used by Item_field & Item_ref (see Item comment)
Item_ident(THD *thd, Item_ident &item);
const char *full_name() const;
bool remove_dependence_processor(byte * arg);
};
......@@ -833,6 +844,12 @@ public:
return Item_field::save_in_field(field, no_conversions);
}
table_map used_tables() const { return (table_map)0L; }
bool walk(Item_processor processor, byte *args)
{
return arg->walk(processor, args) ||
(this->*processor)(args);
}
};
class Item_insert_value : public Item_field
......@@ -850,6 +867,12 @@ public:
return Item_field::save_in_field(field, no_conversions);
}
table_map used_tables() const { return (table_map)0L; }
bool walk(Item_processor processor, byte *args)
{
return arg->walk(processor, args) ||
(this->*processor)(args);
}
};
class Item_cache: public Item
......
......@@ -1094,6 +1094,13 @@ void Item_func_case::split_sum_func(Item **ref_pointer_array,
}
bool Item_func_case::walk (Item_processor processor, byte *arg)
{
return first_expr->walk(processor, arg) ||
else_expr->walk(processor, arg) ||
Item_func::walk(processor, arg);
}
void Item_func_case::update_used_tables()
{
Item_func::update_used_tables();
......@@ -1662,6 +1669,16 @@ Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0;
}
bool Item_cond::walk(Item_processor processor, byte *arg)
{
List_iterator_fast<Item> li(list);
Item *item;
while ((item= li++))
if (item->walk(processor, arg))
return 1;
return Item_func::walk(processor, arg);
}
void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
{
List_iterator<Item> li(list);
......
......@@ -370,6 +370,8 @@ public:
bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
Item *find_item(String *str);
bool walk(Item_processor processor, byte *args);
};
......@@ -632,6 +634,11 @@ class Item_func_in :public Item_int_func
void update_used_tables();
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
bool nulls_in_row();
bool walk(Item_processor processor, byte *arg)
{
return item->walk(processor, arg) ||
Item_int_func::walk(processor, arg);
}
};
/* Functions used by where clause */
......@@ -790,6 +797,8 @@ public:
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
void top_level_item() { abort_on_null=1; }
bool walk(Item_processor processor, byte *arg);
};
......
......@@ -136,6 +136,19 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0;
}
bool Item_func::walk (Item_processor processor, byte *argument)
{
if (arg_count)
{
Item **arg,**arg_end;
for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
{
if ((*arg)->walk(processor, argument))
return 1;
}
}
return (this->*processor)(argument);
}
void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
{
......@@ -2434,6 +2447,15 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
return 0;
}
bool Item_func_match::walk(Item_processor processor, byte *arg)
{
List_iterator_fast<Item> li(fields);
Item *item;
while ((item= li++))
if (item->walk(processor, arg))
return 1;
return Item_func::walk(processor, arg);
}
bool Item_func_match::fix_index()
{
......
......@@ -134,6 +134,8 @@ public:
Field *tmp_table_field() { return result_field; }
Field *tmp_table_field(TABLE *t_arg);
Item *get_tmp_table_item(THD *thd);
bool walk(Item_processor processor, byte *arg);
};
......@@ -647,6 +649,11 @@ public:
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
bool walk(Item_processor processor, byte *arg)
{
return item->walk(processor, arg) ||
Item_int_func::walk(processor, arg);
}
};
......@@ -1024,6 +1031,8 @@ public:
bool fix_index();
void init_search(bool no_order);
bool walk(Item_processor processor, byte *arg);
};
......
......@@ -118,6 +118,16 @@ bool Item_row::check_cols(uint c)
return 0;
}
bool Item_row::walk(Item_processor processor, byte *arg)
{
for (uint i= 0; i < arg_count; i++)
{
if (items[i]->walk(processor, arg))
return 1;
}
return (this->*processor)(arg);
}
void Item_row::bring_value()
{
for (uint i= 0; i < arg_count; i++)
......
......@@ -69,6 +69,8 @@ public:
enum Item_result result_type() const { return ROW_RESULT; }
void update_used_tables();
bool walk(Item_processor processor, byte *arg);
uint cols() { return arg_count; }
Item* el(uint i) { return items[i]; }
Item** addr(uint i) { return items + i; }
......
......@@ -107,6 +107,11 @@ public:
}
void split_sum_func(Item **ref_pointer_array, List<Item> &fields);
const char *func_name() const { return "concat_ws"; }
bool walk(Item_processor processor, byte *arg)
{
return separator->walk(processor, arg) ||
Item_str_func::walk(processor, arg);
}
};
class Item_func_reverse :public Item_str_func
......@@ -385,6 +390,11 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "elt"; }
bool walk(Item_processor processor, byte *arg)
{
return item->walk(processor, arg) ||
Item_str_func::walk(processor, arg);
}
};
......@@ -407,6 +417,12 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "make_set"; }
bool walk(Item_processor processor, byte *arg)
{
return item->walk(processor, arg) ||
Item_str_func::walk(processor, arg);
}
};
......
......@@ -193,7 +193,12 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
ER_SELECT_REDUCED, warn_buff);
}
substitution= select_lex->item_list.head();
/*
as far as we moved content to upper leven, field which depend of
'upper' select is not really dependent => we remove this dependence
*/
substitution->walk(&Item::remove_dependence_processor,
(byte *) select_lex->outer_select());
if (select_lex->where || select_lex->having)
{
Item *cond;
......
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