Skip to content

Commit

Permalink
bugfix: ALTER TABLE and TIMESTAMPs around DST change time
Browse files Browse the repository at this point in the history
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 f4f48e0
  • Loading branch information
vuvova committed Sep 22, 2017
1 parent bc4409a commit a5e1f60
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
2 changes: 2 additions & 0 deletions sql/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ class Field: public Value_source
static void do_field_real(Copy_field *copy);
static void do_field_string(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);
public:
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
Expand Down Expand Up @@ -2388,6 +2389,7 @@ class Field_timestamp :public Field_temporal {
TABLE_SHARE *share);
enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
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(double nr);
int store(longlong nr, bool unsigned_val);
Expand Down
20 changes: 20 additions & 0 deletions sql/field_conv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
MYSQL_TIME ltime;
Expand Down Expand Up @@ -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
{
/* If types are not 100 % identical then convert trough get_date() */
Expand Down

0 comments on commit a5e1f60

Please sign in to comment.