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