← Back to team overview

maria-developers team mailing list archive

Please review MDEV-10811 Change design from "Item is Type_handler" to "Item has Type_handler"

 

Hello Alexey,


Please review a patch for 10.3 for
MDEV-10811 Change design from "Item is Type_handler" to "Item has Type_handler


Thanks.


commit bd9af31224d74fc40a4f72608216a09c6f4ef133
Author: Alexander Barkov <bar@xxxxxxxxxxx>
Date:   Thu Sep 15 12:03:45 2016 +0400

    MDEV-10811 Change design from "Item is Type_handler" to "Item has Type_handler

diff --git a/sql/filesort.cc b/sql/filesort.cc
index ae51fb9..3c0a8ff 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1187,7 +1187,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++;
     }
@@ -1987,7 +1988,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 5bb16d6..9e57482 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -588,8 +588,7 @@ class Type_std_attributes
 
 
 class Item: public Value_source,
-            public Type_std_attributes,
-            public Type_handler
+            public Type_std_attributes
 {
   Item(const Item &);			/* Prevent use of these */
   void operator=(Item &);
@@ -791,35 +790,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
@@ -2140,6 +2124,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
@@ -2770,6 +2756,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
@@ -4697,6 +4685,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
@@ -5163,6 +5153,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
@@ -5449,6 +5441,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 92bc798..7436f25 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<Item> &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 cc7a762..85d690c 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -857,7 +857,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 4cb5529..68db29b 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -753,6 +753,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
@@ -985,6 +987,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 84f610b..21a3c39 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -526,6 +526,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 d856645..a80417f 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 596c338..4b05a46 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))
   { }
 };