diff --git a/sql/item.cc b/sql/item.cc index 5433f1e8ff2..6e856856c16 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -412,13 +412,11 @@ int Item::save_str_value_in_field(Field *field, String *result) Item::Item(): is_expensive_cache(-1), rsize(0), name(0), orig_name(0), name_length(0), - fixed(0), is_autogenerated_name(TRUE), - collation(&my_charset_bin, DERIVATION_COERCIBLE) + fixed(0), is_autogenerated_name(TRUE) { 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; - decimals= 0; max_length= 0; with_subselect= 0; cmp_context= IMPOSSIBLE_RESULT; /* Initially this item is not attached to any JOIN_TAB. */ @@ -451,26 +449,23 @@ Item::Item(): tables. */ Item::Item(THD *thd, Item *item): + Type_std_attributes(item), join_tab_idx(item->join_tab_idx), is_expensive_cache(-1), rsize(0), str_value(item->str_value), name(item->name), orig_name(item->orig_name), - max_length(item->max_length), name_length(item->name_length), - decimals(item->decimals), marker(item->marker), maybe_null(item->maybe_null), in_rollup(item->in_rollup), null_value(item->null_value), - unsigned_flag(item->unsigned_flag), with_sum_func(item->with_sum_func), with_field(item->with_field), fixed(item->fixed), is_autogenerated_name(item->is_autogenerated_name), with_subselect(item->has_subquery()), - collation(item->collation), cmp_context(item->cmp_context) { next= thd->free_list; // Put in free list @@ -3713,17 +3708,14 @@ void Item_param::print(String *str, enum_query_type query_type) void 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; set_param_func= src->set_param_func; item_type= src->item_type; item_result_type= src->item_result_type; - collation.set(src->collation); maybe_null= src->maybe_null; null_value= src->null_value; - max_length= src->max_length; - decimals= src->decimals; state= src->state; value= src->value; @@ -6965,17 +6957,14 @@ error: void Item_ref::set_properties() { - max_length= (*ref)->max_length; + Type_std_attributes::set(*ref); 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 split_sum_func() doesn't try to change the reference. */ with_sum_func= (*ref)->with_sum_func; with_field= (*ref)->with_field; - unsigned_flag= (*ref)->unsigned_flag; fixed= 1; if (alias_name_used) return; @@ -7415,13 +7404,10 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg) :orig_item(item_arg), expr_cache(NULL), expr_value(NULL) { DBUG_ASSERT(orig_item->fixed); - max_length= orig_item->max_length; + Type_std_attributes::set(orig_item); maybe_null= orig_item->maybe_null; - decimals= orig_item->decimals; - collation.set(orig_item->collation); with_sum_func= orig_item->with_sum_func; with_field= orig_item->with_field; - unsigned_flag= orig_item->unsigned_flag; name= item_arg->name; name_length= item_arg->name_length; with_subselect= orig_item->with_subselect; diff --git a/sql/item.h b/sql/item.h index 314882662ea..f76d5aa2a4e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -118,7 +118,7 @@ public: derivation= derivation_arg; set_repertoire_from_charset(collation_arg); } - void set(DTCollation &dt) + void set(const DTCollation &dt) { collation= dt.collation; derivation= dt.derivation; @@ -546,7 +546,48 @@ public: }; -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 */ void operator=(Item &); /** @@ -614,24 +655,17 @@ public: @see Query_arena::free_list */ 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 sync (see bug #11829681/60295 etc). Then also remove some strlen(name) calls. */ uint name_length; /* Length of name */ - uint decimals; int8 marker; bool maybe_null; /* If item may be null */ bool in_rollup; /* If used in GROUP BY list of a query with ROLLUP */ bool null_value; /* if item is null */ - bool unsigned_flag; bool with_sum_func; /* True if item contains a sum func */ /** True if any item except Item_sum contains a field. Set during parsing. @@ -643,7 +677,6 @@ public: bool with_subselect; /* If this item is a subselect or some of its arguments is or contains a subselect */ - DTCollation collation; Item_result cmp_context; /* Comparison context */ // alloc & destruct is done as start of select using sql_alloc Item(); @@ -4149,14 +4182,11 @@ protected: { item= i; null_value=maybe_null=item->maybe_null; - decimals=item->decimals; - max_length=item->max_length; + Type_std_attributes::set(item); name=item->name; cached_field_type= item->field_type(); cached_result_type= item->result_type(); - unsigned_flag= item->unsigned_flag; fixed= item->fixed; - collation.set(item->collation); } public: @@ -4608,10 +4638,7 @@ public: virtual bool setup(Item *item) { example= item; - max_length= item->max_length; - decimals= item->decimals; - collation.set(item->collation); - unsigned_flag= item->unsigned_flag; + Type_std_attributes::set(item); if (item->type() == FIELD_ITEM) cached_field= ((Item_field *)item)->field; return 0; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index eec99d906b2..53c96420641 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -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) { - collation.set(source->collation); + Type_std_attributes::set(source); cached_field_type= source->field_type(); cached_result_type= source->result_type(); - decimals= source->decimals; - max_length= source->max_length; maybe_null= source->maybe_null; - unsigned_flag= source->unsigned_flag; } diff --git a/sql/item_func.cc b/sql/item_func.cc index ffbc06a1bce..4aec0f6203a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6645,11 +6645,8 @@ void Item_func_sp::fix_length_and_dec() DBUG_ENTER("Item_func_sp::fix_length_and_dec"); DBUG_ASSERT(sp_result_field); - decimals= sp_result_field->decimals(); - max_length= sp_result_field->field_length; - collation.set(sp_result_field->charset()); + Type_std_attributes::set(sp_result_field); maybe_null= 1; - unsigned_flag= MY_TEST(sp_result_field->flags & UNSIGNED_FLAG); DBUG_VOID_RETURN; } @@ -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() { last_value= args[arg_count -1]; - decimals= last_value->decimals; - max_length= last_value->max_length; - collation.set(last_value->collation.collation); + Type_std_attributes::set(last_value); maybe_null= last_value->maybe_null; - unsigned_flag= last_value->unsigned_flag; }