List:Commits« Previous MessageNext Message »
From:Martin Hansson Date:December 14 2010 12:50pm
Subject:bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260) Bug#58918
View as plain text  
#At file:///data0/martin/bzrroot/refactoring-Field_clone/n-mr-o-t/ based on revid:tor.didriksen@stripped

 3260 Martin Hansson	2010-12-14
      Bug#58918: Add a clone member function to the Field class for better
      duplication
      
      The patch removes all copying of Field objects using memcpy() and replaces it
      with virtual clone() and clone(MEM_ROOT*) member functions that rely on the
      copy constructor. An operator new (MEM_ROOT*) is also implemented. The sole
      purpose of the Field::size_of() member function was to support the memcpy and
      it is now removed.
     @ sql/field.cc
        Removal of memcpy() based duplication.
     @ sql/field.h
        New implementation of clone() member functions.
        Removal of size_of() member functions
     @ sql/item.cc
        Removal of memcpy() based duplication.

    modified:
      sql/field.cc
      sql/field.h
      sql/item.cc
=== modified file 'sql/field.cc'
--- a/sql/field.cc	2010-11-17 16:04:35 +0000
+++ b/sql/field.cc	2010-12-14 12:50:35 +0000
@@ -1812,8 +1812,8 @@ bool Field::optimize_range(uint idx, uin
 Field *Field::new_field(MEM_ROOT *root, TABLE *new_table,
                         bool keep_type __attribute__((unused)))
 {
-  Field *tmp;
-  if (!(tmp= (Field*) memdup_root(root,(char*) this,size_of())))
+  Field *tmp= clone(root);
+  if (tmp == NULL)
     return 0;
 
   if (tmp->table->maybe_null)
@@ -1849,8 +1849,8 @@ Field *Field::new_key_field(MEM_ROOT *ro
 
 Field *Field::clone(MEM_ROOT *root, TABLE *new_table)
 {
-  Field *tmp;
-  if ((tmp= (Field*) memdup_root(root,(char*) this,size_of())))
+  Field *tmp= clone(root);
+  if (tmp != NULL)
   {
     tmp->init(new_table);
     tmp->move_field_offset((my_ptrdiff_t) (new_table->record[0] -

=== modified file 'sql/field.h'
--- a/sql/field.h	2010-11-19 19:27:31 +0000
+++ b/sql/field.h	2010-12-14 12:50:35 +0000
@@ -16,11 +16,6 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 
-/*
-  Because of the function new_field() all field classes that have static
-  variables must declare the size_of() member function.
-*/
-
 #ifdef USE_PRAGMA_INTERFACE
 #pragma interface			/* gcc class implementation */
 #endif
@@ -84,8 +79,12 @@ class Field
   Field(const Item &);				/* Prevent use of these */
   void operator=(Field &);
 public:
+  /* To do: inherit Sql_alloc and get these for free */
   static void *operator new(size_t size) throw ()
   { return sql_alloc(size); }
+  static void *operator new(size_t size, MEM_ROOT *mem_root) throw () {
+    return alloc_root(mem_root, size);
+  }
   static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); }
 
   uchar		*ptr;			// Position to field in record
@@ -267,7 +266,6 @@ public:
     in str and restore it with set() if needed
   */
   virtual void sql_type(String &str) const =0;
-  virtual uint size_of() const =0;		// For new field
   inline bool is_null(my_ptrdiff_t row_offset= 0)
   { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; }
   inline bool is_real_null(my_ptrdiff_t row_offset= 0)
@@ -339,6 +337,29 @@ public:
                                uchar *new_ptr, uchar *new_null_ptr,
                                uint new_null_bit);
   Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
+
+  /**
+     Makes a shallow copy of the Field object.
+     
+     @note This method must be overridden in all concrete subclasses. Several
+     of the Field subclasses are concrete even though they are not leaf
+     classes, so the compiler will not always catch this.
+
+     @retval NULL If memory allocation failed.
+  */ 
+  virtual Field *clone() const =0;
+
+  /**
+     Makes a shallow copy of the Field object.
+     
+     @note This method must be overridden in all concrete subclasses. Several
+     of the Field subclasses are concrete even though they are not leaf
+     classes, so the compiler will not always catch this.
+     
+     @param mem_root MEM_ROOT to use for memory allocation.
+     @retval NULL If memory allocation failed.
+   */
+  virtual Field *clone(MEM_ROOT *mem_root) const =0;
   inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
   {
     ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
@@ -735,7 +756,6 @@ public:
   friend class Create_field;
   void make_field(Send_field *);
   uint decimals() const { return (uint) dec; }
-  uint size_of() const { return sizeof(*this); }
   bool eq_def(Field *field);
   int store_decimal(const my_decimal *);
   my_decimal *val_decimal(my_decimal *);
@@ -780,7 +800,6 @@ public:
   int  store(longlong nr, bool unsigned_val)=0;
   int  store_decimal(const my_decimal *);
   int  store(const char *to,uint length,CHARSET_INFO *cs)=0;
-  uint size_of() const { return sizeof(*this); }
   uint repertoire(void) const
   {
     return my_charset_repertoire(field_charset);
@@ -835,7 +854,6 @@ public:
   my_decimal *val_decimal(my_decimal *);
   int truncate(double *nr, double max_length);
   uint32 max_display_length() { return field_length; }
-  uint size_of() const { return sizeof(*this); }
   virtual const uchar *unpack(uchar* to, const uchar *from,
                               uint param_data, bool low_byte_first);
   virtual uchar *pack(uchar* to, const uchar *from,
@@ -868,6 +886,14 @@ public:
   void overflow(bool negative);
   bool zero_pack() const { return 0; }
   void sql_type(String &str) const;
+  Field_decimal *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DECIMAL);
+    return new (mem_root) Field_decimal(*this);
+  }
+  Field_decimal *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DECIMAL);
+    return new Field_decimal(*this);
+  }
   virtual const uchar *unpack(uchar* to, const uchar *from,
                               uint param_data, bool low_byte_first)
   {
@@ -922,13 +948,20 @@ public:
   bool zero_pack() const { return 0; }
   void sql_type(String &str) const;
   uint32 max_display_length() { return field_length; }
-  uint size_of() const { return sizeof(*this); } 
   uint32 pack_length() const { return (uint32) bin_size; }
   uint pack_length_from_metadata(uint field_metadata);
   uint row_pack_length() { return pack_length(); }
   bool compatible_field_size(uint field_metadata, Relay_log_info *rli,
                              uint16 mflags, int *order_var);
   uint is_equal(Create_field *new_field);
+  Field_new_decimal *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_NEWDECIMAL);
+    return new (mem_root) Field_new_decimal(*this);
+  }
+  Field_new_decimal *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_NEWDECIMAL);
+    return new Field_new_decimal(*this);
+  }
   virtual const uchar *unpack(uchar* to, const uchar *from,
                               uint param_data, bool low_byte_first);
   static Field *create_from_item (Item *);
