summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item.h88
-rw-r--r--sql/item_cmpfunc.cc6
-rw-r--r--sql/item_cmpfunc.h13
-rw-r--r--sql/item_func.cc70
-rw-r--r--sql/item_func.h85
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/item_sum.cc21
-rw-r--r--sql/item_sum.h15
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> &parameters);
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"; }
};
/*