Commit ecb009b2 authored by Alexander Barkov's avatar Alexander Barkov

Adding Type_std_attributes to reduce some duplicate code.

TODO: move some methods from Item to Type_std_attributes.
parent 04fb09d7
...@@ -412,13 +412,11 @@ int Item::save_str_value_in_field(Field *field, String *result) ...@@ -412,13 +412,11 @@ int Item::save_str_value_in_field(Field *field, String *result)
Item::Item(): Item::Item():
is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0), is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0),
fixed(0), is_autogenerated_name(TRUE), fixed(0), is_autogenerated_name(TRUE)
collation(&my_charset_bin, DERIVATION_COERCIBLE)
{ {
marker= 0; marker= 0;
maybe_null=null_value=with_sum_func=with_field=unsigned_flag=0; maybe_null=null_value=with_sum_func=with_field=0;
in_rollup= 0; in_rollup= 0;
decimals= 0; max_length= 0;
with_subselect= 0; with_subselect= 0;
cmp_context= IMPOSSIBLE_RESULT; cmp_context= IMPOSSIBLE_RESULT;
/* Initially this item is not attached to any JOIN_TAB. */ /* Initially this item is not attached to any JOIN_TAB. */
...@@ -451,26 +449,23 @@ Item::Item(): ...@@ -451,26 +449,23 @@ Item::Item():
tables. tables.
*/ */
Item::Item(THD *thd, Item *item): Item::Item(THD *thd, Item *item):
Type_std_attributes(item),
join_tab_idx(item->join_tab_idx), join_tab_idx(item->join_tab_idx),
is_expensive_cache(-1), is_expensive_cache(-1),
rsize(0), rsize(0),
str_value(item->str_value), str_value(item->str_value),
name(item->name), name(item->name),
orig_name(item->orig_name), orig_name(item->orig_name),
max_length(item->max_length),
name_length(item->name_length), name_length(item->name_length),
decimals(item->decimals),
marker(item->marker), marker(item->marker),
maybe_null(item->maybe_null), maybe_null(item->maybe_null),
in_rollup(item->in_rollup), in_rollup(item->in_rollup),
null_value(item->null_value), null_value(item->null_value),
unsigned_flag(item->unsigned_flag),
with_sum_func(item->with_sum_func), with_sum_func(item->with_sum_func),
with_field(item->with_field), with_field(item->with_field),
fixed(item->fixed), fixed(item->fixed),
is_autogenerated_name(item->is_autogenerated_name), is_autogenerated_name(item->is_autogenerated_name),
with_subselect(item->has_subquery()), with_subselect(item->has_subquery()),
collation(item->collation),
cmp_context(item->cmp_context) cmp_context(item->cmp_context)
{ {
next= thd->free_list; // Put in free list next= thd->free_list; // Put in free list
...@@ -3713,17 +3708,14 @@ void Item_param::print(String *str, enum_query_type query_type) ...@@ -3713,17 +3708,14 @@ void Item_param::print(String *str, enum_query_type query_type)
void void
Item_param::set_param_type_and_swap_value(Item_param *src) Item_param::set_param_type_and_swap_value(Item_param *src)
{ {
unsigned_flag= src->unsigned_flag; Type_std_attributes::set(src);
param_type= src->param_type; param_type= src->param_type;
set_param_func= src->set_param_func; set_param_func= src->set_param_func;
item_type= src->item_type; item_type= src->item_type;
item_result_type= src->item_result_type; item_result_type= src->item_result_type;
collation.set(src->collation);
maybe_null= src->maybe_null; maybe_null= src->maybe_null;
null_value= src->null_value; null_value= src->null_value;
max_length= src->max_length;
decimals= src->decimals;
state= src->state; state= src->state;
value= src->value; value= src->value;
...@@ -6965,17 +6957,14 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) ...@@ -6965,17 +6957,14 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
void Item_ref::set_properties() void Item_ref::set_properties()
{ {
max_length= (*ref)->max_length; Type_std_attributes::set(*ref);
maybe_null= (*ref)->maybe_null; maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals;
collation.set((*ref)->collation);
/* /*
We have to remember if we refer to a sum function, to ensure that We have to remember if we refer to a sum function, to ensure that
split_sum_func() doesn't try to change the reference. split_sum_func() doesn't try to change the reference.
*/ */
with_sum_func= (*ref)->with_sum_func; with_sum_func= (*ref)->with_sum_func;
with_field= (*ref)->with_field; with_field= (*ref)->with_field;
unsigned_flag= (*ref)->unsigned_flag;
fixed= 1; fixed= 1;
if (alias_name_used) if (alias_name_used)
return; return;
...@@ -7415,13 +7404,10 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg) ...@@ -7415,13 +7404,10 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
:orig_item(item_arg), expr_cache(NULL), expr_value(NULL) :orig_item(item_arg), expr_cache(NULL), expr_value(NULL)
{ {
DBUG_ASSERT(orig_item->fixed); DBUG_ASSERT(orig_item->fixed);
max_length= orig_item->max_length; Type_std_attributes::set(orig_item);
maybe_null= orig_item->maybe_null; maybe_null= orig_item->maybe_null;
decimals= orig_item->decimals;
collation.set(orig_item->collation);
with_sum_func= orig_item->with_sum_func; with_sum_func= orig_item->with_sum_func;
with_field= orig_item->with_field; with_field= orig_item->with_field;
unsigned_flag= orig_item->unsigned_flag;
name= item_arg->name; name= item_arg->name;
name_length= item_arg->name_length; name_length= item_arg->name_length;
with_subselect= orig_item->with_subselect; with_subselect= orig_item->with_subselect;
......
...@@ -118,7 +118,7 @@ class DTCollation { ...@@ -118,7 +118,7 @@ class DTCollation {
derivation= derivation_arg; derivation= derivation_arg;
set_repertoire_from_charset(collation_arg); set_repertoire_from_charset(collation_arg);
} }
void set(DTCollation &dt) void set(const DTCollation &dt)
{ {
collation= dt.collation; collation= dt.collation;
derivation= dt.derivation; derivation= dt.derivation;
...@@ -546,7 +546,48 @@ class String_copier_for_item: public String_copier ...@@ -546,7 +546,48 @@ class String_copier_for_item: public String_copier
}; };
class Item { /**
A class to store type attributes for the standard data types.
Does not include attributes for the extended data types
such as ENUM, SET, GEOMETRY.
*/
class Type_std_attributes
{
public:
DTCollation collation;
uint decimals;
/*
The maximum value length in characters multiplied by collation->mbmaxlen.
Almost always it's the maximum value length in bytes.
*/
uint32 max_length;
bool unsigned_flag;
Type_std_attributes()
:collation(&my_charset_bin, DERIVATION_COERCIBLE),
decimals(0), max_length(0), unsigned_flag(false)
{ }
Type_std_attributes(const Type_std_attributes *other)
:collation(other->collation),
decimals(other->decimals),
max_length(other->max_length),
unsigned_flag(other->unsigned_flag)
{ }
void set(const Type_std_attributes *other)
{
*this= *other;
}
void set(const Field *field)
{
decimals= field->decimals();
max_length= field->field_length;
collation.set(field->charset());
unsigned_flag= MY_TEST(field->flags & UNSIGNED_FLAG);
}
};
class Item: public Type_std_attributes
{
Item(const Item &); /* Prevent use of these */ Item(const Item &); /* Prevent use of these */
void operator=(Item &); void operator=(Item &);
/** /**
...@@ -614,24 +655,17 @@ class Item { ...@@ -614,24 +655,17 @@ class Item {
@see Query_arena::free_list @see Query_arena::free_list
*/ */
Item *next; Item *next;
/*
The maximum value length in characters multiplied by collation->mbmaxlen.
Almost always it's the maximum value length in bytes.
*/
uint32 max_length;
/* /*
TODO: convert name and name_length fields into LEX_STRING to keep them in TODO: convert name and name_length fields into LEX_STRING to keep them in
sync (see bug #11829681/60295 etc). Then also remove some strlen(name) sync (see bug #11829681/60295 etc). Then also remove some strlen(name)
calls. calls.
*/ */
uint name_length; /* Length of name */ uint name_length; /* Length of name */
uint decimals;
int8 marker; int8 marker;
bool maybe_null; /* If item may be null */ bool maybe_null; /* If item may be null */
bool in_rollup; /* If used in GROUP BY list bool in_rollup; /* If used in GROUP BY list
of a query with ROLLUP */ of a query with ROLLUP */
bool null_value; /* if item is null */ bool null_value; /* if item is null */
bool unsigned_flag;
bool with_sum_func; /* True if item contains a sum func */ bool with_sum_func; /* True if item contains a sum func */
/** /**
True if any item except Item_sum contains a field. Set during parsing. True if any item except Item_sum contains a field. Set during parsing.
...@@ -643,7 +677,6 @@ class Item { ...@@ -643,7 +677,6 @@ class Item {
bool with_subselect; /* If this item is a subselect or some bool with_subselect; /* If this item is a subselect or some
of its arguments is or contains a of its arguments is or contains a
subselect */ subselect */
DTCollation collation;
Item_result cmp_context; /* Comparison context */ Item_result cmp_context; /* Comparison context */
// alloc & destruct is done as start of select using sql_alloc // alloc & destruct is done as start of select using sql_alloc
Item(); Item();
...@@ -4149,14 +4182,11 @@ class Item_copy :public Item ...@@ -4149,14 +4182,11 @@ class Item_copy :public Item
{ {
item= i; item= i;
null_value=maybe_null=item->maybe_null; null_value=maybe_null=item->maybe_null;
decimals=item->decimals; Type_std_attributes::set(item);
max_length=item->max_length;
name=item->name; name=item->name;
cached_field_type= item->field_type(); cached_field_type= item->field_type();
cached_result_type= item->result_type(); cached_result_type= item->result_type();
unsigned_flag= item->unsigned_flag;
fixed= item->fixed; fixed= item->fixed;
collation.set(item->collation);
} }
public: public:
...@@ -4608,10 +4638,7 @@ class Item_cache: public Item_basic_constant ...@@ -4608,10 +4638,7 @@ class Item_cache: public Item_basic_constant
virtual bool setup(Item *item) virtual bool setup(Item *item)
{ {
example= item; example= item;
max_length= item->max_length; Type_std_attributes::set(item);
decimals= item->decimals;
collation.set(item->collation);
unsigned_flag= item->unsigned_flag;
if (item->type() == FIELD_ITEM) if (item->type() == FIELD_ITEM)
cached_field= ((Item_field *)item)->field; cached_field= ((Item_field *)item)->field;
return 0; return 0;
......
...@@ -2654,13 +2654,10 @@ void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref) ...@@ -2654,13 +2654,10 @@ void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
void Item_func_if::cache_type_info(Item *source) void Item_func_if::cache_type_info(Item *source)
{ {
collation.set(source->collation); Type_std_attributes::set(source);
cached_field_type= source->field_type(); cached_field_type= source->field_type();
cached_result_type= source->result_type(); cached_result_type= source->result_type();
decimals= source->decimals;
max_length= source->max_length;
maybe_null= source->maybe_null; maybe_null= source->maybe_null;
unsigned_flag= source->unsigned_flag;
} }
......
...@@ -6645,11 +6645,8 @@ void Item_func_sp::fix_length_and_dec() ...@@ -6645,11 +6645,8 @@ void Item_func_sp::fix_length_and_dec()
DBUG_ENTER("Item_func_sp::fix_length_and_dec"); DBUG_ENTER("Item_func_sp::fix_length_and_dec");
DBUG_ASSERT(sp_result_field); DBUG_ASSERT(sp_result_field);
decimals= sp_result_field->decimals(); Type_std_attributes::set(sp_result_field);
max_length= sp_result_field->field_length;
collation.set(sp_result_field->charset());
maybe_null= 1; maybe_null= 1;
unsigned_flag= MY_TEST(sp_result_field->flags & UNSIGNED_FLAG);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -6999,9 +6996,6 @@ my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value) ...@@ -6999,9 +6996,6 @@ my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value)
void Item_func_last_value::fix_length_and_dec() void Item_func_last_value::fix_length_and_dec()
{ {
last_value= args[arg_count -1]; last_value= args[arg_count -1];
decimals= last_value->decimals; Type_std_attributes::set(last_value);
max_length= last_value->max_length;
collation.set(last_value->collation.collation);
maybe_null= last_value->maybe_null; maybe_null= last_value->maybe_null;
unsigned_flag= last_value->unsigned_flag;
} }
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