Commit 6d6d04a0 authored by dlenev@mysql.com's avatar dlenev@mysql.com

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.
parent b100adf7
...@@ -221,3 +221,12 @@ ts1 ...@@ -221,3 +221,12 @@ ts1
20040101000000 20040101000000
20040101010000 20040101010000
drop table t1; 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;
...@@ -148,3 +148,16 @@ select * from t1; ...@@ -148,3 +148,16 @@ select * from t1;
set new=0; set new=0;
select * from t1; select * from t1;
drop table 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;
...@@ -2505,34 +2505,6 @@ void Field_timestamp::store(const char *from,uint len) ...@@ -2505,34 +2505,6 @@ void Field_timestamp::store(const char *from,uint len)
longstore(ptr,tmp); 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) void Field_timestamp::store(double nr)
{ {
...@@ -2644,7 +2616,7 @@ double Field_timestamp::val_real(void) ...@@ -2644,7 +2616,7 @@ double Field_timestamp::val_real(void)
longlong Field_timestamp::val_int(void) longlong Field_timestamp::val_int(void)
{ {
uint len,pos; uint len, pos, max_int_rep_len;
int part_time; int part_time;
uint32 temp; uint32 temp;
time_t time_arg; time_t time_arg;
...@@ -2665,7 +2637,8 @@ longlong Field_timestamp::val_int(void) ...@@ -2665,7 +2637,8 @@ longlong Field_timestamp::val_int(void)
localtime_r(&time_arg,&tm_tmp); localtime_r(&time_arg,&tm_tmp);
l_time=&tm_tmp; l_time=&tm_tmp;
res=(longlong) 0; 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; bool year_flag=0;
switch (dayord.pos[pos]) { switch (dayord.pos[pos]) {
...@@ -2677,7 +2650,7 @@ longlong Field_timestamp::val_int(void) ...@@ -2677,7 +2650,7 @@ longlong Field_timestamp::val_int(void)
case 5: part_time=l_time->tm_sec; break; case 5: part_time=l_time->tm_sec; break;
default: part_time=0; break; /* purecov: deadcode */ 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+ res=res*(longlong) 10000+(part_time+
((part_time < YY_PART_YEAR) ? 2000 : 1900)); ((part_time < YY_PART_YEAR) ? 2000 : 1900));
......
...@@ -591,7 +591,6 @@ public: ...@@ -591,7 +591,6 @@ public:
longget(tmp,ptr); longget(tmp,ptr);
return tmp; return tmp;
} }
void fill_and_store(char *from,uint len);
bool get_date(TIME *ltime,bool fuzzydate); bool get_date(TIME *ltime,bool fuzzydate);
bool get_time(TIME *ltime); bool get_time(TIME *ltime);
......
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