summaryrefslogtreecommitdiff
path: root/sql/field_conv.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2017-09-19 11:18:45 +0200
committerSergei Golubchik <serg@mariadb.org>2017-09-21 22:03:21 +0200
commitf4f48e06215fe6717865ccbe27ddc388a2cb86b8 (patch)
treec4128f9caa12333de890e338a609f8bbe6f897fb /sql/field_conv.cc
parent46a2917c0fd287755d9e357a98d04ed2c8b1ba0a (diff)
downloadmariadb-git-f4f48e06215fe6717865ccbe27ddc388a2cb86b8.tar.gz
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).
Diffstat (limited to 'sql/field_conv.cc')
-rw-r--r--sql/field_conv.cc16
1 files changed, 15 insertions, 1 deletions
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 7b57c7da104..74c5fb5b502 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -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