mirror of
https://github.com/MariaDB/server.git
synced 2025-07-26 07:02:12 +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
|
Warning 1264 Out of range value for column 'b' at row 1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET @@global.mysql56_temporal_format=DEFAULT;
|
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;
|
DROP TABLE t1;
|
||||||
SET @@global.mysql56_temporal_format=DEFAULT;
|
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)
|
static void do_field_temporal(Copy_field *copy)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
@ -724,7 +736,9 @@ Copy_field::get_copy_func(Field *to,Field *from)
|
|||||||
((to->table->in_use->variables.sql_mode &
|
((to->table->in_use->variables.sql_mode &
|
||||||
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) &&
|
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)) &&
|
||||||
mysql_type_to_time_type(to->type()) != MYSQL_TIMESTAMP_TIME))
|
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 */
|
/* Do binary copy */
|
||||||
}
|
}
|
||||||
// Check if identical fields
|
// Check if identical fields
|
||||||
|
Reference in New Issue
Block a user