Commit 99898c6f authored by Alexander Barkov's avatar Alexander Barkov

Minor reorganization in Item hierarchy, to remove duplicate code.

- Adding a new class Item_args, represending regular function or
  aggregate function arguments array.

- Adding a new class Item_func_or_sum,
  a parent class for Item_func and Item_sum

- Moving Item_result_field::name() to Item_func_or_sum(),
  as name() is not needed on Item_result_field level.
parent 3c4668c5
......@@ -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();
......
......@@ -3263,6 +3263,93 @@ class Item_result_field :public Item /* Item with result field */
}
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 @@ class Item_cache_wrapper :public Item_result_field
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(); }
......
......@@ -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;
......
......@@ -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 @@ class Arg_comparator: public Sql_alloc
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 @@ class Arg_comparator: public Sql_alloc
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()
{
......
......@@ -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;
}
}
......
......@@ -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 @@ class Item_func :public Item_result_field
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 @@ class Item_func :public Item_result_field
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 @@ class Item_func :public Item_result_field
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);
......
......@@ -240,7 +240,6 @@ class Item_subselect :public Item_result_field
@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; }
......
......@@ -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;
......
......@@ -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 @@ class Item_sum :public Item_result_field
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 @@ class Item_sum :public Item_result_field
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 @@ class Item_avg_field :public Item_result_field
{
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 @@ class Item_variance_field :public Item_result_field
{
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 @@ class Item_std_field :public Item_variance_field
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"; }
};
/*
......
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