mirror of
https://github.com/MariaDB/server.git
synced 2026-04-28 11:15:33 +02:00
Backport of TIME->MYSQL_TIME / Y2K fixset
Made year 2000 handling more uniform Removed year 2000 handling out from calc_days() The above removes some bugs in date/datetimes with year between 0 and 200 Now we get a note when we insert a datetime value into a date column For default values to CREATE, don't give errors for warning level NOTE Fixed some compiler failures Added library ws2_32 for windows compilation (needed if we want to compile with IOCP support) Removed duplicate typedef TIME and replaced it with MYSQL_TIME Better (more complete) fix for: Bug#21103 "DATE column not compared as DATE" Fixed properly Bug#18997 "DATE_ADD and DATE_SUB perform year2K autoconversion magic on 4-digit year value" Fixed Bug#23093 "Implicit conversion of 9912101 to date does not match cast(9912101 as date)" include/my_time.h: Removed not used define YY_MAGIC_BELOW Added prototype for year_2000_handling() mysql-test/r/date_formats.result: Updated results (fixed bug in date_format() with year < 99 mysql-test/r/func_sapdb.result: Added more testing of make_date() mysql-test/r/ps_2myisam.result: Now we get a note when we insert a datetime value into a date column mysql-test/r/ps_3innodb.result: Now we get a note when we insert a datetime value into a date column mysql-test/r/ps_4heap.result: Now we get a note when we insert a datetime value into a date column mysql-test/r/ps_5merge.result: Now we get a note when we insert a datetime value into a date column mysql-test/r/ps_7ndb.result: Now we get a note when we insert a datetime value into a date column mysql-test/r/strict.result: zero-year in str_to_date() throws warning in strict mysql-test/r/type_date.result: Added test for date conversions mysql-test/r/type_datetime.result: Added testcase for datetime to date conversion. mysql-test/t/date_formats.test: Added testing of dates < 200 mysql-test/t/func_sapdb.test: More testing of makedate() mysql-test/t/type_date.test: Added test for date conversions mysql-test/t/type_datetime.test: Added testcase for datetime to date conversion sql/field.cc: Give note if we insert a datetime value in a date field Don't give notes if we are doing internal test conversions (like from convert_constant_item()) More documentation (store functions can now return '3' to inform that the function did return a NOTE (not warning or error)) Revert some changes in Field_newdate::store() to get more optimal code Field::set_warning() will now ignore notes if CHECK_FIELD_IGNORE is set. New parameters to make_truncated_value_warning() sql/field.h: Give note if we insert a datetime value in a date field Don't give notes if we are doing internal test conversions (like from convert_constant_item()) More documentation (store functions can now return '3' to inform that the function did return a NOTE (not warning or error)) Revert some changes in Field_newdate::store() to get more optimal code Field::set_warning() will now ignore notes if CHECK_FIELD_IGNORE is set. New parameters to make_truncated_value_warning() sql/item.cc: Give note if we insert a datetime value in a date field Don't give notes if we are doing internal test conversions (like from convert_constant_item()) More documentation (store functions can now return '3' to inform that the function did return a NOTE (not warning or error)) Revert some changes in Field_newdate::store() to get more optimal code Field::set_warning() will now ignore notes if CHECK_FIELD_IGNORE is set. New parameters to make_truncated_value_warning() sql/item.h: TIME -> MYSQL_TIME sql/item_cmpfunc.cc: Don't print notes in convert_constant_item() sql/item_func.h: TIME -> MYSQL_TIME sql/item_timefunc.cc: New parameters to make_truncated_value_warning() Moved year 2000 handling out from calc_days() sql/item_timefunc.h: TIME -> MYSQL_TIME sql/my_decimal.cc: TIME -> MYSQL_TIME sql/my_decimal.h: TIME -> MYSQL_TIME sql/mysql_priv.h: Added error level to make_truncated_value_warning() sql/protocol.cc: TIME -> MYSQL_TIME sql/protocol.h: TIME -> MYSQL_TIME sql/sp.cc: TIME -> MYSQL_TIME sql/sql_base.cc: Make testing of result value of save_in_field() uniform sql/sql_class.h: TIME -> MYSQL_TIME sql/sql_show.cc: TIME -> MYSQL_TIME sql/structs.h: TIME -> MYSQL_TIME sql/time.cc: Added error level to make_truncated_value_warning() sql/tztime.cc: TIME -> MYSQL_TIME sql/tztime.h: TIME -> MYSQL_TIME sql/unireg.cc: For default values to CREATE, don't give errors for warning level NOTE (Fixed failed CREATE when we give a datetime value to a date field) sql-common/my_time.c: Added year_2000_handling() Removed year 2000 handling from calc_daynr()
This commit is contained in:
parent
7703b67659
commit
b5e4f54a53
38 changed files with 622 additions and 335 deletions
|
|
@ -77,7 +77,7 @@ typedef struct lsinfo
|
|||
|
||||
/*
|
||||
Structure with information describing ranges of my_time_t shifted to local
|
||||
time (my_time_t + offset). Used for local TIME -> my_time_t conversion.
|
||||
time (my_time_t + offset). Used for local MYSQL_TIME -> my_time_t conversion.
|
||||
See comments for TIME_to_gmt_sec() for more info.
|
||||
*/
|
||||
typedef struct revtinfo
|
||||
|
|
@ -292,9 +292,9 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
|||
be used if there are no transitions or we have moment in time before
|
||||
any transitions.
|
||||
Second task is to build "shifted my_time_t" -> my_time_t map used in
|
||||
TIME -> my_time_t conversion.
|
||||
MYSQL_TIME -> my_time_t conversion.
|
||||
Note: See description of TIME_to_gmt_sec() function first.
|
||||
In order to perform TIME -> my_time_t conversion we need to build table
|
||||
In order to perform MYSQL_TIME -> my_time_t conversion we need to build table
|
||||
which defines "shifted by tz offset and leap seconds my_time_t" ->
|
||||
my_time_t function wich is almost the same (except ranges of ambiguity)
|
||||
as reverse function to piecewise linear function used for my_time_t ->
|
||||
|
|
@ -531,14 +531,14 @@ static const uint year_lengths[2]=
|
|||
offset - local time zone offset
|
||||
|
||||
DESCRIPTION
|
||||
Convert my_time_t with offset to TIME struct. Differs from timesub
|
||||
Convert my_time_t with offset to MYSQL_TIME struct. Differs from timesub
|
||||
(from elsie code) because doesn't contain any leap correction and
|
||||
TM_GMTOFF and is_dst setting and contains some MySQL specific
|
||||
initialization. Funny but with removing of these we almost have
|
||||
glibc's offtime function.
|
||||
*/
|
||||
static void
|
||||
sec_to_TIME(TIME * tmp, my_time_t t, long offset)
|
||||
sec_to_TIME(MYSQL_TIME * tmp, my_time_t t, long offset)
|
||||
{
|
||||
long days;
|
||||
long rem;
|
||||
|
|
@ -594,7 +594,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset)
|
|||
tmp->month++;
|
||||
tmp->day= (uint)(days + 1);
|
||||
|
||||
/* filling MySQL specific TIME members */
|
||||
/* filling MySQL specific MYSQL_TIME members */
|
||||
tmp->neg= 0; tmp->second_part= 0;
|
||||
tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
|
||||
}
|
||||
|
|
@ -686,7 +686,7 @@ find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp)
|
|||
|
||||
/*
|
||||
Converts time in my_time_t representation (seconds in UTC since Epoch) to
|
||||
broken down TIME representation in local time zone.
|
||||
broken down MYSQL_TIME representation in local time zone.
|
||||
|
||||
SYNOPSIS
|
||||
gmt_sec_to_TIME()
|
||||
|
|
@ -701,12 +701,12 @@ find_transition_type(my_time_t t, const TIME_ZONE_INFO *sp)
|
|||
(60th and 61st second, look how we calculate them as "hit" in this
|
||||
function).
|
||||
Under realistic assumptions about frequency of transitions the same array
|
||||
can be used fot TIME -> my_time_t conversion. For this we need to
|
||||
can be used fot MYSQL_TIME -> my_time_t conversion. For this we need to
|
||||
implement tweaked binary search which will take into account that some
|
||||
TIME has two matching my_time_t ranges and some of them have none.
|
||||
MYSQL_TIME has two matching my_time_t ranges and some of them have none.
|
||||
*/
|
||||
static void
|
||||
gmt_sec_to_TIME(TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
|
||||
gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t sec_in_utc, const TIME_ZONE_INFO *sp)
|
||||
{
|
||||
const TRAN_TYPE_INFO *ttisp;
|
||||
const LS_INFO *lp;
|
||||
|
|
@ -809,7 +809,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
|
|||
|
||||
|
||||
/*
|
||||
Converts local time in broken down TIME representation to my_time_t
|
||||
Converts local time in broken down MYSQL_TIME representation to my_time_t
|
||||
representation.
|
||||
|
||||
SYNOPSIS
|
||||
|
|
@ -851,7 +851,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
|
|||
|
||||
We use completely different approach. It is better since it is both
|
||||
faster than iterative implementations and fully determenistic. If you
|
||||
look at my_time_t to TIME conversion then you'll find that it consist
|
||||
look at my_time_t to MYSQL_TIME conversion then you'll find that it consist
|
||||
of two steps:
|
||||
The first is calculating shifted my_time_t value and the second - TIME
|
||||
calculation from shifted my_time_t value (well it is a bit simplified
|
||||
|
|
@ -881,7 +881,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
|
|||
0 in case of error.
|
||||
*/
|
||||
static my_time_t
|
||||
TIME_to_gmt_sec(const TIME *t, const TIME_ZONE_INFO *sp,
|
||||
TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp,
|
||||
my_bool *in_dst_time_gap)
|
||||
{
|
||||
my_time_t local_t;
|
||||
|
|
@ -1008,20 +1008,20 @@ class Time_zone_system : public Time_zone
|
|||
{
|
||||
public:
|
||||
Time_zone_system() {} /* Remove gcc warning */
|
||||
virtual my_time_t TIME_to_gmt_sec(const TIME *t,
|
||||
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
|
||||
my_bool *in_dst_time_gap) const;
|
||||
virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
|
||||
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
|
||||
virtual const String * get_name() const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Converts local time in system time zone in TIME representation
|
||||
Converts local time in system time zone in MYSQL_TIME representation
|
||||
to its my_time_t representation.
|
||||
|
||||
SYNOPSIS
|
||||
TIME_to_gmt_sec()
|
||||
t - pointer to TIME structure with local time in
|
||||
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
|
||||
|
|
@ -1029,7 +1029,7 @@ public:
|
|||
|
||||
DESCRIPTION
|
||||
This method uses system function (localtime_r()) for conversion
|
||||
local time in system time zone in TIME structure to its my_time_t
|
||||
local time in system time zone in MYSQL_TIME structure to its my_time_t
|
||||
representation. Unlike the same function for Time_zone_db class
|
||||
it it won't handle unnormalized input properly. Still it will
|
||||
return lowest possible my_time_t in case of ambiguity or if we
|
||||
|
|
@ -1041,7 +1041,7 @@ public:
|
|||
Corresponding my_time_t value or 0 in case of error
|
||||
*/
|
||||
my_time_t
|
||||
Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
||||
Time_zone_system::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
|
||||
{
|
||||
long not_used;
|
||||
return my_system_gmt_sec(t, ¬_used, in_dst_time_gap);
|
||||
|
|
@ -1054,7 +1054,7 @@ Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
|||
|
||||
SYNOPSIS
|
||||
gmt_sec_to_TIME()
|
||||
tmp - pointer to TIME structure to fill-in
|
||||
tmp - pointer to MYSQL_TIME structure to fill-in
|
||||
t - my_time_t value to be converted
|
||||
|
||||
NOTE
|
||||
|
|
@ -1065,7 +1065,7 @@ Time_zone_system::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
|||
the 1902 easily.
|
||||
*/
|
||||
void
|
||||
Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
|
||||
Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
|
||||
{
|
||||
struct tm tmp_tm;
|
||||
time_t tmp_t= (time_t)t;
|
||||
|
|
@ -1095,26 +1095,26 @@ Time_zone_system::get_name() const
|
|||
/*
|
||||
Instance of this class represents UTC time zone. It uses system gmtime_r
|
||||
function for conversions and is always available. It is used only for
|
||||
my_time_t -> TIME conversions in various UTC_... functions, it is not
|
||||
intended for TIME -> my_time_t conversions and shouldn't be exposed to user.
|
||||
my_time_t -> MYSQL_TIME conversions in various UTC_... functions, it is not
|
||||
intended for MYSQL_TIME -> my_time_t conversions and shouldn't be exposed to user.
|
||||
*/
|
||||
class Time_zone_utc : public Time_zone
|
||||
{
|
||||
public:
|
||||
Time_zone_utc() {} /* Remove gcc warning */
|
||||
virtual my_time_t TIME_to_gmt_sec(const TIME *t,
|
||||
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
|
||||
my_bool *in_dst_time_gap) const;
|
||||
virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
|
||||
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
|
||||
virtual const String * get_name() const;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Convert UTC time from TIME representation to its my_time_t representation.
|
||||
Convert UTC time from MYSQL_TIME representation to its my_time_t representation.
|
||||
|
||||
SYNOPSIS
|
||||
TIME_to_gmt_sec()
|
||||
t - pointer to TIME structure with local time
|
||||
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
|
||||
|
|
@ -1129,7 +1129,7 @@ public:
|
|||
0
|
||||
*/
|
||||
my_time_t
|
||||
Time_zone_utc::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
||||
Time_zone_utc::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
|
||||
{
|
||||
/* Should be never called */
|
||||
DBUG_ASSERT(0);
|
||||
|
|
@ -1143,14 +1143,14 @@ Time_zone_utc::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
|||
|
||||
SYNOPSIS
|
||||
gmt_sec_to_TIME()
|
||||
tmp - pointer to TIME structure to fill-in
|
||||
tmp - pointer to MYSQL_TIME structure to fill-in
|
||||
t - my_time_t value to be converted
|
||||
|
||||
NOTE
|
||||
See note for apropriate Time_zone_system method.
|
||||
*/
|
||||
void
|
||||
Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
|
||||
Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
|
||||
{
|
||||
struct tm tmp_tm;
|
||||
time_t tmp_t= (time_t)t;
|
||||
|
|
@ -1191,9 +1191,9 @@ 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 TIME *t,
|
||||
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
|
||||
my_bool *in_dst_time_gap) const;
|
||||
virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
|
||||
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
|
||||
virtual const String * get_name() const;
|
||||
private:
|
||||
TIME_ZONE_INFO *tz_info;
|
||||
|
|
@ -1227,7 +1227,7 @@ Time_zone_db::Time_zone_db(TIME_ZONE_INFO *tz_info_arg,
|
|||
|
||||
SYNOPSIS
|
||||
TIME_to_gmt_sec()
|
||||
t - pointer to TIME structure with local time
|
||||
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
|
||||
|
|
@ -1241,7 +1241,7 @@ 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 TIME *t, my_bool *in_dst_time_gap) const
|
||||
Time_zone_db::TIME_to_gmt_sec(const MYSQL_TIME *t, my_bool *in_dst_time_gap) const
|
||||
{
|
||||
return ::TIME_to_gmt_sec(t, tz_info, in_dst_time_gap);
|
||||
}
|
||||
|
|
@ -1253,11 +1253,11 @@ Time_zone_db::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
|||
|
||||
SYNOPSIS
|
||||
gmt_sec_to_TIME()
|
||||
tmp - pointer to TIME structure to fill-in
|
||||
tmp - pointer to MYSQL_TIME structure to fill-in
|
||||
t - my_time_t value to be converted
|
||||
*/
|
||||
void
|
||||
Time_zone_db::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
|
||||
Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
|
||||
{
|
||||
::gmt_sec_to_TIME(tmp, t, tz_info);
|
||||
}
|
||||
|
|
@ -1287,9 +1287,9 @@ class Time_zone_offset : public Time_zone
|
|||
{
|
||||
public:
|
||||
Time_zone_offset(long tz_offset_arg);
|
||||
virtual my_time_t TIME_to_gmt_sec(const TIME *t,
|
||||
virtual my_time_t TIME_to_gmt_sec(const MYSQL_TIME *t,
|
||||
my_bool *in_dst_time_gap) const;
|
||||
virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
|
||||
virtual void gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const;
|
||||
virtual const String * get_name() const;
|
||||
/*
|
||||
This have to be public because we want to be able to access it from
|
||||
|
|
@ -1324,11 +1324,11 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
|
|||
|
||||
/*
|
||||
Converts local time in time zone described as offset from UTC
|
||||
from TIME representation to its my_time_t representation.
|
||||
from MYSQL_TIME representation to its my_time_t representation.
|
||||
|
||||
SYNOPSIS
|
||||
TIME_to_gmt_sec()
|
||||
t - pointer to TIME structure with local time
|
||||
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
|
||||
|
|
@ -1340,7 +1340,7 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
|
|||
Corresponding my_time_t value or 0 in case of error
|
||||
*/
|
||||
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 MYSQL_TIME *t, my_bool *in_dst_time_gap) const
|
||||
{
|
||||
my_time_t local_t;
|
||||
int shift= 0;
|
||||
|
|
@ -1385,11 +1385,11 @@ Time_zone_offset::TIME_to_gmt_sec(const TIME *t, my_bool *in_dst_time_gap) const
|
|||
|
||||
SYNOPSIS
|
||||
gmt_sec_to_TIME()
|
||||
tmp - pointer to TIME structure to fill-in
|
||||
tmp - pointer to MYSQL_TIME structure to fill-in
|
||||
t - my_time_t value to be converted
|
||||
*/
|
||||
void
|
||||
Time_zone_offset::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const
|
||||
Time_zone_offset::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
|
||||
{
|
||||
sec_to_TIME(tmp, t, offset);
|
||||
}
|
||||
|
|
@ -2651,7 +2651,7 @@ main(int argc, char **argv)
|
|||
my_bool localtime_negative;
|
||||
TIME_ZONE_INFO tz_info;
|
||||
struct tm tmp;
|
||||
TIME time_tmp;
|
||||
MYSQL_TIME time_tmp;
|
||||
time_t t, t1, t2;
|
||||
char fullname[FN_REFLEN+1];
|
||||
char *str_end;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue