mirror of
https://github.com/MariaDB/server.git
synced 2025-07-24 19:42:23 +03:00
MDEV-12672 Replicated TIMESTAMP fields given wrong value near DST change
Implement a special Copy_field method for timestamps, that copies timestamps without converting them to MYSQL_TIME (the conversion is lossy around DST change dates).
This commit is contained in:
@ -127,3 +127,26 @@ Warning 1264 Out of range value for column 'a' at row 1
|
||||
Warning 1264 Out of range value for column 'b' at row 1
|
||||
DROP TABLE t1;
|
||||
SET @@global.mysql56_temporal_format=DEFAULT;
|
||||
set time_zone='Europe/Moscow';
|
||||
set global mysql56_temporal_format=false;
|
||||
create table t1 (a timestamp);
|
||||
set timestamp=1288477526;
|
||||
insert t1 values (null);
|
||||
set timestamp=1288481126;
|
||||
insert t1 values (null);
|
||||
select a, unix_timestamp(a) from t1;
|
||||
a unix_timestamp(a)
|
||||
2010-10-31 02:25:26 1288477526
|
||||
2010-10-31 02:25:26 1288481126
|
||||
set global mysql56_temporal_format=true;
|
||||
select a, unix_timestamp(a) from t1;
|
||||
a unix_timestamp(a)
|
||||
2010-10-31 02:25:26 1288477526
|
||||
2010-10-31 02:25:26 1288481126
|
||||
alter table t1 modify a timestamp;
|
||||
select a, unix_timestamp(a) from t1;
|
||||
a unix_timestamp(a)
|
||||
2010-10-31 02:25:26 1288477526
|
||||
2010-10-31 02:25:26 1288481126
|
||||
drop table t1;
|
||||
set time_zone=DEFAULT;
|
||||
|
@ -0,0 +1,28 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
set global time_zone='Europe/Moscow';
|
||||
set time_zone='UTC';
|
||||
stop slave;
|
||||
start slave;
|
||||
set global mysql56_temporal_format=false;
|
||||
set global time_zone='Europe/Moscow';
|
||||
set time_zone='UTC';
|
||||
create table t1 (pk int primary key, t timestamp not null);
|
||||
set timestamp = 1288477526;
|
||||
insert into t1 values (1,null);
|
||||
set timestamp = 1288481126;
|
||||
insert into t1 values (2,null);
|
||||
select pk, t, unix_timestamp(t) from t1;
|
||||
pk t unix_timestamp(t)
|
||||
1 2010-10-30 22:25:26 1288477526
|
||||
2 2010-10-30 23:25:26 1288481126
|
||||
set time_zone=default;
|
||||
select pk, t, unix_timestamp(t) from t1;
|
||||
pk t unix_timestamp(t)
|
||||
1 2010-10-31 02:25:26 1288477526
|
||||
2 2010-10-31 02:25:26 1288481126
|
||||
set global time_zone=default;
|
||||
drop table t1;
|
||||
set global time_zone=default;
|
||||
set global mysql56_temporal_format=default;
|
||||
include/rpl_end.inc
|
@ -0,0 +1,37 @@
|
||||
#
|
||||
# MDEV-12672 Replicated TIMESTAMP fields given wrong value near DST change
|
||||
#
|
||||
source include/have_binlog_format_row.inc;
|
||||
source include/master-slave.inc;
|
||||
|
||||
connection slave;
|
||||
set global time_zone='Europe/Moscow';
|
||||
set time_zone='UTC';
|
||||
stop slave;
|
||||
start slave;
|
||||
|
||||
connection master;
|
||||
set global mysql56_temporal_format=false;
|
||||
set global time_zone='Europe/Moscow';
|
||||
set time_zone='UTC';
|
||||
|
||||
create table t1 (pk int primary key, t timestamp not null);
|
||||
set timestamp = 1288477526;
|
||||
insert into t1 values (1,null);
|
||||
set timestamp = 1288481126;
|
||||
insert into t1 values (2,null);
|
||||
|
||||
sync_slave_with_master;
|
||||
|
||||
select pk, t, unix_timestamp(t) from t1;
|
||||
set time_zone=default;
|
||||
select pk, t, unix_timestamp(t) from t1;
|
||||
|
||||
set global time_zone=default;
|
||||
|
||||
connection master;
|
||||
drop table t1;
|
||||
set global time_zone=default;
|
||||
set global mysql56_temporal_format=default;
|
||||
|
||||
source include/rpl_end.inc;
|
@ -83,3 +83,20 @@ SELECT TO_DAYS(a), TO_DAYS(b) FROM t1;
|
||||
DROP TABLE t1;
|
||||
SET @@global.mysql56_temporal_format=DEFAULT;
|
||||
|
||||
#
|
||||
# MDEV-12672 Replicated TIMESTAMP fields given wrong value near DST change
|
||||
#
|
||||
set time_zone='Europe/Moscow';
|
||||
set global mysql56_temporal_format=false;
|
||||
create table t1 (a timestamp);
|
||||
set timestamp=1288477526;
|
||||
insert t1 values (null);
|
||||
set timestamp=1288481126;
|
||||
insert t1 values (null);
|
||||
select a, unix_timestamp(a) from t1;
|
||||
set global mysql56_temporal_format=true;
|
||||
select a, unix_timestamp(a) from t1;
|
||||
alter table t1 modify a timestamp;
|
||||
select a, unix_timestamp(a) from t1;
|
||||
drop table t1;
|
||||
set time_zone=DEFAULT;
|
||||
|
@ -417,6 +417,18 @@ static void do_field_decimal(Copy_field *copy)
|
||||
}
|
||||
|
||||
|
||||
static void do_field_timestamp(Copy_field *copy)
|
||||
{
|
||||
DBUG_ASSERT(copy->from_field->type() == MYSQL_TYPE_TIMESTAMP);
|
||||
DBUG_ASSERT(copy->to_field->type() == MYSQL_TYPE_TIMESTAMP);
|
||||
ulong sec_part;
|
||||
Field_timestamp *f= static_cast<Field_timestamp*>(copy->from_field);
|
||||
Field_timestamp *t= static_cast<Field_timestamp*>(copy->to_field);
|
||||
my_time_t ts= f->get_timestamp(&sec_part);
|
||||
t->store_TIME(ts, sec_part);
|
||||
}
|
||||
|
||||
|
||||
static void do_field_temporal(Copy_field *copy)
|
||||
{
|
||||
MYSQL_TIME ltime;
|
||||
@ -724,7 +736,9 @@ Copy_field::get_copy_func(Field *to,Field *from)
|
||||
((to->table->in_use->variables.sql_mode &
|
||||
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) &&
|
||||
mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME))
|
||||
return do_field_temporal;
|
||||
return (from->type() == MYSQL_TYPE_TIMESTAMP &&
|
||||
to->type() == MYSQL_TYPE_TIMESTAMP)
|
||||
? do_field_timestamp : do_field_temporal;
|
||||
/* Do binary copy */
|
||||
}
|
||||
// Check if identical fields
|
||||
|
Reference in New Issue
Block a user