summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/old-mode.result22
-rw-r--r--mysql-test/t/old-mode.test17
-rw-r--r--sql/field.cc17
-rw-r--r--sql/field.h1
-rw-r--r--sql/field_conv.cc19
5 files changed, 69 insertions, 7 deletions
diff --git a/mysql-test/r/old-mode.result b/mysql-test/r/old-mode.result
index 398e719cf02..b9a3edd4e94 100644
--- a/mysql-test/r/old-mode.result
+++ b/mysql-test/r/old-mode.result
@@ -149,4 +149,26 @@ a unix_timestamp(a)
2010-10-31 02:25:26 1288477526
2010-10-31 02:25:26 1288481126
drop table t1;
+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
+create table t2 (a timestamp);
+insert t2 select a from t1;
+select a, unix_timestamp(a) from t2;
+a unix_timestamp(a)
+2010-10-31 02:25:26 1288477526
+2010-10-31 02:25:26 1288481126
+drop table t1, t2;
set time_zone=DEFAULT;
diff --git a/mysql-test/t/old-mode.test b/mysql-test/t/old-mode.test
index 99c92f8093d..ed33da523c7 100644
--- a/mysql-test/t/old-mode.test
+++ b/mysql-test/t/old-mode.test
@@ -86,6 +86,8 @@ SET @@global.mysql56_temporal_format=DEFAULT;
#
# MDEV-12672 Replicated TIMESTAMP fields given wrong value near DST change
#
+
+# Copy_field
set time_zone='Europe/Moscow';
set global mysql56_temporal_format=false;
create table t1 (a timestamp);
@@ -99,4 +101,19 @@ select a, unix_timestamp(a) from t1;
alter table t1 modify a timestamp;
select a, unix_timestamp(a) from t1;
drop table t1;
+
+# field_conv_incompatible()
+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;
+create table t2 (a timestamp);
+insert t2 select a from t1;
+select a, unix_timestamp(a) from t2;
+drop table t1, t2;
set time_zone=DEFAULT;
diff --git a/sql/field.cc b/sql/field.cc
index 8eb37c56c7e..6a28b38a612 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5064,6 +5064,23 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
}
+int Field_timestamp::store_timestamp(Field_timestamp *from)
+{
+ ulong sec_part;
+ my_time_t ts= from->get_timestamp(&sec_part);
+ store_TIME(ts, sec_part);
+ if (!ts && !sec_part && get_thd()->variables.sql_mode & MODE_NO_ZERO_DATE)
+ {
+ ErrConvString s(
+ STRING_WITH_LEN("0000-00-00 00:00:00.000000") - (decimals() ? 6 - decimals() : 7),
+ system_charset_info);
+ set_datetime_warning(WARN_DATA_TRUNCATED, &s, MYSQL_TIMESTAMP_DATETIME, 1);
+ return 1;
+ }
+ return 0;
+}
+
+
double Field_timestamp::val_real(void)
{
return (double) Field_timestamp::val_int();
diff --git a/sql/field.h b/sql/field.h
index 30f24ecc1bb..154037df767 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -2186,6 +2186,7 @@ public:
int store(longlong nr, bool unsigned_val);
int store_time_dec(MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
+ int store_timestamp(Field_timestamp *from);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 74c5fb5b502..850403afb97 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -219,6 +219,13 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions)
}
+static int copy_timestamp_fields(Field *from, Field *to)
+{
+ DBUG_ASSERT(from->type() == MYSQL_TYPE_TIMESTAMP);
+ DBUG_ASSERT(to->type() == MYSQL_TYPE_TIMESTAMP);
+ return ((Field_timestamp*)to)->store_timestamp((Field_timestamp*)from);
+}
+
static void do_skip(Copy_field *copy __attribute__((unused)))
{
}
@@ -419,13 +426,7 @@ 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);
+ copy_timestamp_fields(copy->from_field, copy->to_field);
}
@@ -938,6 +939,10 @@ int field_conv_incompatible(Field *to, Field *from)
my_decimal buff;
return to->store_decimal(from->val_decimal(&buff));
}
+ if (from->type() == MYSQL_TYPE_TIMESTAMP && to->type() == MYSQL_TYPE_TIMESTAMP)
+ {
+ return copy_timestamp_fields(from, to);
+ }
if (from->cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;