Commit 35c8b4c5 authored by Chad MILLER's avatar Chad MILLER

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.)

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()
parent 986a27fb
...@@ -1612,4 +1612,29 @@ t1 CREATE TABLE `t1` ( ...@@ -1612,4 +1612,29 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`id`) 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) */ ) 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; 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 End of 5.1 tests
...@@ -1761,4 +1761,34 @@ while ($n) ...@@ -1761,4 +1761,34 @@ while ($n)
--enable_query_log --enable_query_log
show create table t1; show create table t1;
drop 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 --echo End of 5.1 tests
...@@ -2826,6 +2826,7 @@ int ha_partition::write_row(uchar * buf) ...@@ -2826,6 +2826,7 @@ int ha_partition::write_row(uchar * buf)
bool autoincrement_lock= FALSE; bool autoincrement_lock= FALSE;
my_bitmap_map *old_map; my_bitmap_map *old_map;
THD *thd= ha_thd(); THD *thd= ha_thd();
timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
#ifdef NOT_NEEDED #ifdef NOT_NEEDED
uchar *rec0= m_rec0; uchar *rec0= m_rec0;
#endif #endif
...@@ -2835,6 +2836,7 @@ int ha_partition::write_row(uchar * buf) ...@@ -2835,6 +2836,7 @@ int ha_partition::write_row(uchar * buf)
/* If we have a timestamp column, update it to the current time */ /* If we have a timestamp column, update it to the current time */
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time(); 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 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) ...@@ -2901,6 +2903,7 @@ int ha_partition::write_row(uchar * buf)
error= m_file[part_id]->ha_write_row(buf); error= m_file[part_id]->ha_write_row(buf);
reenable_binlog(thd); reenable_binlog(thd);
exit: exit:
table->timestamp_field_type= orig_timestamp_type;
if (autoincrement_lock) if (autoincrement_lock)
pthread_mutex_unlock(&table_share->mutex); pthread_mutex_unlock(&table_share->mutex);
DBUG_RETURN(error); DBUG_RETURN(error);
...@@ -2953,10 +2956,8 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data) ...@@ -2953,10 +2956,8 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
inside m_file[*]->update_row() methods inside m_file[*]->update_row() methods
*/ */
if (orig_timestamp_type & TIMESTAMP_AUTO_SET_ON_UPDATE) if (orig_timestamp_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
{
table->timestamp_field->set_time(); 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], if ((error= get_parts_for_update(old_data, new_data, table->record[0],
m_part_info, &old_part_id, &new_part_id, m_part_info, &old_part_id, &new_part_id,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment