List:Commits« Previous MessageNext Message »
From:Øystein Grøvlen Date:December 17 2010 12:28pm
Subject:Re: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3260)
Bug#58918
View as plain text  
Hi Martin,

Thanks for a good initiative.  I have bitten by this memcpy stuff 
myself. I wonder whether I should require or just suggest that you try 
to add a unit test for your clone methods.  Unit tests for basic classes 
like Field should be possible without too much work.  (Tor told me it 
was pretty straight-forward for Item_int).

I also think that we should drop the existing clone method:

 >     Field *clone(MEM_ROOT *mem_root, TABLE *new_table);

This is used in only one place, and its implementation uses only public 
Field methods, so I think the entire code should be moved to the caller.
(The Field interface is unecessarily large. No need to provide 
unecessary helper functions.)

--
Øystein


On 12/16/10 02:49 PM, Martin Hansson wrote:
> #At file:///data0/martin/bzrroot/refactoring-Field_clone/n-mr-o-t/ based on
> revid:tor.didriksen@stripped
>
>   3260 Martin Hansson	2010-12-16
>        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.
>
>      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-16 13:49: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-16 13:49: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 member function 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 member function 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-16 13:49: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]));
>
>
>
>
>
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