List:Commits« Previous MessageNext Message »
From:holyfoot Date:November 12 2007 5:11pm
Subject:bk commit into 5.1 tree (holyfoot:1.2625) BUG#32067
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of hf. When hf does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-11-12 21:11:31+04:00, holyfoot@stripped +3 -0
  Bug #32067 Partitions: crash with timestamp column.
  
  Partition handler fails updating tables with partitioning
  based on timestamp field, as it calculates the timestamp field
  AFTER it calculates the number of partition of a record.
  
  Fixed by adding timestamp_field->set_time() call and disabling
  such consequent calls

  mysql-test/r/partition.result@stripped, 2007-11-12 21:11:27+04:00, holyfoot@stripped +5 -0
    Bug #32067 Partitions: crash with timestamp column.
    
    test result

  mysql-test/t/partition.test@stripped, 2007-11-12 21:11:27+04:00, holyfoot@stripped +21 -0
    Bug #32067 Partitions: crash with timestamp column.
    
    test case

  sql/ha_partition.cc@stripped, 2007-11-12 21:11:27+04:00, holyfoot@stripped +22 -6
    Bug #32067 Partitions: crash with timestamp column.
    
    do timestamp_field->set_time() in the ha_partition::update_row()

diff -Nrup a/mysql-test/r/partition.result b/mysql-test/r/partition.result
--- a/mysql-test/r/partition.result	2007-10-20 01:03:16 +05:00
+++ b/mysql-test/r/partition.result	2007-11-12 21:11:27 +04:00
@@ -1291,4 +1291,9 @@ t1	CREATE TABLE `t1` (
   `b` int(11) DEFAULT NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (b) (PARTITION p1 VALUES LESS THAN (10) ENGINE = MyISAM, PARTITION p2 VALUES LESS THAN (20) ENGINE = MyISAM) */
 drop table t1, t2;
+create table t1
+(s1 timestamp on update current_timestamp, s2 int)
+partition by key(s1) partitions 3;
+insert into t1 values (null,null);
+drop table t1;
 End of 5.1 tests
diff -Nrup a/mysql-test/t/partition.test b/mysql-test/t/partition.test
--- a/mysql-test/t/partition.test	2007-10-20 01:03:16 +05:00
+++ b/mysql-test/t/partition.test	2007-11-12 21:11:27 +04:00
@@ -1528,4 +1528,25 @@ PARTITION BY RANGE (b) (
 show create table t1;
 drop table t1, t2;
 
+#
+# Bug #32067 Partitions: crash with timestamp column
+#  this bug occurs randomly on some UPDATE statement
+#  with the '1032: Can't find record in 't1'' error
+
+create table t1
+ (s1 timestamp on update current_timestamp, s2 int)
+ partition by key(s1) partitions 3;
+
+insert into t1 values (null,null);
+--disable_query_log
+let $cnt= 1000;
+while ($cnt)
+{
+  update t1 set s2 = 1;
+  update t1 set s2 = 2;
+  dec $cnt;
+}
+--enable_query_log
+
+drop table t1;
 --echo End of 5.1 tests
diff -Nrup a/sql/ha_partition.cc b/sql/ha_partition.cc
--- a/sql/ha_partition.cc	2007-10-23 19:02:24 +05:00
+++ b/sql/ha_partition.cc	2007-11-12 21:11:27 +04:00
@@ -2783,16 +2783,28 @@ exit:
 int ha_partition::update_row(const uchar *old_data, uchar *new_data)
 {
   uint32 new_part_id, old_part_id;
-  int error;
+  int error= 0;
   longlong func_value;
+  timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
   DBUG_ENTER("ha_partition::update_row");
 
+  /*
+    We need to set timestamp field once before we calculate
+    the partition. Then we disable timestamp calculations
+    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;
+  }
+
   if ((error= get_parts_for_update(old_data, new_data, table->record[0],
                                    m_part_info, &old_part_id, &new_part_id,
                                    &func_value)))
   {
     m_part_info->err_value= func_value;
-    DBUG_RETURN(error);
+    goto exit;
   }
 
   /*
@@ -2804,23 +2816,27 @@ int ha_partition::update_row(const uchar
   if (new_part_id == old_part_id)
   {
     DBUG_PRINT("info", ("Update in partition %d", new_part_id));
-    DBUG_RETURN(m_file[new_part_id]->update_row(old_data, new_data));
+    error= m_file[new_part_id]->update_row(old_data, new_data);
+    goto exit;
   }
   else
   {
     DBUG_PRINT("info", ("Update from partition %d to partition %d",
 			old_part_id, new_part_id));
     if ((error= m_file[new_part_id]->write_row(new_data)))
-      DBUG_RETURN(error);
+      goto exit;
     if ((error= m_file[old_part_id]->delete_row(old_data)))
     {
 #ifdef IN_THE_FUTURE
       (void) m_file[new_part_id]->delete_last_inserted_row(new_data);
 #endif
-      DBUG_RETURN(error);
+      goto exit;
     }
   }
-  DBUG_RETURN(0);
+
+exit:
+  table->timestamp_field_type= orig_timestamp_type;
+  DBUG_RETURN(error);
 }
 
 
Thread
bk commit into 5.1 tree (holyfoot:1.2625) BUG#32067holyfoot12 Nov