Commit a5e1f60b authored by Sergei Golubchik's avatar Sergei Golubchik

bugfix: ALTER TABLE and TIMESTAMPs around DST change time

Implement a special Copy_func function for timestamps, that copies
timestamps without converting them to MYSQL_TIME (the conversion is
lossy around DST change time).

This fixes ALTER TABLE part of main.old-mode test.

This is 10.2 version of f4f48e06
parent bc4409ab
...@@ -699,6 +699,7 @@ class Field: public Value_source ...@@ -699,6 +699,7 @@ class Field: public Value_source
static void do_field_real(Copy_field *copy); static void do_field_real(Copy_field *copy);
static void do_field_string(Copy_field *copy); static void do_field_string(Copy_field *copy);
static void do_field_temporal(Copy_field *copy); static void do_field_temporal(Copy_field *copy);
static void do_field_timestamp(Copy_field *copy);
static void do_field_decimal(Copy_field *copy); static void do_field_decimal(Copy_field *copy);
public: public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw () static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
...@@ -2388,6 +2389,7 @@ class Field_timestamp :public Field_temporal { ...@@ -2388,6 +2389,7 @@ class Field_timestamp :public Field_temporal {
TABLE_SHARE *share); TABLE_SHARE *share);
enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;} enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
Copy_func *get_copy_func(const Field *from) const;
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
int store(longlong nr, bool unsigned_val); int store(longlong nr, bool unsigned_val);
......
...@@ -417,6 +417,16 @@ void Field::do_field_decimal(Copy_field *copy) ...@@ -417,6 +417,16 @@ void Field::do_field_decimal(Copy_field *copy)
} }
void Field::do_field_timestamp(Copy_field *copy)
{
Field_timestamp *f= static_cast<Field_timestamp*>(copy->from_field);
Field_timestamp *t= static_cast<Field_timestamp*>(copy->to_field);
ulong sec_part;
my_time_t ts= f->get_timestamp(&sec_part);
t->store_TIME(ts, sec_part);
}
void Field::do_field_temporal(Copy_field *copy) void Field::do_field_temporal(Copy_field *copy)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
...@@ -706,6 +716,16 @@ void Copy_field::set(Field *to,Field *from,bool save) ...@@ -706,6 +716,16 @@ void Copy_field::set(Field *to,Field *from,bool save)
} }
Field::Copy_func *Field_timestamp::get_copy_func(const Field *from) const
{
Field::Copy_func *copy= Field_temporal::get_copy_func(from);
if (copy == do_field_temporal && from->type() == MYSQL_TYPE_TIMESTAMP)
return do_field_timestamp;
else
return copy;
}
Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
{ {
/* If types are not 100 % identical then convert trough get_date() */ /* If types are not 100 % identical then convert trough get_date() */
......
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