List:Commits« Previous MessageNext Message »
From:Tatiana A. Nurnberg Date:October 9 2009 12:41pm
Subject:bzr commit into mysql-5.1-bugteam branch (azundris:3068) Bug#43508
View as plain text  
#At file:///Users/tnurnberg/forest/43508/51-43508/ based on revid:li-bing.song@stripped

 3068 Tatiana A. Nurnberg	2009-10-09 [merge]
      Bug#43508: Renaming timestamp or date column triggers table copy
      
      We set up DATE and TIMESTAMP differently in field-creation than we
      did in field-MD creation (for CREATE). Admirably, ALTER TABLE
      detected this and didn't damage any data, but it did initiate a
      full copy/conversion, which we don't really need to do.
      
      Now we describe Field and Create_field the same for those types.
      As a result, ALTER TABLE that only changes meta-data (like a
      field's name) no longer forces a data-copy when there needn't
      be one.
     @ mysql-test/r/alter_table.result
        0 rows should be affected when a meta-data change is enough ALTER TABLE.
     @ mysql-test/t/alter_table.test
        add test-case: show that we don't do a full data-copy on ALTER TABLE
        when we don't need to.
     @ sql/field.cc
        Remove Field_str::compare_str_field_flags() (now in Field/Create_field as
        field_flags_are_binary().
        
        Correct some field-lengths!
     @ sql/field.h
        Clean-up: use defined constants rather than numeric literals for certain
        field-lengths.
        
        Add enquiry-functions binaryp() to classes Field and Create_field.
        This replaces field.cc's Field_str::compare_str_field_flags().

    modified:
      mysql-test/r/alter_table.result
      mysql-test/t/alter_table.test
      sql/field.cc
      sql/field.h
=== modified file 'mysql-test/r/alter_table.result'
--- a/mysql-test/r/alter_table.result	2008-12-09 13:31:22 +0000
+++ b/mysql-test/r/alter_table.result	2009-10-09 12:41:04 +0000
@@ -1268,4 +1268,12 @@ a	b
 4	b
 5	a
 DROP TABLE t1;
+CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL,
+f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2);
+this should affect no rows as there is no real change
+ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
+affected rows: 0
+info: Records: 0  Duplicates: 0  Warnings: 0
+DROP TABLE t1;
 End of 5.1 tests

=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test	2008-12-09 13:31:22 +0000
+++ b/mysql-test/t/alter_table.test	2009-10-09 12:41:04 +0000
@@ -1000,4 +1000,19 @@ ALTER TABLE t1 MODIFY b ENUM('a', 'z', '
 SELECT * FROM t1;
 DROP TABLE t1;
 
+#
+# Bug#43508: Renaming timestamp or date column triggers table copy
+#
+
+CREATE TABLE t1 (f1 TIMESTAMP NULL DEFAULT NULL,
+                 f2 INT(11) DEFAULT NULL) ENGINE=MYISAM DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES (NULL, NULL), ("2009-10-09 11:46:19", 2);
+
+--echo this should affect no rows as there is no real change
+--enable_info
+ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL;
+--disable_info
+DROP TABLE t1;
+
 --echo End of 5.1 tests

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2009-08-06 11:31:26 +0000
+++ b/sql/field.cc	2009-10-09 12:41:04 +0000
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -6470,20 +6470,9 @@ uint Field::is_equal(Create_field *new_f
 }
 
 
-/* If one of the fields is binary and the other one isn't return 1 else 0 */
-
-bool Field_str::compare_str_field_flags(Create_field *new_field, uint32 flag_arg)
-{
-  return (((new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
-          !(flag_arg & (BINCMP_FLAG | BINARY_FLAG))) ||
-         (!(new_field->flags & (BINCMP_FLAG | BINARY_FLAG)) &&
-          (flag_arg & (BINCMP_FLAG | BINARY_FLAG))));
-}
-
-
 uint Field_str::is_equal(Create_field *new_field)
 {
-  if (compare_str_field_flags(new_field, flags))
+  if (field_flags_are_binary() != new_field->field_flags_are_binary())
     return 0;
 
   return ((new_field->sql_type == real_type()) &&
@@ -8249,7 +8238,7 @@ uint Field_blob::max_packed_col_length(u
 
 uint Field_blob::is_equal(Create_field *new_field)
 {
-  if (compare_str_field_flags(new_field, flags))
+  if (field_flags_are_binary() != new_field->field_flags_are_binary())
     return 0;
 
   return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
@@ -9535,7 +9524,7 @@ bool Create_field::init(THD *thd, char *
     }
 
     if (length == 0)
-      fld_length= 0; /* purecov: inspected */
+      fld_length= NULL; /* purecov: inspected */
   }
 
   sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
@@ -9687,8 +9676,7 @@ bool Create_field::init(THD *thd, char *
   case MYSQL_TYPE_TIMESTAMP:
     if (fld_length == NULL)
     {
-      /* Compressed date YYYYMMDDHHMMSS */
-      length= MAX_DATETIME_COMPRESSED_WIDTH;
+      length= MAX_DATETIME_WIDTH;
     }
     else if (length != MAX_DATETIME_WIDTH)
     {
@@ -9753,7 +9741,7 @@ bool Create_field::init(THD *thd, char *
       sql_type= MYSQL_TYPE_NEWDATE;
     /* fall trough */
   case MYSQL_TYPE_NEWDATE:
-    length= 10;
+    length= MAX_DATE_WIDTH;
     break;
   case MYSQL_TYPE_TIME:
     length= 10;
@@ -9834,6 +9822,17 @@ bool Create_field::init(THD *thd, char *
     DBUG_RETURN(TRUE);
   }
 
+  switch (fld_type) {
+  case MYSQL_TYPE_DATE:
+  case MYSQL_TYPE_NEWDATE:
+  case MYSQL_TYPE_TIME:
+  case MYSQL_TYPE_DATETIME:
+  case MYSQL_TYPE_TIMESTAMP:
+    charset= &my_charset_bin;
+    flags|= BINCMP_FLAG;
+  default: break;
+  }
+
   DBUG_RETURN(FALSE); /* success */
 }
 

=== modified file 'sql/field.h'
--- a/sql/field.h	2009-06-09 16:44:26 +0000
+++ b/sql/field.h	2009-06-24 11:02:20 +0000
@@ -1,4 +1,4 @@
-/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+/* Copyright 2000-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -603,6 +603,12 @@ protected:
     handle_int64(to, from, low_byte_first_from, table->s->db_low_byte_first);
     return from + sizeof(int64);
   }
+
+  bool field_flags_are_binary()
+  {
+    return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
+  }
+
 };
 
 
@@ -658,7 +664,6 @@ public:
   friend class Create_field;
   my_decimal *val_decimal(my_decimal *);
   virtual bool str_needs_quotes() { return TRUE; }
-  bool compare_str_field_flags(Create_field *new_field, uint32 flags);
   uint is_equal(Create_field *new_field);
 };
 
@@ -1268,12 +1273,12 @@ public:
   Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
 	     enum utype unireg_check_arg, const char *field_name_arg,
 	     CHARSET_INFO *cs)
-    :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
+    :Field_str(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
 	       unireg_check_arg, field_name_arg, cs)
     {}
   Field_date(bool maybe_null_arg, const char *field_name_arg,
              CHARSET_INFO *cs)
-    :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0,
+    :Field_str((uchar*) 0, MAX_DATE_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
 	       NONE, field_name_arg, cs) {}
   enum_field_types type() const { return MYSQL_TYPE_DATE;}
   enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
@@ -1383,12 +1388,12 @@ public:
   Field_datetime(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
 		 enum utype unireg_check_arg, const char *field_name_arg,
 		 CHARSET_INFO *cs)
-    :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
+    :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
 	       unireg_check_arg, field_name_arg, cs)
     {}
   Field_datetime(bool maybe_null_arg, const char *field_name_arg,
 		 CHARSET_INFO *cs)
-    :Field_str((uchar*) 0,19, maybe_null_arg ? (uchar*) "": 0,0,
+    :Field_str((uchar*) 0, MAX_DATETIME_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
 	       NONE, field_name_arg, cs) {}
   enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
 #ifdef HAVE_LONG_LONG
@@ -2061,6 +2066,11 @@ public:
             Item *on_update_value, LEX_STRING *comment, char *change,
             List<String> *interval_list, CHARSET_INFO *cs,
             uint uint_geom_type);
+
+  bool field_flags_are_binary()
+  {
+    return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
+  }
 };
 
 


Attachment: [text/bzr-bundle] bzr/azundris@mysql.com-20091009124104-smswmzubqi8me3zq.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (azundris:3068) Bug#43508Tatiana A. Nurnberg9 Oct