From: Martin Hansson Date: December 8 2010 9:02am Subject: bzr commit into mysql-trunk-bugfixing branch (martin.hansson:3255) List-Archive: http://lists.mysql.com/commits/126294 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0911053578==" --===============0911053578== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///data0/martin/bzrroot/refactoring-Field_clone/n-mr-o-t/ based on revid:tor.didriksen@stripped 3255 Martin Hansson 2010-12-08 Refactoring: Remove all copying of Field objects using memcpy() and replace it with virtual clone() and clone(MEM_ROOT*) methods. An operator new (MEM_ROOT*) is also implemented. The sole purpose of the Field::size_of() method was to support the memcpy and 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-08 09:02:02 +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-08 09:02:02 +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-08 09:02:02 +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])); --===============0911053578== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/martin.hansson@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: martin.hansson@stripped\ # ttwm7i6m9w1mrqq6 # target_branch: file:///data0/martin/bzrroot/refactoring-\ # Field_clone/n-mr-o-t/ # testament_sha1: a7b4a3c5aff7e793a3b8c0f1d784a43b85240376 # timestamp: 2010-12-08 10:02:07 +0100 # base_revision_id: tor.didriksen@stripped\ # hex6tudypt2kr3m4 # # Begin bundle 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 i7kinChIc70uEIA= --===============0911053578==--