diff options
-rw-r--r-- | sql/item.cc | 2 | ||||
-rw-r--r-- | sql/item.h | 88 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 6 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 13 | ||||
-rw-r--r-- | sql/item_func.cc | 70 | ||||
-rw-r--r-- | sql/item_func.h | 85 | ||||
-rw-r--r-- | sql/item_subselect.h | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 21 | ||||
-rw-r--r-- | sql/item_sum.h | 15 |
9 files changed, 179 insertions, 122 deletions
diff --git a/sql/item.cc b/sql/item.cc index c8a9164fd92..3a4d6c61fe7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7466,7 +7466,7 @@ void Item_cache_wrapper::print(String *str, enum_query_type query_type) return; } - str->append(func_name()); + str->append("<expr_cache>"); if (expr_cache) { init_on_demand(); diff --git a/sql/item.h b/sql/item.h index 825496e3e9a..ede69f08373 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3263,6 +3263,93 @@ public: } void cleanup(); bool check_vcol_func_processor(uchar *arg) { return FALSE;} +}; + + +/** + Array of items, e.g. function or aggerate function arguments. +*/ +class Item_args +{ +protected: + Item **args, *tmp_arg[2]; + void set_arguments(List<Item> &list); +public: + uint arg_count; + Item_args(void) + :args(NULL), arg_count(0) + { } + Item_args(Item *a) + :args(tmp_arg), arg_count(1) + { + args[0]= a; + } + Item_args(Item *a, Item *b) + :args(tmp_arg), arg_count(2) + { + args[0]= a; args[1]= b; + } + Item_args(Item *a, Item *b, Item *c) + { + arg_count= 0; + if ((args= (Item**) sql_alloc(sizeof(Item*) * 3))) + { + arg_count= 3; + args[0]= a; args[1]= b; args[2]= c; + } + } + Item_args(Item *a, Item *b, Item *c, Item *d) + { + arg_count= 0; + if ((args= (Item**) sql_alloc(sizeof(Item*) * 4))) + { + arg_count= 4; + args[0]= a; args[1]= b; args[2]= c; args[3]= d; + } + } + Item_args(Item *a, Item *b, Item *c, Item *d, Item* e) + { + arg_count= 5; + if ((args= (Item**) sql_alloc(sizeof(Item*) * 5))) + { + arg_count= 5; + args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e; + } + } + Item_args(List<Item> &list) + { + set_arguments(list); + } + Item_args(THD *thd, const Item_args *other); + inline Item **arguments() const { return args; } + inline uint argument_count() const { return arg_count; } + inline void remove_arguments() { arg_count=0; } +}; + + +/** + An abstract class representing common features of + regular functions and aggregate functions. +*/ +class Item_func_or_sum: public Item_result_field, public Item_args +{ +public: + Item_func_or_sum() + :Item_result_field(), Item_args() {} + Item_func_or_sum(Item *a) + :Item_result_field(), Item_args(a) { } + Item_func_or_sum(Item *a, Item *b) + :Item_result_field(), Item_args(a, b) { } + Item_func_or_sum(Item *a, Item *b, Item *c) + :Item_result_field(), Item_args(a, b, c) { } + Item_func_or_sum(Item *a, Item *b, Item *c, Item *d) + :Item_result_field(), Item_args(a, b, c, d) { } + Item_func_or_sum(Item *a, Item *b, Item *c, Item *d, Item *e) + :Item_result_field(), Item_args(a, b, c, d, e) { } + Item_func_or_sum(THD *thd, Item_func_or_sum *item) + :Item_result_field(thd, item), Item_args(thd, item) { } + Item_func_or_sum(List<Item> &list) + :Item_result_field(), Item_args(list) { } /* 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 @@ -3559,7 +3646,6 @@ public: Item_cache_wrapper(Item *item_arg); ~Item_cache_wrapper(); - const char *func_name() const { return "<expr_cache>"; } enum Type type() const { return EXPR_CACHE_ITEM; } enum Type real_type() const { return orig_item->type(); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 75916456ebd..23676d722a3 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -585,7 +585,7 @@ void Item_bool_func2::fix_length_and_dec() } -int Arg_comparator::set_compare_func(Item_result_field *item, Item_result type) +int Arg_comparator::set_compare_func(Item_func_or_sum *item, Item_result type) { owner= item; func= comparator_matrix[type] @@ -787,7 +787,7 @@ bool Arg_comparator::agg_arg_charsets_for_comparison() items, holding the cached converted value of the original (constant) item. */ -int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, +int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2, Item_result type) { @@ -858,7 +858,7 @@ Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value, } -void Arg_comparator::set_datetime_cmp_func(Item_result_field *owner_arg, +void Arg_comparator::set_datetime_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **b1) { thd= current_thd; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 9c5067569c3..2d039d5e7b7 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -40,7 +40,7 @@ class Arg_comparator: public Sql_alloc { Item **a, **b; arg_cmp_func func; - Item_result_field *owner; + Item_func_or_sum *owner; bool set_null; // TRUE <=> set owner->null_value Arg_comparator *comparators; // used only for compare_row() double precision; @@ -48,8 +48,8 @@ class Arg_comparator: public Sql_alloc THD *thd; Item *a_cache, *b_cache; // Cached values of a and b items // when one of arguments is NULL. - int set_compare_func(Item_result_field *owner, Item_result type); - inline int set_compare_func(Item_result_field *owner_arg) + int set_compare_func(Item_func_or_sum *owner, Item_result type); + inline int set_compare_func(Item_func_or_sum *owner_arg) { return set_compare_func(owner_arg, item_cmp_type((*a)->result_type(), (*b)->result_type())); @@ -67,11 +67,11 @@ public: comparators(0), thd(0), a_cache(0), b_cache(0) {}; private: - int set_cmp_func(Item_result_field *owner_arg, + int set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2, Item_result type); public: - inline int set_cmp_func(Item_result_field *owner_arg, + inline int set_cmp_func(Item_func_or_sum *owner_arg, Item **a1, Item **a2, bool set_null_arg) { set_null= set_null_arg; @@ -104,7 +104,8 @@ public: Item** cache_converted_constant(THD *thd, Item **value, Item **cache, Item_result type); - void set_datetime_cmp_func(Item_result_field *owner_arg, Item **a1, Item **b1); + void set_datetime_cmp_func(Item_func_or_sum *owner_arg, + Item **a1, Item **b1); static arg_cmp_func comparator_matrix [6][2]; inline bool is_owner_equal_func() { diff --git a/sql/item_func.cc b/sql/item_func.cc index 85a5f7c7ced..9179a20ecae 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -88,51 +88,51 @@ static inline bool test_if_sum_overflows_ull(ulonglong arg1, ulonglong arg2) return ULONGLONG_MAX - arg1 < arg2; } -void Item_func::set_arguments(List<Item> &list) + +void Item_args::set_arguments(List<Item> &list) { - allowed_arg_cols= 1; - arg_count=list.elements; - args= tmp_arg; // If 2 arguments - if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) + arg_count= list.elements; + if (arg_count <= 2) { - List_iterator_fast<Item> li(list); - Item *item; - Item **save_args= args; - - while ((item=li++)) - { - *(save_args++)= item; - with_sum_func|=item->with_sum_func; - with_field|= item->with_field; - } + args= tmp_arg; } - list.empty(); // Fields are used + else if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count))) + { + arg_count= 0; + return; + } + uint i= 0; + List_iterator_fast<Item> li(list); + Item *item; + while ((item= li++)) + args[i++]= item; } -Item_func::Item_func(List<Item> &list) - :allowed_arg_cols(1) + +Item_args::Item_args(THD *thd, const Item_args *other) + :arg_count(other->arg_count) { - set_arguments(list); + if (arg_count <= 2) + { + args= tmp_arg; + } + else if (!(args= (Item**) thd->alloc(sizeof(Item*) * arg_count))) + { + arg_count= 0; + return; + } + memcpy(args, other->args, sizeof(Item*) * arg_count); } -Item_func::Item_func(THD *thd, Item_func *item) - :Item_result_field(thd, item), - allowed_arg_cols(item->allowed_arg_cols), - arg_count(item->arg_count), - used_tables_cache(item->used_tables_cache), - not_null_tables_cache(item->not_null_tables_cache), - const_item_cache(item->const_item_cache) + +void Item_func::sync_with_sum_func_and_with_field(List<Item> &list) { - if (arg_count) + List_iterator_fast<Item> li(list); + Item *item; + while ((item= li++)) { - if (arg_count <=2) - args= tmp_arg; - else - { - if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count))) - return; - } - memcpy((char*) args, (char*) item->args, sizeof(Item*)*arg_count); + with_sum_func|= item->with_sum_func; + with_field|= item->with_field; } } diff --git a/sql/item_func.h b/sql/item_func.h index 84454ad2290..653c08e58c8 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -30,10 +30,11 @@ extern "C" /* Bug in BSDI include file */ } #endif -class Item_func :public Item_result_field + +class Item_func :public Item_func_or_sum { + void sync_with_sum_func_and_with_field(List<Item> &list); protected: - Item **args, *tmp_arg[2]; /* Allowed numbers of columns in result (usually 1, which means scalar value) 0 means get this number from first argument @@ -41,7 +42,6 @@ protected: uint allowed_arg_cols; String *val_str_from_val_str_ascii(String *str, String *str2); public: - uint arg_count; /* In some cases used_tables_cache is not what used_tables() return so the method should be used where one need used tables bit map @@ -72,69 +72,59 @@ public: enum Type type() const { return FUNC_ITEM; } virtual enum Functype functype() const { return UNKNOWN_FUNC; } Item_func(void): - allowed_arg_cols(1), arg_count(0) + Item_func_or_sum(), allowed_arg_cols(1) { with_sum_func= 0; with_field= 0; } Item_func(Item *a): - allowed_arg_cols(1), arg_count(1) + Item_func_or_sum(a), allowed_arg_cols(1) { - args= tmp_arg; - args[0]= a; with_sum_func= a->with_sum_func; with_field= a->with_field; } Item_func(Item *a,Item *b): - allowed_arg_cols(1), arg_count(2) + Item_func_or_sum(a, b), allowed_arg_cols(1) { - args= tmp_arg; - args[0]= a; args[1]= b; with_sum_func= a->with_sum_func || b->with_sum_func; with_field= a->with_field || b->with_field; } Item_func(Item *a,Item *b,Item *c): - allowed_arg_cols(1) + Item_func_or_sum(a, b, c), allowed_arg_cols(1) { - arg_count= 0; - if ((args= (Item**) sql_alloc(sizeof(Item*)*3))) - { - arg_count= 3; - args[0]= a; args[1]= b; args[2]= c; - with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func; - with_field= a->with_field || b->with_field || c->with_field; - } + with_sum_func= a->with_sum_func || b->with_sum_func || c->with_sum_func; + with_field= a->with_field || b->with_field || c->with_field; } Item_func(Item *a,Item *b,Item *c,Item *d): - allowed_arg_cols(1) + Item_func_or_sum(a, b, c, d), allowed_arg_cols(1) { - arg_count= 0; - if ((args= (Item**) sql_alloc(sizeof(Item*)*4))) - { - arg_count= 4; - args[0]= a; args[1]= b; args[2]= c; args[3]= d; - with_sum_func= a->with_sum_func || b->with_sum_func || - c->with_sum_func || d->with_sum_func; - with_field= a->with_field || b->with_field || - c->with_field || d->with_field; - } + with_sum_func= a->with_sum_func || b->with_sum_func || + c->with_sum_func || d->with_sum_func; + with_field= a->with_field || b->with_field || + c->with_field || d->with_field; } Item_func(Item *a,Item *b,Item *c,Item *d,Item* e): - allowed_arg_cols(1) + Item_func_or_sum(a, b, c, d, e), allowed_arg_cols(1) { - arg_count= 5; - if ((args= (Item**) sql_alloc(sizeof(Item*)*5))) - { - args[0]= a; args[1]= b; args[2]= c; args[3]= d; args[4]= e; - with_sum_func= a->with_sum_func || b->with_sum_func || - c->with_sum_func || d->with_sum_func || e->with_sum_func ; - with_field= a->with_field || b->with_field || - c->with_field || d->with_field || e->with_field; - } + with_sum_func= a->with_sum_func || b->with_sum_func || + c->with_sum_func || d->with_sum_func || e->with_sum_func; + with_field= a->with_field || b->with_field || + c->with_field || d->with_field || e->with_field; + } + Item_func(List<Item> &list) + :Item_func_or_sum(list), allowed_arg_cols(1) + { + set_arguments(list); } - Item_func(List<Item> &list); // Constructor used for Item_cond_and/or (see Item comment) - Item_func(THD *thd, Item_func *item); + Item_func(THD *thd, Item_func *item) + :Item_func_or_sum(thd, item), + allowed_arg_cols(item->allowed_arg_cols), + used_tables_cache(item->used_tables_cache), + not_null_tables_cache(item->not_null_tables_cache), + const_item_cache(item->const_item_cache) + { + } bool fix_fields(THD *, Item **ref); void fix_after_pullout(st_select_lex *new_parent, Item **ref); void quick_fix_field(); @@ -146,10 +136,13 @@ public: virtual bool have_rev_func() const { return 0; } virtual Item *key_item() const { return args[0]; } virtual bool const_item() const { return const_item_cache; } - inline Item **arguments() const { return args; } - void set_arguments(List<Item> &list); - inline uint argument_count() const { return arg_count; } - inline void remove_arguments() { arg_count=0; } + void set_arguments(List<Item> &list) + { + allowed_arg_cols= 1; + Item_args::set_arguments(list); + sync_with_sum_func_and_with_field(list); + list.empty(); // Fields are used + } void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields); virtual void print(String *str, enum_query_type query_type); void print_op(String *str, enum_query_type query_type); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 92b269d02f1..add2e0b6f9b 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -240,7 +240,6 @@ public: @return the SELECT_LEX structure associated with this Item */ st_select_lex* get_select_lex(); - const char *func_name() const { DBUG_ASSERT(0); return "subselect"; } virtual bool expr_cache_is_needed(THD *); virtual void get_cache_parameters(List<Item> ¶meters); virtual bool is_subquery_processor (uchar *opt_arg) { return 1; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 21f14ae8435..6b00316849e 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -400,20 +400,9 @@ bool Item_sum::collect_outer_ref_processor(uchar *param) } -Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), +Item_sum::Item_sum(List<Item> &list) :Item_func_or_sum(list), forced_const(FALSE) { - if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) - { - uint i=0; - List_iterator_fast<Item> li(list); - Item *item; - - while ((item=li++)) - { - args[i++]= item; - } - } if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count))) { args= NULL; @@ -429,27 +418,23 @@ Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements), */ Item_sum::Item_sum(THD *thd, Item_sum *item): - Item_result_field(thd, item), + Item_func_or_sum(thd, item), aggr_sel(item->aggr_sel), nest_level(item->nest_level), aggr_level(item->aggr_level), quick_group(item->quick_group), - arg_count(item->arg_count), orig_args(NULL), + orig_args(NULL), used_tables_cache(item->used_tables_cache), forced_const(item->forced_const) { if (arg_count <= 2) { - args=tmp_args; orig_args=tmp_orig_args; } else { - if (!(args= (Item**) thd->alloc(sizeof(Item*)*arg_count))) - return; if (!(orig_args= (Item**) thd->alloc(sizeof(Item*)*arg_count))) return; } - memcpy(args, item->args, sizeof(Item*)*arg_count); memcpy(orig_args, item->orig_args, sizeof(Item*)*arg_count); init_aggregator(); with_distinct= item->with_distinct; diff --git a/sql/item_sum.h b/sql/item_sum.h index 54319b027e7..15556051972 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -305,7 +305,7 @@ class st_select_lex; */ -class Item_sum :public Item_result_field +class Item_sum :public Item_func_or_sum { friend class Aggregator_distinct; friend class Aggregator_simple; @@ -362,8 +362,6 @@ public: List<Item_field> outer_fields; protected: - uint arg_count; - Item **args, *tmp_args[2]; /* Copy of the arguments list to hold the original set of arguments. Used in EXPLAIN EXTENDED instead of the current argument list because @@ -383,22 +381,20 @@ protected: public: void mark_as_sum_func(); - Item_sum() :quick_group(1), arg_count(0), forced_const(FALSE) + Item_sum() :Item_func_or_sum(), quick_group(1), forced_const(FALSE) { mark_as_sum_func(); init_aggregator(); } - Item_sum(Item *a) :quick_group(1), arg_count(1), args(tmp_args), + Item_sum(Item *a) :Item_func_or_sum(a), quick_group(1), orig_args(tmp_orig_args), forced_const(FALSE) { - args[0]=a; mark_as_sum_func(); init_aggregator(); } - Item_sum( Item *a, Item *b ) :quick_group(1), arg_count(2), args(tmp_args), + Item_sum(Item *a, Item *b) :Item_func_or_sum(a, b), quick_group(1), orig_args(tmp_orig_args), forced_const(FALSE) { - args[0]=a; args[1]=b; mark_as_sum_func(); init_aggregator(); } @@ -839,7 +835,6 @@ public: { return trace_unsupported_by_check_vcol_func_processor("avg_field"); } - const char *func_name() const { DBUG_ASSERT(0); return "avg_field"; } }; @@ -920,7 +915,6 @@ public: { return trace_unsupported_by_check_vcol_func_processor("var_field"); } - const char *func_name() const { DBUG_ASSERT(0); return "variance_field"; } }; @@ -996,7 +990,6 @@ public: my_decimal *val_decimal(my_decimal *); enum Item_result result_type () const { return REAL_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;} - const char *func_name() const { DBUG_ASSERT(0); return "std_field"; } }; /* |