@@ -962,7 +995,14 @@ public:
   uint32 pack_length() const { return 1; }
   void sql_type(String &str) const;
   uint32 max_display_length() { return 4; }
-
+  Field_tiny *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_TINY);
+    return new (mem_root) Field_tiny(*this);
+  }
+  Field_tiny *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_TINY);
+    return new Field_tiny(*this);
+  }
   virtual uchar *pack(uchar* to, const uchar *from,
                       uint max_length, bool low_byte_first)
   {
@@ -1011,7 +1051,14 @@ public:
   uint32 pack_length() const { return 2; }
   void sql_type(String &str) const;
   uint32 max_display_length() { return 6; }
-
+  Field_short *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_SHORT);
+    return new (mem_root) Field_short(*this);
+  }
+  Field_short *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_SHORT);
+    return new Field_short(*this);
+  }
   virtual uchar *pack(uchar* to, const uchar *from,
                       uint max_length, bool low_byte_first)
   {
@@ -1052,7 +1099,14 @@ public:
   uint32 pack_length() const { return 3; }
   void sql_type(String &str) const;
   uint32 max_display_length() { return 8; }
-
+  Field_medium *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_INT24);
+    return new (mem_root) Field_medium(*this);
+  }
+  Field_medium *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_INT24);
+    return new Field_medium(*this);
+  }
   virtual uchar *pack(uchar* to, const uchar *from,
                       uint max_length, bool low_byte_first)
   {
@@ -1099,6 +1153,14 @@ public:
   uint32 pack_length() const { return 4; }
   void sql_type(String &str) const;
   uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; }
+  Field_long *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_LONG);
+    return new (mem_root) Field_long(*this);
+  }
+  Field_long *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_LONG);
+    return new Field_long(*this);
+  }
   virtual uchar *pack(uchar* to, const uchar *from,
                       uint max_length __attribute__((unused)),
                       bool low_byte_first)
