Commit 22f6c58b authored by unknown's avatar unknown
Browse files

Fix for bug #8894 "TIMESTAMP values scrambled/misaligned when using --new".

Fixed Field_timestamp::val_int() so now it works correctly in --new mode
(or for TIMESTAMP(19) columns). 
Also removed unused Field_timestamp::fill_and_store() method.


mysql-test/r/type_timestamp.result:
  Added test for bug #8894 "TIMESTAMP values scrambled/misaligned when 
  using --new".
mysql-test/t/type_timestamp.test:
  Added test for bug #8894 "TIMESTAMP values scrambled/misaligned when 
  using --new".
sql/field.cc:
  Field_timestamp::fill_and_store() 
    Removed unused method.
  Field_timestamp::val_int()
    Even in --new mode integer representation of TIMESTAMP value should
    not exceed 14 digits.
sql/field.h:
  Removed unused Field_timestamp::fill_and_store() method.
parent 606ee28d
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -221,3 +221,12 @@ ts1
20040101000000
20040101010000
drop table t1;
create table t1 (ts timestamp);
set TIMESTAMP=1000000000;
insert into t1 values ();
set new=1;
select ts+0 from t1;
ts+0
20010909044640
set new=0;
drop table t1;
+13 −0
Original line number Diff line number Diff line
@@ -148,3 +148,16 @@ select * from t1;
set new=0;
select * from t1;
drop table t1;

#
# Test for bug #8894 "TIMESTAMP values scrambled/misaligned when using
# --new". TIMESTAMP columns should have correct values when they are used in
# integer context in --new mode.
#
create table t1 (ts timestamp);
set TIMESTAMP=1000000000;
insert into t1 values ();
set new=1;
select ts+0 from t1;
set new=0;
drop table t1;
+4 −31
Original line number Diff line number Diff line
@@ -2505,34 +2505,6 @@ void Field_timestamp::store(const char *from,uint len)
    longstore(ptr,tmp);
}

void Field_timestamp::fill_and_store(char *from,uint len)
{
  uint res_length;
  if (len <= field_length)
    res_length=field_length;
  else if (len <= 12)
    res_length=12;				/* purecov: inspected */
  else if (len <= 14)
    res_length=14;				/* purecov: inspected */
  else
    res_length=(len+1)/2*2;			// must be even
  if (res_length != len)
  {
    bmove_upp(from+res_length,from+len,len);
    bfill(from,res_length-len,'0');
    len=res_length;
  }
  long tmp=(long) str_to_timestamp(from,len);
#ifdef WORDS_BIGENDIAN
  if (table->db_low_byte_first)
  {
    int4store(ptr,tmp);
  }
  else
#endif
    longstore(ptr,tmp);
}


void Field_timestamp::store(double nr)
{
@@ -2644,7 +2616,7 @@ double Field_timestamp::val_real(void)

longlong Field_timestamp::val_int(void)
{
  uint len,pos;
  uint len, pos, max_int_rep_len;
  int part_time;
  uint32 temp;
  time_t time_arg;
@@ -2665,7 +2637,8 @@ longlong Field_timestamp::val_int(void)
  localtime_r(&time_arg,&tm_tmp);
  l_time=&tm_tmp;
  res=(longlong) 0;
  for (pos=len=0; len+1 < (uint) field_length ; len+=2,pos++)
  max_int_rep_len= min(field_length, 14);
  for (pos= len= 0; len+1 < max_int_rep_len ; len+= 2,pos++)
  {
    bool year_flag=0;
    switch (dayord.pos[pos]) {
@@ -2677,7 +2650,7 @@ longlong Field_timestamp::val_int(void)
    case 5: part_time=l_time->tm_sec; break;
    default: part_time=0; break; /* purecov: deadcode */
    }
    if (year_flag && (field_length == 8 || field_length == 14))
    if (year_flag && (max_int_rep_len == 8 || max_int_rep_len == 14))
    {
      res=res*(longlong) 10000+(part_time+
				((part_time < YY_PART_YEAR) ? 2000 : 1900));
+0 −1
Original line number Diff line number Diff line
@@ -591,7 +591,6 @@ class Field_timestamp :public Field_num {
    longget(tmp,ptr);
    return tmp;
  }
  void fill_and_store(char *from,uint len);
  bool get_date(TIME *ltime,bool fuzzydate);
  bool get_time(TIME *ltime);