diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-04-24 12:59:21 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-04-24 12:59:21 +0400 |
commit | 04fb09d7811606e1a1a8f646532e1b379d50b217 (patch) | |
tree | eaff2e4e2123dc8bcd215a46ebed96adebe46891 /sql | |
parent | c2dd88ac85e6b1fe63ac36465f62a784cf6b4d4a (diff) | |
download | mariadb-git-04fb09d7811606e1a1a8f646532e1b379d50b217.tar.gz |
Deriving Item_row from Item_args and sharing more code
between Item_func, Item_sum, Item_row.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 16 | ||||
-rw-r--r-- | sql/item_func.cc | 57 | ||||
-rw-r--r-- | sql/item_func.h | 1 | ||||
-rw-r--r-- | sql/item_row.cc | 76 | ||||
-rw-r--r-- | sql/item_row.h | 38 | ||||
-rw-r--r-- | sql/item_sum.cc | 16 | ||||
-rw-r--r-- | sql/item_sum.h | 1 |
7 files changed, 75 insertions, 130 deletions
diff --git a/sql/item.h b/sql/item.h index 4b42db2aa9e..314882662ea 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3275,6 +3275,16 @@ class Item_args protected: Item **args, *tmp_arg[2]; void set_arguments(List<Item> &list); + bool walk_args(Item_processor processor, bool walk_subquery, uchar *arg) + { + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->walk(processor, walk_subquery, arg)) + return true; + } + return false; + } + bool transform_args(Item_transformer transformer, uchar *arg); public: uint arg_count; Item_args(void) @@ -3417,6 +3427,12 @@ public: :Item_result_field(thd, item), Item_args(thd, item) { } Item_func_or_sum(List<Item> &list) :Item_result_field(), Item_args(list) { } + bool walk(Item_processor processor, bool walk_subquery, uchar *arg) + { + if (walk_args(processor, walk_subquery, arg)) + return true; + return (this->*processor)(arg); + } /* This method is used for debug purposes to print the name of an item to the debug log. The second use of this method is as diff --git a/sql/item_func.cc b/sql/item_func.cc index fb4b78df875..ffbc06a1bce 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -291,21 +291,6 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref) } -bool Item_func::walk(Item_processor processor, bool walk_subquery, - uchar *argument) -{ - if (arg_count) - { - Item **arg,**arg_end; - for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) - { - if ((*arg)->walk(processor, walk_subquery, argument)) - return 1; - } - } - return (this->*processor)(argument); -} - void Item_func::traverse_cond(Cond_traverser traverser, void *argument, traverse_order order) { @@ -334,6 +319,26 @@ void Item_func::traverse_cond(Cond_traverser traverser, } +bool Item_args::transform_args(Item_transformer transformer, uchar *arg) +{ + for (uint i= 0; i < arg_count; i++) + { + Item *new_item= args[i]->transform(transformer, arg); + if (!new_item) + return true; + /* + THD::change_item_tree() should be called only if the tree was + really transformed, i.e. when a new item has been created. + Otherwise we'll be allocating a lot of unnecessary memory for + change records at each execution. + */ + if (args[i] != new_item) + current_thd->change_item_tree(&args[i], new_item); + } + return false; +} + + /** Transform an Item_func object with a transformer callback function. @@ -354,26 +359,8 @@ void Item_func::traverse_cond(Cond_traverser traverser, Item *Item_func::transform(Item_transformer transformer, uchar *argument) { DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare()); - - if (arg_count) - { - Item **arg,**arg_end; - for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) - { - Item *new_item= (*arg)->transform(transformer, argument); - if (!new_item) - return 0; - - /* - THD::change_item_tree() should be called only if the tree was - really transformed, i.e. when a new item has been created. - Otherwise we'll be allocating a lot of unnecessary memory for - change records at each execution. - */ - if (*arg != new_item) - current_thd->change_item_tree(arg, new_item); - } - } + if (transform_args(transformer, argument)) + return 0; return (this->*transformer)(argument); } diff --git a/sql/item_func.h b/sql/item_func.h index 1b7988ab3cf..eff6b2f3e48 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -232,7 +232,6 @@ public: items, nitems, item_sep); } - bool walk(Item_processor processor, bool walk_subquery, uchar *arg); Item *transform(Item_transformer transformer, uchar *arg); Item* compile(Item_analyzer analyzer, uchar **arg_p, Item_transformer transformer, uchar *arg_t); diff --git a/sql/item_row.cc b/sql/item_row.cc index 1fc2000813b..dea26ebc6ae 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -24,38 +24,6 @@ #include "sql_class.h" // THD, set_var.h: THD #include "set_var.h" -/** - Row items used for comparing rows and IN operations on rows: - - @verbatim - (a, b, c) > (10, 10, 30) - (a, b, c) = (select c, d, e, from t1 where x=12) - (a, b, c) IN ((1,2,2), (3,4,5), (6,7,8) - (a, b, c) IN (select c, d, e, from t1) - @endverbatim - - @todo - think placing 2-3 component items in item (as it done for function -*/ - -Item_row::Item_row(List<Item> &arg): - Item(), Used_tables_and_const_cache(), not_null_tables_cache(0), with_null(0) -{ - - //TODO: think placing 2-3 component items in item (as it done for function) - if ((arg_count= arg.elements)) - items= (Item**) sql_alloc(sizeof(Item*)*arg_count); - else - items= 0; - List_iterator_fast<Item> li(arg); - uint i= 0; - Item *item; - while ((item= li++)) - { - items[i]= item; - i++; - } -} void Item_row::illegal_method_call(const char *method) { @@ -72,7 +40,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref) null_value= 0; maybe_null= 0; Item **arg, **arg_end; - for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) + for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++) { if (!(*arg)->fixed && (*arg)->fix_fields(thd, arg)) @@ -110,7 +78,7 @@ Item_row::eval_not_null_tables(uchar *opt_arg) not_null_tables_cache= 0; if (arg_count) { - for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) + for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++) { not_null_tables_cache|= (*arg)->not_null_tables(); } @@ -136,7 +104,7 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields) { Item **arg, **arg_end; - for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++) + for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++) (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, TRUE); } @@ -147,9 +115,9 @@ void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref) not_null_tables_cache= 0; for (uint i= 0; i < arg_count; i++) { - items[i]->fix_after_pullout(new_parent, &items[i]); - used_tables_and_const_cache_join(items[i]); - not_null_tables_cache|= items[i]->not_null_tables(); + args[i]->fix_after_pullout(new_parent, &args[i]); + used_tables_and_const_cache_join(args[i]); + not_null_tables_cache|= args[i]->not_null_tables(); } } @@ -171,47 +139,23 @@ void Item_row::print(String *str, enum_query_type query_type) { if (i) str->append(','); - items[i]->print(str, query_type); + args[i]->print(str, query_type); } str->append(')'); } -bool Item_row::walk(Item_processor processor, bool walk_subquery, uchar *arg) -{ - for (uint i= 0; i < arg_count; i++) - { - if (items[i]->walk(processor, walk_subquery, arg)) - return 1; - } - return (this->*processor)(arg); -} - - Item *Item_row::transform(Item_transformer transformer, uchar *arg) { DBUG_ASSERT(!current_thd->stmt_arena->is_stmt_prepare()); - for (uint i= 0; i < arg_count; i++) - { - Item *new_item= items[i]->transform(transformer, arg); - if (!new_item) - return 0; - - /* - THD::change_item_tree() should be called only if the tree was - really transformed, i.e. when a new item has been created. - Otherwise we'll be allocating a lot of unnecessary memory for - change records at each execution. - */ - if (items[i] != new_item) - current_thd->change_item_tree(&items[i], new_item); - } + if (transform_args(transformer, arg)) + return 0; return (this->*transformer)(arg); } void Item_row::bring_value() { for (uint i= 0; i < arg_count; i++) - items[i]->bring_value(); + args[i]->bring_value(); } diff --git a/sql/item_row.h b/sql/item_row.h index 31efc015909..1bec6212715 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -17,20 +17,31 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -class Item_row: public Item, private Used_tables_and_const_cache +/** + Row items used for comparing rows and IN operations on rows: + + @verbatim + (a, b, c) > (10, 10, 30) + (a, b, c) = (select c, d, e, from t1 where x=12) + (a, b, c) IN ((1,2,2), (3,4,5), (6,7,8) + (a, b, c) IN (select c, d, e, from t1) + @endverbatim +*/ + +class Item_row: public Item, + private Item_args, + private Used_tables_and_const_cache { - Item **items; table_map not_null_tables_cache; - uint arg_count; bool with_null; public: - Item_row(List<Item> &); + Item_row(List<Item> &list) + :Item_args(list), not_null_tables_cache(0), with_null(0) + { } Item_row(Item_row *item): - Item(), + Item_args(item), Used_tables_and_const_cache(item), - items(item->items), not_null_tables_cache(0), - arg_count(item->arg_count), with_null(0) {} @@ -72,18 +83,23 @@ public: void update_used_tables() { used_tables_and_const_cache_init(); - used_tables_and_const_cache_update_and_join(arg_count, items); + used_tables_and_const_cache_update_and_join(arg_count, args); } table_map not_null_tables() const { return not_null_tables_cache; } virtual void print(String *str, enum_query_type query_type); - bool walk(Item_processor processor, bool walk_subquery, uchar *arg); + bool walk(Item_processor processor, bool walk_subquery, uchar *arg) + { + if (walk_args(processor, walk_subquery, arg)) + return true; + return (this->*processor)(arg); + } Item *transform(Item_transformer transformer, uchar *arg); bool eval_not_null_tables(uchar *opt_arg); uint cols() { return arg_count; } - Item* element_index(uint i) { return items[i]; } - Item** addr(uint i) { return items + i; } + Item* element_index(uint i) { return args[i]; } + Item** addr(uint i) { return args + i; } bool check_cols(uint c); bool null_inside() { return with_null; }; void bring_value(); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 6b00316849e..bac5c599561 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -497,22 +497,6 @@ Item *Item_sum::get_tmp_table_item(THD *thd) } -bool Item_sum::walk (Item_processor processor, bool walk_subquery, - uchar *argument) -{ - if (arg_count) - { - Item **arg,**arg_end; - for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++) - { - if ((*arg)->walk(processor, walk_subquery, argument)) - return 1; - } - } - return (this->*processor)(argument); -} - - Field *Item_sum::create_tmp_field(bool group, TABLE *table, uint convert_blob_length) { diff --git a/sql/item_sum.h b/sql/item_sum.h index 8435924e62d..db45a336b46 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -476,7 +476,6 @@ public: Item *get_tmp_table_item(THD *thd); virtual Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length); - bool walk(Item_processor processor, bool walk_subquery, uchar *argument); virtual bool collect_outer_ref_processor(uchar *param); bool init_sum_func_check(THD *thd); bool check_sum_func(THD *thd, Item **ref); |