List:Commits« Previous MessageNext Message »
From:eugene Date:July 7 2007 8:17pm
Subject:bk commit into 5.1 tree (evgen:1.2534) BUG#29310
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of evgen. When evgen 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-07-08 00:17:35+04:00, evgen@stripped +4 -0
  Bug#29310: An InnoDB table was updated when the data wasn't actually changed.
  
  When a table is being updated it has two set of fields - fields required for
  checks of conditions and fields to be updated. A storage engine is allowed
  not to retrieve columns marked for update. Due to this fact records can't
  be compared to see whether the data has been changed or not. This makes the
  server always update records independently of data change.
  
  Now when server sees that a handle isn't going to retrieve write-only fields
  then all of such fields are marked as to be read to force the handler to
  retrieve them.

  mysql-test/include/mix1.inc@stripped, 2007-07-08 00:17:04+04:00, evgen@stripped +22 -0
    Added a test case for the bug#29310: An InnoDB table was updated when the data wasn't actually changed.

  mysql-test/r/innodb_mysql.result@stripped, 2007-07-08 00:17:07+04:00, evgen@stripped +28 -0
    Added a test case for the bug#29310: An InnoDB table was updated when the data wasn't actually changed.

  sql/sql_insert.cc@stripped, 2007-07-08 00:10:24+04:00, evgen@stripped +2 -1
    Bug#29310: An InnoDB table was updated when the data wasn't actually changed.
    Now the write_record function can compare records when fileds to be written is
    a subset of the fields to be read while updating a record.

  sql/sql_update.cc@stripped, 2007-07-08 00:16:29+04:00, evgen@stripped +7 -0
    Bug#29310: An InnoDB table was updated when the data wasn't actually changed.
    Now the mysql_update function marks write-only fields
    as to be read to force the table handler to retrieve them.

diff -Nrup a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
--- a/mysql-test/include/mix1.inc	2007-07-04 12:58:54 +04:00
+++ b/mysql-test/include/mix1.inc	2007-07-08 00:17:04 +04:00
@@ -948,5 +948,27 @@ unlock tables;
 select * from t1;
 drop tables t1;
 
+#
+# Bug#29310: An InnoDB table was updated when the data wasn't actually changed.
+#
+create table t1(f1 varchar(5) unique, f2 timestamp NOT NULL DEFAULT
+  CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
+insert into t1(f1) values(1);
+-- replace _column 1 #
+select @a:=f2 from t1;
+--sleep 5
+update t1 set f1=1;
+-- replace _column 1 #
+select @b:=f2 from t1;
+select if(@a=@b,"ok","wrong");
+--sleep 5
+insert into t1(f1) values (1) on duplicate key update f1="1";
+select @b:=f2 from t1;
+select if(@a=@b,"ok","wrong");
+--sleep 5
+insert into t1(f1) select f1 from t1 on duplicate key update f1="1";
+select @b:=f2 from t1;
+select if(@a=@b,"ok","wrong");
+drop table t1;
 
 --echo End of 5.1 tests
diff -Nrup a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
--- a/mysql-test/r/innodb_mysql.result	2007-07-04 12:58:54 +04:00
+++ b/mysql-test/r/innodb_mysql.result	2007-07-08 00:17:07 +04:00
@@ -951,4 +951,32 @@ NULL
 1
 Two
 drop tables t1;
+create table t1(f1 varchar(5) unique, f2 timestamp NOT NULL DEFAULT
+CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
+insert into t1(f1) values(1);
+select @a:=f2 from t1;
+@a:=f2
+2007-07-07 00:02:53
+update t1 set f1=1;
+select @b:=f2 from t1;
+@b:=f2
+2007-07-07 00:02:53
+select if(@a=@b,"ok","wrong");
+if(@a=@b,"ok","wrong")
+ok
+insert into t1(f1) values (1) on duplicate key update f1="1";
+select @b:=f2 from t1;
+@b:=f2
+2007-07-07 00:02:53
+select if(@a=@b,"ok","wrong");
+if(@a=@b,"ok","wrong")
+ok
+insert into t1(f1) select f1 from t1 on duplicate key update f1="1";
+select @b:=f2 from t1;
+@b:=f2
+2007-07-07 00:02:53
+select if(@a=@b,"ok","wrong");
+if(@a=@b,"ok","wrong")
+ok
+drop table t1;
 End of 5.1 tests
diff -Nrup a/sql/sql_insert.cc b/sql/sql_insert.cc
--- a/sql/sql_insert.cc	2007-07-01 07:25:43 +04:00
+++ b/sql/sql_insert.cc	2007-07-08 00:10:24 +04:00
@@ -1419,7 +1419,8 @@ int write_record(THD *thd, TABLE *table,
           goto before_trg_err;
 
         table->file->restore_auto_increment(prev_insert_id);
-        if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) ||
+        if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ &&
+             !bitmap_is_subset(table->write_set, table->read_set)) ||
             compare_record(table))
         {
           if ((error=table->file->ha_update_row(table->record[1],
diff -Nrup a/sql/sql_update.cc b/sql/sql_update.cc
--- a/sql/sql_update.cc	2007-06-28 17:07:54 +04:00
+++ b/sql/sql_update.cc	2007-07-08 00:16:29 +04:00
@@ -231,6 +231,13 @@ int mysql_update(THD *thd,
     if (cond_value == Item::COND_FALSE)
       limit= 0;                                   // Impossible WHERE
   }
+
+  /*
+    Force handler to retrieve write-only fields to be able to compare
+    records and detect data change.
+  */
+  if (table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ)
+    bitmap_union(table->read_set, table->write_set);
   // Don't count on usage of 'only index' when calculating which key to use
   table->covering_keys.clear_all();
 
Thread
bk commit into 5.1 tree (evgen:1.2534) BUG#29310eugene7 Jul
  • Re: bk commit into 5.1 tree (evgen:1.2534) BUG#29310Sergei Golubchik7 Jul