List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:August 15 2008 8:26pm
Subject:bzr commit into mysql-5.1-bugteam branch (chad:2704) Bug#38272
View as plain text  
#At file:///home/cmiller/work/mysqlbzr/mysql-5.1-bugteam/

 2704 Chad MILLER	2008-08-15
      Bug#38272: timestamps fields incorrectly defaulted on \
      	update accross partitions.
            
      It's not Innodb-specific bug.
      ha_partition::update_row() didn't set
      table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET when
      orig_timestamp_type == TIMESTAMP_AUTO_SET_ON_INSERT.
      
      So that a partition sets the timestamp field when a record
      is moved to a different partition.
      
      Fixed by doing '= TIMESTAMP_NO_AUTO_SET' unconditionally.
      Also ha_partition::write_row() is fixed in same way as now
      Field_timestamp::set() is called twice in SET_ON_INSERT case.
      
      (Chad queues this patch on demand by Trudy/Davi.)
modified:
  mysql-test/r/partition.result
  mysql-test/t/partition.test
  sql/ha_partition.cc

per-file messages:
  mysql-test/r/partition.result
    Bug#38272 timestamps fields incorrectly defaulted on update accross partitions.
    test result
  mysql-test/t/partition.test
    Bug#38272 timestamps fields incorrectly defaulted on update accross partitions.
    test case
  sql/ha_partition.cc
    Bug#38272 timestamps fields incorrectly defaulted on update accross partitions.
    Do table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET unconditionally
    in ha_partition::update_row and ::write_row()
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2008-08-11 18:02:03 +0000
+++ b/mysql-test/r/partition.result	2008-08-15 18:26:25 +0000
@@ -1612,4 +1612,29 @@ t1	CREATE TABLE `t1` (
   PRIMARY KEY (`id`)
 ) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (id)
SUBPARTITION BY HASH (id) SUBPARTITIONS 2 (PARTITION pa1 VALUES LESS THAN (10) ENGINE =
MyISAM, PARTITION pa2 VALUES LESS THAN (20) ENGINE = MyISAM, PARTITION pa11 VALUES LESS
THAN MAXVALUE ENGINE = MyISAM) */
 drop table t1;
+CREATE TABLE  t1 (
+`ID` bigint(20) NOT NULL AUTO_INCREMENT,
+`createdDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+`number` int,
+PRIMARY KEY (`ID`, number)
+)
+PARTITION BY RANGE (number) (
+PARTITION p0 VALUES LESS THAN (6),
+PARTITION p1 VALUES LESS THAN (11)
+);
+create table t2 (
+`ID` bigint(20),
+`createdDate` TIMESTAMP,
+`number` int
+);
+INSERT INTO t1 SET number=1;
+insert into t2 select * from t1;
+SELECT SLEEP(1);
+SLEEP(1)
+0
+UPDATE t1 SET number=6;
+select count(*) from t1, t2 where t1.createdDate = t2.createdDate;
+count(*)
+1
+drop table t1, t2;
 End of 5.1 tests

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2008-08-11 18:02:03 +0000
+++ b/mysql-test/t/partition.test	2008-08-15 18:26:25 +0000
@@ -1761,4 +1761,34 @@ while ($n)
 --enable_query_log
 show create table t1;
 drop table t1;
+
+#
+# Bug #38272 timestamps fields incorrectly defaulted on update accross partitions.
+#
+
+CREATE TABLE  t1 (
+  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
+  `createdDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `number` int,
+  PRIMARY KEY (`ID`, number)
+)
+PARTITION BY RANGE (number) (
+    PARTITION p0 VALUES LESS THAN (6),
+    PARTITION p1 VALUES LESS THAN (11)
+);
+
+create table t2 (
+  `ID` bigint(20),
+  `createdDate` TIMESTAMP,
+  `number` int
+);
+
+INSERT INTO t1 SET number=1;
+insert into t2 select * from t1;
+SELECT SLEEP(1);
+UPDATE t1 SET number=6;
+select count(*) from t1, t2 where t1.createdDate = t2.createdDate;
+
+drop table t1, t2;
+
 --echo End of 5.1 tests

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2008-08-13 08:47:24 +0000
+++ b/sql/ha_partition.cc	2008-08-15 18:26:25 +0000
@@ -2826,6 +2826,7 @@ int ha_partition::write_row(uchar * buf)
   bool autoincrement_lock= FALSE;
   my_bitmap_map *old_map;
   THD *thd= ha_thd();
+  timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
 #ifdef NOT_NEEDED
   uchar *rec0= m_rec0;
 #endif
@@ -2835,6 +2836,7 @@ int ha_partition::write_row(uchar * buf)
   /* If we have a timestamp column, update it to the current time */
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
     table->timestamp_field->set_time();
+  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
   /*
     If we have an auto_increment column and we are writing a changed row
@@ -2901,6 +2903,7 @@ int ha_partition::write_row(uchar * buf)
   error= m_file[part_id]->ha_write_row(buf);
   reenable_binlog(thd);
 exit:
+  table->timestamp_field_type= orig_timestamp_type;
   if (autoincrement_lock)
     pthread_mutex_unlock(&table_share->mutex);
   DBUG_RETURN(error);
@@ -2953,10 +2956,8 @@ int ha_partition::update_row(const uchar
     inside m_file[*]->update_row() methods
   */
   if (orig_timestamp_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
-  {
     table->timestamp_field->set_time();
-    table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-  }
+  table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
   if ((error= get_parts_for_update(old_data, new_data, table->record[0],
                                    m_part_info, &old_part_id, &new_part_id,

Thread
bzr commit into mysql-5.1-bugteam branch (chad:2704) Bug#38272Chad MILLER15 Aug