From 8b4f181c60acc163438b7f85365b4f429e49a3a8 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 16 Nov 2016 10:08:17 +0400 Subject: [PATCH] MDEV-10811 Change design from "Item is Type_handler" to "Item has Type_handler" --- sql/filesort.cc | 6 ++++-- sql/item.h | 44 +++++++++++++++++++------------------------- sql/item_func.h | 2 ++ sql/item_sum.cc | 3 ++- sql/item_sum.h | 4 ++++ sql/item_timefunc.h | 2 ++ sql/sql_type.cc | 2 +- sql/sql_type.h | 44 ++++++++------------------------------------ 8 files changed, 42 insertions(+), 65 deletions(-) diff --git a/sql/filesort.cc b/sql/filesort.cc index 2210dc569dfe1..c77304eba7c7a 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1183,7 +1183,8 @@ static void make_sortkey(register Sort_param *param, } else { // Item - sort_field->item->make_sort_key(to, sort_field->item, sort_field, param); + sort_field->item->type_handler()->make_sort_key(to, sort_field->item, + sort_field, param); if ((maybe_null= sort_field->item->maybe_null)) to++; } @@ -1983,7 +1984,8 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length, } else { - sortorder->item->sortlength(thd, sortorder->item, sortorder); + sortorder->item->type_handler()->sortlength(thd, sortorder->item, + sortorder); if (use_strnxfrm(sortorder->item->collation.collation)) { *multi_byte_charset= true; diff --git a/sql/item.h b/sql/item.h index 5b3c3a6a0d597..e0634e63c9bd7 100644 --- a/sql/item.h +++ b/sql/item.h @@ -642,8 +642,7 @@ class Type_std_attributes class Item: public Value_source, - public Type_std_attributes, - public Type_handler + public Type_std_attributes { void operator=(Item &); /** @@ -855,35 +854,20 @@ class Item: public Value_source, { return save_in_field(field, 1); } virtual bool send(Protocol *protocol, String *str); virtual bool eq(const Item *, bool binary_cmp) const; - const Type_handler *type_handler() const + virtual enum_field_types field_type() const= 0; + virtual const Type_handler *type_handler() const { - return get_handler_by_field_type(field_type()); - } - Field *make_num_distinct_aggregator_field(MEM_ROOT *mem_root, - const Item *item) const - { - return type_handler()->make_num_distinct_aggregator_field(mem_root, this); - } - Field *make_conversion_table_field(TABLE *table, - uint metadata, const Field *target) const - { - DBUG_ASSERT(0); // Should not be called in Item context - return NULL; + return Type_handler::get_handler_by_field_type(field_type()); } /* result_type() of an item specifies how the value should be returned */ - Item_result result_type() const { return type_handler()->result_type(); } - /* ... while cmp_type() specifies how it should be compared */ - Item_result cmp_type() const { return type_handler()->cmp_type(); } - void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, - Sort_param *param) const + virtual Item_result result_type() const { - type_handler()->make_sort_key(to, item, sort_field, param); + return type_handler()->result_type(); } - void sortlength(THD *thd, - const Type_std_attributes *item, - SORT_FIELD_ATTR *attr) const + /* ... while cmp_type() specifies how it should be compared */ + virtual Item_result cmp_type() const { - type_handler()->sortlength(thd, item, attr); + return type_handler()->cmp_type(); } virtual Item_result cast_to_int_type() const { return cmp_type(); } enum_field_types string_field_type() const @@ -2182,6 +2166,8 @@ class Item_splocal :public Item_sp_variable, inline uint get_var_idx() const; inline enum Type type() const; + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const @@ -2840,6 +2826,8 @@ class Item_param :public Item_basic_value, enum Type item_type; + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const @@ -4835,6 +4823,8 @@ class Item_copy :public Item, /** All of the subclasses should have the same type tag */ enum Type type() const { return COPY_STR_ITEM; } + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const @@ -5356,6 +5346,8 @@ class Item_cache: public Item_basic_constant, }; enum Type type() const { return CACHE_ITEM; } + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const @@ -5669,6 +5661,8 @@ class Item_type_holder: public Item, public: Item_type_holder(THD*, Item*); + const Type_handler *type_handler() const + { return Type_handler_hybrid_real_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_real_field_type::field_type(); } enum_field_types real_field_type() const diff --git a/sql/item_func.h b/sql/item_func.h index d4314f7bd6a15..d30ab750e339c 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -399,6 +399,8 @@ class Item_hybrid_func: public Item_func, Item_hybrid_func(THD *thd, List &list): Item_func(thd, list) { } Item_hybrid_func(THD *thd, Item_hybrid_func *item) :Item_func(thd, item), Type_handler_hybrid_field_type(item) { } + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 51a6c2bd3ebd1..3754bc1a954ea 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -867,7 +867,8 @@ bool Aggregator_distinct::setup(THD *thd) if (always_null) DBUG_RETURN(FALSE); - Field *field= arg->make_num_distinct_aggregator_field(thd->mem_root, arg); + Field *field= arg->type_handler()-> + make_num_distinct_aggregator_field(thd->mem_root, arg); if (!field || !(table= create_virtual_tmp_table(thd, field))) DBUG_RETURN(TRUE); diff --git a/sql/item_sum.h b/sql/item_sum.h index b9075db019664..76cc983ad9e03 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -755,6 +755,8 @@ class Item_sum_sum :public Item_sum_num, longlong val_int(); String *val_str(String*str); my_decimal *val_decimal(my_decimal *); + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const @@ -1012,6 +1014,8 @@ class Item_sum_hybrid :public Item_sum, public Type_handler_hybrid_field_type void reset_field(); String *val_str(String *); bool keep_field_type(void) const { return 1; } + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum Item_result result_type () const { return Type_handler_hybrid_field_type::result_type(); } enum Item_result cmp_type () const diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index d8f69e2098d01..dafcdf64b455f 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -565,6 +565,8 @@ class Item_temporal_hybrid_func: public Item_temporal_func, public: Item_temporal_hybrid_func(THD *thd, Item *a, Item *b): Item_temporal_func(thd, a, b) {} + const Type_handler *type_handler() const + { return Type_handler_hybrid_field_type::type_handler(); } enum_field_types field_type() const { return Type_handler_hybrid_field_type::field_type(); } enum Item_result result_type () const diff --git a/sql/sql_type.cc b/sql/sql_type.cc index d85664568a1fa..a80417f60b9b2 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -68,7 +68,7 @@ static Type_handler_set type_handler_set; all around the code. */ const Type_handler * -Type_handler::string_type_handler(uint max_octet_length) const +Type_handler::string_type_handler(uint max_octet_length) { if (max_octet_length >= 16777216) return &type_handler_long_blob; diff --git a/sql/sql_type.h b/sql/sql_type.h index 596c338720e6e..4b05a4663c428 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -33,12 +33,12 @@ struct SORT_FIELD_ATTR; class Type_handler { protected: - const Type_handler *string_type_handler(uint max_octet_length) const; void make_sort_key_longlong(uchar *to, bool maybe_null, bool null_value, bool unsigned_flag, longlong value) const; public: + static const Type_handler *string_type_handler(uint max_octet_length); static const Type_handler *get_handler_by_field_type(enum_field_types type); static const Type_handler *get_handler_by_real_type(enum_field_types type); virtual enum_field_types field_type() const= 0; @@ -499,7 +499,7 @@ class Type_handler_set: public Type_handler_string_result Makes sure that field_type(), cmp_type() and result_type() are always in sync to each other for hybrid functions. */ -class Type_handler_hybrid_field_type: public Type_handler +class Type_handler_hybrid_field_type { const Type_handler *m_type_handler; const Type_handler *get_handler_by_result_type(Item_result type) const; @@ -509,11 +509,12 @@ class Type_handler_hybrid_field_type: public Type_handler :m_type_handler(handler) { } Type_handler_hybrid_field_type(enum_field_types type) - :m_type_handler(get_handler_by_field_type(type)) + :m_type_handler(Type_handler::get_handler_by_field_type(type)) { } Type_handler_hybrid_field_type(const Type_handler_hybrid_field_type *other) :m_type_handler(other->m_type_handler) { } + const Type_handler *type_handler() const { return m_type_handler; } enum_field_types field_type() const { return m_type_handler->field_type(); } enum_field_types real_field_type() const { @@ -540,42 +541,12 @@ class Type_handler_hybrid_field_type: public Type_handler } const Type_handler *set_handler_by_field_type(enum_field_types type) { - return (m_type_handler= get_handler_by_field_type(type)); + return (m_type_handler= Type_handler::get_handler_by_field_type(type)); } const Type_handler *set_handler_by_real_type(enum_field_types type) { - return (m_type_handler= get_handler_by_real_type(type)); + return (m_type_handler= Type_handler::get_handler_by_real_type(type)); } - const Type_handler * - type_handler_adjusted_to_max_octet_length(uint max_octet_length, - CHARSET_INFO *cs) const - { - return - m_type_handler->type_handler_adjusted_to_max_octet_length(max_octet_length, - cs); - } - Field *make_num_distinct_aggregator_field(MEM_ROOT *mem_root, - const Item *item) const - { - return m_type_handler->make_num_distinct_aggregator_field(mem_root, item); - } - Field *make_conversion_table_field(TABLE *table, uint metadata, - const Field *target) const - { - return m_type_handler->make_conversion_table_field(table, metadata, target); - } - void make_sort_key(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, - Sort_param *param) const - { - m_type_handler->make_sort_key(to, item, sort_field, param); - } - void sortlength(THD *thd, - const Type_std_attributes *item, - SORT_FIELD_ATTR *attr) const - { - m_type_handler->sortlength(thd, item, attr); - } - }; @@ -587,7 +558,8 @@ class Type_handler_hybrid_real_field_type: { public: Type_handler_hybrid_real_field_type(enum_field_types type) - :Type_handler_hybrid_field_type(get_handler_by_real_type(type)) + :Type_handler_hybrid_field_type(Type_handler:: + get_handler_by_real_type(type)) { } };