@@ -1153,6 +1215,14 @@ public:
   void sql_type(String &str) const;
   bool can_be_compared_as_longlong() const { return TRUE; }
   uint32 max_display_length() { return 20; }
+  Field_longlong *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_LONGLONG);
+    return new (mem_root) Field_longlong(*this);
+  }
+  Field_longlong *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_LONGLONG);
+    return new Field_longlong(*this);
+  }
   virtual uchar *pack(uchar* to, const uchar *from,
                       uint max_length  __attribute__((unused)),
                       bool low_byte_first)
@@ -1199,6 +1269,14 @@ public:
   uint32 pack_length() const { return sizeof(float); }
   uint row_pack_length() { return pack_length(); }
   void sql_type(String &str) const;
+  Field_float *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_FLOAT);
+    return new (mem_root) Field_float(*this);
+  }
+  Field_float *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_FLOAT);
+    return new Field_float(*this);
+  }
 private:
   int do_save_field_metadata(uchar *first_byte);
 };
@@ -1239,6 +1317,14 @@ public:
   uint32 pack_length() const { return sizeof(double); }
   uint row_pack_length() { return pack_length(); }
   void sql_type(String &str) const;
+  Field_double *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DOUBLE);
+    return new (mem_root) Field_double(*this);
+  }
+  Field_double *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DOUBLE);
+    return new Field_double(*this);
+  }
 private:
   int do_save_field_metadata(uchar *first_byte);
 };
@@ -1272,8 +1358,15 @@ public:
   void sort_string(uchar *buff, uint length)  {}
   uint32 pack_length() const { return 0; }
   void sql_type(String &str) const;
-  uint size_of() const { return sizeof(*this); }
   uint32 max_display_length() { return 4; }
+  Field_null *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_NULL);
+    return new (mem_root) Field_null(*this);
+  }
+  Field_null *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_NULL);
+    return new Field_null(*this);
+  }
 };
 
 
@@ -1343,6 +1436,14 @@ public:
   bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
   bool get_time(MYSQL_TIME *ltime);
   timestamp_auto_set_type get_auto_set_type() const;
+  Field_timestamp *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_TIMESTAMP);
+    return new (mem_root) Field_timestamp(*this);
+  }
+  Field_timestamp *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_TIMESTAMP);
+    return new Field_timestamp(*this);
+  }
   uchar *pack(uchar *to, const uchar *from,
               uint max_length __attribute__((unused)), bool low_byte_first)
   {
@@ -1375,6 +1476,14 @@ public:
   bool send_binary(Protocol *protocol);
   void sql_type(String &str) const;
   bool can_be_compared_as_longlong() const { return TRUE; }
+  Field_year *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_YEAR);
+    return new (mem_root) Field_year(*this);
+  }
+  Field_year *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_YEAR);
+    return new Field_year(*this);
+  }
 };
 
 
@@ -1413,6 +1522,14 @@ public:
   void sql_type(String &str) const;
   bool can_be_compared_as_longlong() const { return TRUE; }
   bool zero_pack() const { return 1; }
+  Field_date *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DATE);
+    return new (mem_root) Field_date(*this);
+  }
+  Field_date *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DATE);
+    return new Field_date(*this);
+  }
   uchar *pack(uchar* to, const uchar *from,
               uint max_length __attribute__((unused)), bool low_byte_first)
   {
@@ -1465,6 +1582,16 @@ public:
   bool zero_pack() const { return 1; }
   bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
   bool get_time(MYSQL_TIME *ltime);
+  Field_newdate *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DATE);
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_NEWDATE);
+    return new (mem_root) Field_newdate(*this);
+  }
+  Field_newdate *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DATE);
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_NEWDATE);
+    return new Field_newdate(*this);
+  }
 };
 
 
@@ -1505,6 +1632,14 @@ public:
   void sql_type(String &str) const;
   bool can_be_compared_as_longlong() const { return TRUE; }
   bool zero_pack() const { return 1; }
+  Field_time *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_TIME);
+    return new (mem_root) Field_time(*this);
+  }
+  Field_time *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_TIME);
+    return new Field_time(*this);
+  }
 };
 
 
@@ -1552,6 +1687,14 @@ public:
   bool zero_pack() const { return 1; }
   bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
   bool get_time(MYSQL_TIME *ltime);
