Commit b4d06c0d authored by msvensson@pilot.blaudden's avatar msvensson@pilot.blaudden

Merge pilot.blaudden:/home/msvensson/mysql/bug26536/my50-bug26536

into  pilot.blaudden:/home/msvensson/mysql/bug26536/my51-bug26536
parents 5ba46a56 7e292b9a
...@@ -30,7 +30,13 @@ extern uchar days_in_month[]; ...@@ -30,7 +30,13 @@ extern uchar days_in_month[];
/* /*
Portable time_t replacement. Portable time_t replacement.
Should be signed and hold seconds for 1902-2038 range. Should be signed and hold seconds for 1902 -- 2038-01-19 range
i.e at least a 32bit variable
Using the system built in time_t is not an option as
we rely on the above requirements in the time functions
For example QNX has an unsigned time_t type
*/ */
#if defined(_WIN64) || defined(WIN64) #if defined(_WIN64) || defined(WIN64)
/* on Win64 long is still 4 bytes (not 8!) */ /* on Win64 long is still 4 bytes (not 8!) */
......
...@@ -780,6 +780,8 @@ gmt_sec_to_TIME(TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp) ...@@ -780,6 +780,8 @@ gmt_sec_to_TIME(TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
static my_time_t static my_time_t
sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
{ {
/* Guard against my_time_t overflow(on system with 32 bit my_time_t) */
DBUG_ASSERT(!(year == TIMESTAMP_MAX_YEAR && mon == 1 && mday > 17));
#ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES #ifndef WE_WANT_TO_HANDLE_UNORMALIZED_DATES
/* /*
It turns out that only whenever month is normalized or unnormalized It turns out that only whenever month is normalized or unnormalized
...@@ -960,12 +962,12 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp, ...@@ -960,12 +962,12 @@ TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
*/ */
if (shift) if (shift)
{ {
if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift*86400L + if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY +
sp->revtis[i].rt_offset - saved_seconds)) sp->revtis[i].rt_offset - saved_seconds))
{ {
DBUG_RETURN(0); /* my_time_t overflow */ DBUG_RETURN(0); /* my_time_t overflow */
} }
local_t+= shift*86400L; local_t+= shift * SECS_PER_DAY;
} }
if (sp->revtis[i].rt_type) if (sp->revtis[i].rt_type)
...@@ -1353,6 +1355,7 @@ my_time_t ...@@ -1353,6 +1355,7 @@ my_time_t
Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
{ {
my_time_t local_t; my_time_t local_t;
int shift= 0;
/* /*
Check timestamp range.we have to do this as calling function relies on Check timestamp range.we have to do this as calling function relies on
...@@ -1361,10 +1364,24 @@ Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const ...@@ -1361,10 +1364,24 @@ Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
if (!validate_timestamp_range(t)) if (!validate_timestamp_range(t))
return 0; return 0;
local_t= sec_since_epoch(t->year, t->month, t->day, /*
Do a temporary shift of the boundary dates to avoid
overflow of my_time_t if the time value is near it's
maximum range
*/
if ((t->year == TIMESTAMP_MAX_YEAR) && (t->month == 1) && t->day > 4)
shift= 2;
local_t= sec_since_epoch(t->year, t->month, (t->day - shift),
t->hour, t->minute, t->second) - t->hour, t->minute, t->second) -
offset; offset;
if (shift)
{
/* Add back the shifted time */
local_t+= shift * SECS_PER_DAY;
}
if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE) if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
return local_t; return local_t;
......
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