diff options
Diffstat (limited to 'sql/tztime.cc')
-rw-r--r-- | sql/tztime.cc | 92 |
1 files changed, 52 insertions, 40 deletions
diff --git a/sql/tztime.cc b/sql/tztime.cc index 678483e1c14..bb0608cc3bd 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -815,9 +815,11 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) TIME_to_gmt_sec() t - pointer to structure for broken down represenatation sp - pointer to struct with time zone description - in_dst_time_gap - pointer to bool which is set to true if datetime - value passed doesn't really exist (i.e. falls into - spring time-gap) and is not touched otherwise. + error_code - 0, if the conversion was successful; + ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value + which is out of TIMESTAMP range; + ER_WARN_INVALID_TIMESTAMP, if t represents value which + doesn't exists (falls into the spring time-gap). DESCRIPTION This is mktime analog for MySQL. It is essentially different @@ -879,20 +881,23 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec) Seconds in UTC since Epoch. 0 in case of error. */ + static my_time_t -TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, - my_bool *in_dst_time_gap) +TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code) { my_time_t local_t; uint saved_seconds; uint i; int shift= 0; - DBUG_ENTER("TIME_to_gmt_sec"); if (!validate_timestamp_range(t)) + { + *error_code= ER_WARN_DATA_OUT_OF_RANGE; DBUG_RETURN(0); + } + *error_code= 0; /* We need this for correct leap seconds handling */ if (t->second < SECS_PER_MIN) @@ -936,6 +941,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, This means that source time can't be represented as my_time_t due to limited my_time_t range. */ + *error_code= ER_WARN_DATA_OUT_OF_RANGE; DBUG_RETURN(0); } @@ -952,6 +958,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, if (local_t > (my_time_t) (TIMESTAMP_MAX_VALUE - shift * SECS_PER_DAY + sp->revtis[i].rt_offset - saved_seconds)) { + *error_code= ER_WARN_DATA_OUT_OF_RANGE; DBUG_RETURN(0); /* my_time_t overflow */ } local_t+= shift * SECS_PER_DAY; @@ -965,7 +972,7 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, Now we are returning my_time_t value corresponding to the beginning of the gap. */ - *in_dst_time_gap= 1; + *error_code= ER_WARN_INVALID_TIMESTAMP; local_t= sp->revts[i] - sp->revtis[i].rt_offset + saved_seconds; } else @@ -973,7 +980,10 @@ TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, /* check for TIMESTAMP_MAX_VALUE was already done above */ if (local_t < TIMESTAMP_MIN_VALUE) + { local_t= 0; + *error_code= ER_WARN_DATA_OUT_OF_RANGE; + } DBUG_RETURN(local_t); } @@ -1007,8 +1017,7 @@ class Time_zone_system : public Time_zone { public: Time_zone_system() {} /* Remove gcc warning */ - virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, - my_bool *in_dst_time_gap) const; + virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const; virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; }; @@ -1022,9 +1031,11 @@ public: TIME_to_gmt_sec() t - pointer to MYSQL_TIME structure with local time in broken-down representation. - in_dst_time_gap - pointer to bool which is set to true if datetime - value passed doesn't really exist (i.e. falls into - spring time-gap) and is not touched otherwise. + error_code - 0, if the conversion was successful; + ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value + which is out of TIMESTAMP range; + ER_WARN_INVALID_TIMESTAMP, if t represents value which + doesn't exists (falls into the spring time-gap). DESCRIPTION This method uses system function (localtime_r()) for conversion @@ -1040,10 +1051,10 @@ public: Corresponding my_time_t value or 0 in case of error */ my_time_t -Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const +Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const { long not_used; - return my_system_gmt_sec(t, ¬_used, in_dst_time_gap); + return my_system_gmt_sec(t, ¬_used, error_code); } @@ -1103,7 +1114,7 @@ class Time_zone_utc : public Time_zone public: Time_zone_utc() {} /* Remove gcc warning */ virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, - my_bool *in_dst_time_gap) const; + uint *error_code) const; virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; }; @@ -1112,14 +1123,6 @@ public: /* Convert UTC time from MYSQL_TIME representation to its my_time_t representation. - SYNOPSIS - TIME_to_gmt_sec() - t - pointer to MYSQL_TIME structure with local time - in broken-down representation. - in_dst_time_gap - pointer to bool which is set to true if datetime - value passed doesn't really exist (i.e. falls into - spring time-gap) and is not touched otherwise. - DESCRIPTION Since Time_zone_utc is used only internally for my_time_t -> TIME conversions, this function of Time_zone interface is not implemented for @@ -1129,10 +1132,11 @@ public: 0 */ my_time_t -Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const +Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const { /* Should be never called */ DBUG_ASSERT(0); + *error_code= ER_WARN_DATA_OUT_OF_RANGE; return 0; } @@ -1192,8 +1196,7 @@ class Time_zone_db : public Time_zone { public: Time_zone_db(TIME_ZONE_INFO *tz_info_arg, const String * tz_name_arg); - virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, - my_bool *in_dst_time_gap) const; + virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const; virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; private: @@ -1230,9 +1233,11 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg, TIME_to_gmt_sec() t - pointer to MYSQL_TIME structure with local time in broken-down representation. - in_dst_time_gap - pointer to bool which is set to true if datetime - value passed doesn't really exist (i.e. falls into - spring time-gap) and is not touched otherwise. + error_code - 0, if the conversion was successful; + ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value + which is out of TIMESTAMP range; + ER_WARN_INVALID_TIMESTAMP, if t represents value which + doesn't exists (falls into the spring time-gap). DESCRIPTION Please see ::TIME_to_gmt_sec for function description and @@ -1242,9 +1247,9 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg, Corresponding my_time_t value or 0 in case of error */ my_time_t -Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const +Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const { - return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap); + return ::TIME_to_gmt_sec(t, tz_info, error_code); } @@ -1290,7 +1295,7 @@ class Time_zone_offset : public Time_zone public: Time_zone_offset(long tz_offset_arg); virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t, - my_bool *in_dst_time_gap) const; + uint *error_code) const; virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const; virtual const String * get_name() const; /* @@ -1332,17 +1337,19 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg): TIME_to_gmt_sec() t - pointer to MYSQL_TIME structure with local time in broken-down representation. - in_dst_time_gap - pointer to bool which should be set to true if - datetime value passed doesn't really exist - (i.e. falls into spring time-gap) and is not - touched otherwise. - It is not really used in this class. + error_code - 0, if the conversion was successful; + ER_WARN_DATA_OUT_OF_RANGE, if t contains datetime value + which is out of TIMESTAMP range; + ER_WARN_INVALID_TIMESTAMP, if t represents value which + doesn't exists (falls into the spring time-gap). RETURN VALUE - Corresponding my_time_t value or 0 in case of error + Corresponding my_time_t value or 0 in case of error. In case of error + *in_dst_time_gap is also set. */ + my_time_t -Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const +Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const { my_time_t local_t; int shift= 0; @@ -1352,7 +1359,11 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) us to make all validation checks here. */ if (!validate_timestamp_range(t)) + { + *error_code= ER_WARN_DATA_OUT_OF_RANGE; return 0; + } + *error_code= 0; /* Do a temporary shift of the boundary dates to avoid @@ -1376,6 +1387,7 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) return local_t; /* range error*/ + *error_code= ER_WARN_DATA_OUT_OF_RANGE; return 0; } @@ -2743,7 +2755,7 @@ main(int argc, char **argv) for (time_tmp.second=0; time_tmp.second<60; time_tmp.second+=25) { long not_used; - my_bool not_used_2; + uint not_used_2; t= (time_t)my_system_gmt_sec(&time_tmp, ¬_used, ¬_used_2); t1= (time_t)TIME_to_gmt_sec(&time_tmp, &tz_info, ¬_used_2); if (t != t1) |