+  Field_datetime *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DATETIME);
+    return new (mem_root) Field_datetime(*this);
+  }
+  Field_datetime *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_DATETIME);
+    return new Field_datetime(*this);
+  }
   uchar *pack(uchar* to, const uchar *from,
               uint max_length __attribute__((unused)), bool low_byte_first)
   {
@@ -1629,11 +1772,18 @@ public:
   int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update);
   uint packed_col_length(const uchar *to, uint length);
   uint max_packed_col_length(uint max_length);
-  uint size_of() const { return sizeof(*this); }
   enum_field_types real_type() const { return MYSQL_TYPE_STRING; }
   bool has_charset(void) const
   { return charset() == &my_charset_bin ? FALSE : TRUE; }
   Field *new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
+  Field_string *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_STRING);
+    return new (mem_root) Field_string(*this);
+  }
+  Field_string *clone() const {
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_STRING);
+    return new Field_string(*this);
+  }
   virtual uint get_key_image(uchar *buff,uint length, imagetype type);
 private:
   int do_save_field_metadata(uchar *first_byte);
@@ -1709,7 +1859,6 @@ public:
   uint packed_col_length(const uchar *to, uint length);
   uint max_packed_col_length(uint max_length);
   uint32 data_length();
-  uint size_of() const { return sizeof(*this); }
   enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
   bool has_charset(void) const
   { return charset() == &my_charset_bin ? FALSE : TRUE; }
@@ -1717,6 +1866,16 @@ public:
   Field *new_key_field(MEM_ROOT *root, TABLE *new_table,
                        uchar *new_ptr, uchar *new_null_ptr,
                        uint new_null_bit);
+  Field_varstring *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_VARCHAR);
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_VARCHAR);
+    return new (mem_root) Field_varstring(*this);
+  }
+  Field_varstring *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_VARCHAR);
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_VARCHAR);
+    return new Field_varstring(*this);
+  }
   uint is_equal(Create_field *new_field);
   void hash(ulong *nr, ulong *nr2);
 private:
@@ -1877,6 +2036,14 @@ public:
     memcpy(ptr+packlength, &tmp, sizeof(char*));
     return 0;
   }
+  Field_blob *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_BLOB);
+    return new (mem_root) Field_blob(*this);
+  }
+  Field_blob *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_BLOB);
+    return new Field_blob(*this);
+  }
   virtual uchar *pack(uchar *to, const uchar *from,
                       uint max_length, bool low_byte_first);
   virtual const uchar *unpack(uchar *to, const uchar *from,
@@ -1886,7 +2053,6 @@ public:
   void free() { value.free(); }
   inline void clear_temporary() { bzero((uchar*) &value,sizeof(value)); }
   friend int field_conv(Field *to,Field *from);
-  uint size_of() const { return sizeof(*this); }
   bool has_charset(void) const
   { return charset() == &my_charset_bin ? FALSE : TRUE; }
   uint32 max_display_length();
@@ -1923,9 +2089,16 @@ public:
   int  store(double nr);
   int  store(longlong nr, bool unsigned_val);
   int  store_decimal(const my_decimal *);
-  uint size_of() const { return sizeof(*this); }
   int  reset(void) { return !maybe_null() || Field_blob::reset(); }
   geometry_type get_geometry_type() { return geom_type; };
+  Field_geom *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_GEOMETRY);
+    return new (mem_root) Field_geom(*this);
+  }
+  Field_geom *clone() const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_GEOMETRY);
+    return new Field_geom(*this);
+  }
 };
 #endif /*HAVE_SPATIAL*/
 
@@ -1964,7 +2137,6 @@ public:
   uint32 pack_length() const { return (uint32) packlength; }
   void store_type(ulonglong value);
   void sql_type(String &str) const;
-  uint size_of() const { return sizeof(*this); }
   enum_field_types real_type() const { return MYSQL_TYPE_ENUM; }
   uint pack_length_from_metadata(uint field_metadata)
   { return (field_metadata & 0x00ff); }
@@ -1975,7 +2147,14 @@ public:
   bool has_charset(void) const { return TRUE; }
   /* enum and set are sorted as integers */
   CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
-
+  Field_enum *clone(MEM_ROOT *mem_root) const {
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_ENUM);
+    return new (mem_root) Field_enum(*this);
+  }
+  Field_enum *clone() const { 
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_ENUM);
+    return new Field_enum(*this);
+  }
   virtual uchar *pack(uchar *to, const uchar *from,
                       uint max_length, bool low_byte_first);
   virtual const uchar *unpack(uchar *to, const uchar *from,
@@ -2004,12 +2183,19 @@ public:
   int  store(const char *to,uint length,CHARSET_INFO *charset);
   int  store(double nr) { return Field_set::store((longlong) nr, FALSE); }
   int  store(longlong nr, bool unsigned_val);
-
   virtual bool zero_pack() const { return 1; }
   String *val_str(String*,String *);
   void sql_type(String &str) const;
   enum_field_types real_type() const { return MYSQL_TYPE_SET; }
   bool has_charset(void) const { return TRUE; }
+  Field_set *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_SET);
+    return new (mem_root) Field_set(*this);
+  }
+  Field_set *clone() const {
+    DBUG_ASSERT(real_type() == MYSQL_TYPE_SET);
+    return new Field_set(*this);
+  }
 };
 
 
@@ -2041,7 +2227,6 @@ public:
   uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
   uint32 max_data_length() const { return (field_length + 7) / 8; }
   uint32 max_display_length() { return field_length; }
-  uint size_of() const { return sizeof(*this); }
   Item_result result_type () const { return INT_RESULT; }
   int reset(void) { 
     bzero(ptr, bytes_in_rec); 
@@ -2117,7 +2302,14 @@ public:
     bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*);
   }
   void hash(ulong *nr, ulong *nr2);
-
+  Field_bit *clone(MEM_ROOT *mem_root) const { 
+    DBUG_ASSERT(type() == MYSQL_TYPE_BIT);
+    return new (mem_root) Field_bit(*this);
+  }
+  Field_bit *clone() const {
+    DBUG_ASSERT(type() == MYSQL_TYPE_BIT);
+    return new Field_bit(*this);
+  }
 private:
   virtual size_t do_last_null_byte() const;
   int do_save_field_metadata(uchar *first_byte);
@@ -2137,12 +2329,15 @@ public:
                     uchar null_bit_arg,
                     enum utype unireg_check_arg, const char *field_name_arg);
   enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
-  uint size_of() const { return sizeof(*this); }
   int store(const char *to, uint length, CHARSET_INFO *charset);
   int store(double nr) { return Field_bit::store(nr); }
   int store(longlong nr, bool unsigned_val)
   { return Field_bit::store(nr, unsigned_val); }
   void sql_type(String &str) const;
+  Field_bit_as_char *clone(MEM_ROOT *mem_root) const { 
+    return new (mem_root) Field_bit_as_char(*this);
+  }
+  Field_bit_as_char *clone() const { return new Field_bit_as_char(*this); }
 };
 
 

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2010-11-29 16:27:58 +0000
+++ b/sql/item.cc	2010-12-14 12:50:35 +0000
@@ -6984,9 +6984,11 @@ bool Item_default_value::fix_fields(THD 
     my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name);
     goto error;
   }
-  if (!(def_field= (Field*) sql_alloc(field_arg->field->size_of())))
+
+  def_field= field_arg->field->clone();
+  if (def_field == NULL)
     goto error;
-  memcpy(def_field, field_arg->field, field_arg->field->size_of());
+
   def_field->move_field_offset((my_ptrdiff_t)
                                (def_field->table->s->default_values -
                                 def_field->table->record[0]));
@@ -7127,10 +7129,10 @@ bool Item_insert_value::fix_fields(THD *
 
   if (field_arg->field->table->insert_values)
   {
-    Field *def_field= (Field*) sql_alloc(field_arg->field->size_of());
+    Field *def_field= field_arg->field->clone();
     if (!def_field)
       return TRUE;
-    memcpy(def_field, field_arg->field, field_arg->field->size_of());
+
     def_field->move_field_offset((my_ptrdiff_t)
                                  (def_field->table->insert_values -
                                   def_field->table->record[0]));


Attachment: [text/bzr-bundle] bzr/martin.hansson@oracle.com-20101214125035-rd676ha09s8xgb3u.bundle
Thread
bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260) Bug#58918Martin Hansson14 Dec
Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Tor Didriksen15 Dec
  • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Martin Hansson15 Dec
    • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Tor Didriksen16 Dec
    • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Øystein Grøvlen16 Dec
      • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Martin Hansson16 Dec
Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Tor Didriksen16 Dec
  • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Martin Hansson16 Dec
Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Øystein Grøvlen17 Dec
  • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Martin Hansson20 Dec
    • Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)Bug#58918Øystein Grøvlen20 Dec