Loading include/my_time.h +13 −1 Original line number Diff line number Diff line Loading @@ -44,12 +44,24 @@ typedef long my_time_t; #define TIME_FUZZY_DATE 1 #define TIME_DATETIME_ONLY 2 #define MYSQL_TIME_WARN_TRUNCATED 1 #define MYSQL_TIME_WARN_OUT_OF_RANGE 2 /* Limits for the TIME data type */ #define TIME_MAX_HOUR 838 #define TIME_MAX_MINUTE 59 #define TIME_MAX_SECOND 59 #define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \ TIME_MAX_SECOND) enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, uint flags, int *was_cut); bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time, int *was_cut); int *warning); int check_time_range(struct st_mysql_time *time, int *warning); long calc_daynr(uint year,uint month,uint day); Loading mysql-test/r/func_sapdb.result +11 −4 Original line number Diff line number Diff line Loading @@ -97,7 +97,9 @@ subtime("02:01:01.999999", "01:01:01.999999") 01:00:00.000000 select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002"); timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002") 8807:59:59.999999 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '8807:59:59.999999' select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 Loading Loading @@ -208,13 +210,16 @@ NULL NULL SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test; ttt qqq -744:00:00 NULL 26305:01:02 22:58:58 -26305:01:02 -22:58:58 838:59:59 22:58:58 -838:59:59 -22:58:58 NULL 26:02:02 00:00:00 -26:02:02 NULL NULL NULL NULL 00:00:00 -24:00:00 Warnings: Warning 1292 Truncated incorrect time value: '26305:01:02' Warning 1292 Truncated incorrect time value: '-26305:01:02' drop table t1, test; select addtime("-01:01:01.01", "-23:59:59.1") as a; a Loading @@ -224,7 +229,9 @@ a 10000 select microsecond(19971231235959.01) as a; a 10000 0 Warnings: Warning 1292 Truncated incorrect time value: '19971231235959.01' select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a; a 1997-12-31 00:00:10.090000 Loading mysql-test/r/func_time.result +90 −1 Original line number Diff line number Diff line Loading @@ -330,7 +330,9 @@ extract(DAY_MINUTE FROM "02 10:11:12") 21011 select extract(DAY_SECOND FROM "225 10:11:12"); extract(DAY_SECOND FROM "225 10:11:12") 225101112 8385959 Warnings: Warning 1292 Truncated incorrect time value: '225 10:11:12' select extract(HOUR FROM "1999-01-02 10:11:12"); extract(HOUR FROM "1999-01-02 10:11:12") 10 Loading Loading @@ -694,6 +696,93 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; SELECT SEC_TO_TIME(3300000); SEC_TO_TIME(3300000) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '3300000' SELECT SEC_TO_TIME(3300000)+0; SEC_TO_TIME(3300000)+0 8385959.000000 Warnings: Warning 1292 Truncated incorrect time value: '3300000' SELECT SEC_TO_TIME(3600 * 4294967296); SEC_TO_TIME(3600 * 4294967296) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '15461882265600' SELECT TIME_TO_SEC('916:40:00'); TIME_TO_SEC('916:40:00') 3020399 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' SELECT ADDTIME('500:00:00', '416:40:00'); ADDTIME('500:00:00', '416:40:00') 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' SELECT ADDTIME('916:40:00', '416:40:00'); ADDTIME('916:40:00', '416:40:00') 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' Warning 1292 Truncated incorrect time value: '1255:39:59' SELECT SUBTIME('916:40:00', '416:40:00'); SUBTIME('916:40:00', '416:40:00') 422:19:59 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' SELECT SUBTIME('-916:40:00', '416:40:00'); SUBTIME('-916:40:00', '416:40:00') -838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '-916:40:00' Warning 1292 Truncated incorrect time value: '-1255:39:59' SELECT MAKETIME(916,0,0); MAKETIME(916,0,0) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '916:00:00' SELECT MAKETIME(4294967296, 0, 0); MAKETIME(4294967296, 0, 0) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '4294967296:00:00' SELECT MAKETIME(-4294967296, 0, 0); MAKETIME(-4294967296, 0, 0) -838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '-4294967296:00:00' SELECT MAKETIME(0, 4294967296, 0); MAKETIME(0, 4294967296, 0) NULL SELECT MAKETIME(0, 0, 4294967296); MAKETIME(0, 0, 4294967296) NULL SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); MAKETIME(CAST(-1 AS UNSIGNED), 0, 0) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00' SELECT EXTRACT(HOUR FROM '100000:02:03'); EXTRACT(HOUR FROM '100000:02:03') 838 Warnings: Warning 1292 Truncated incorrect time value: '100000:02:03' CREATE TABLE t1(f1 TIME); INSERT INTO t1 VALUES('916:00:00 a'); Warnings: Warning 1265 Data truncated for column 'f1' at row 1 Warning 1264 Data truncated; out of range for column 'f1' at row 1 SELECT * FROM t1; f1 838:59:59 DROP TABLE t1; SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); SEC_TO_TIME(CAST(-1 AS UNSIGNED)) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '18446744073709551615' SET NAMES latin1; SET character_set_results = NULL; SHOW VARIABLES LIKE 'character_set_results'; Loading mysql-test/t/func_time.test +41 −0 Original line number Diff line number Diff line Loading @@ -369,6 +369,47 @@ show create table t1; drop table t1; # # Bug #11655: Wrong time is returning from nested selects - maximum time exists # # check if SEC_TO_TIME() handles out-of-range values correctly SELECT SEC_TO_TIME(3300000); SELECT SEC_TO_TIME(3300000)+0; SELECT SEC_TO_TIME(3600 * 4294967296); # check if TIME_TO_SEC() handles out-of-range values correctly SELECT TIME_TO_SEC('916:40:00'); # check if ADDTIME() handles out-of-range values correctly SELECT ADDTIME('500:00:00', '416:40:00'); SELECT ADDTIME('916:40:00', '416:40:00'); # check if SUBTIME() handles out-of-range values correctly SELECT SUBTIME('916:40:00', '416:40:00'); SELECT SUBTIME('-916:40:00', '416:40:00'); # check if MAKETIME() handles out-of-range values correctly SELECT MAKETIME(916,0,0); SELECT MAKETIME(4294967296, 0, 0); SELECT MAKETIME(-4294967296, 0, 0); SELECT MAKETIME(0, 4294967296, 0); SELECT MAKETIME(0, 0, 4294967296); SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); # check if EXTRACT() handles out-of-range values correctly SELECT EXTRACT(HOUR FROM '100000:02:03'); # check if we get proper warnings if both input string truncation # and out-of-range value occur CREATE TABLE t1(f1 TIME); INSERT INTO t1 VALUES('916:00:00 a'); SELECT * FROM t1; DROP TABLE t1; # # Bug #20927: sec_to_time treats big unsigned as signed # # check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); # 21913: DATE_FORMAT() Crashes mysql server if I use it through # mysql-connector-j driver. # Loading sql-common/my_time.c +69 −22 Original line number Diff line number Diff line Loading @@ -402,8 +402,10 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, There may be an optional [.second_part] after seconds length Length of str l_time Store result here was_cut Set to 1 if value was cut during conversion or to 0 otherwise. warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string was cut during conversion, and/or MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is out of range. NOTES Because of the extra days argument, this function can only Loading @@ -414,16 +416,16 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, 1 error */ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *was_cut) bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *warning) { long date[5],value; ulong date[5]; ulonglong value; const char *end=str+length, *end_of_days; bool found_days,found_hours; uint state; l_time->neg=0; *was_cut= 0; *warning= 0; for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) length--; if (str != end && *str == '-') Loading @@ -438,13 +440,16 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, /* Check first if this is a full TIMESTAMP */ if (length >= 12) { /* Probably full timestamp */ int was_cut; enum enum_mysql_timestamp_type res= str_to_datetime(str, length, l_time, (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut); (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut); if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR) { if (was_cut) *warning|= MYSQL_TIME_WARN_TRUNCATED; return res == MYSQL_TIMESTAMP_ERROR; /* We need to restore was_cut flag since str_to_datetime can modify it */ *was_cut= 0; } } /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ Loading Loading @@ -524,7 +529,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, if (field_length > 0) value*= (long) log_10_int[field_length]; else if (field_length < 0) *was_cut= 1; *warning|= MYSQL_TIME_WARN_TRUNCATED; date[4]=value; } else Loading @@ -538,10 +543,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, ((str[1] == '-' || str[1] == '+') && (end - str) > 2 && my_isdigit(&my_charset_latin1, str[2])))) { *was_cut= 1; return 1; } if (internal_format_positions[7] != 255) { Loading @@ -560,12 +562,12 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, } } /* Some simple checks */ if (date[2] >= 60 || date[3] >= 60) { *was_cut= 1; /* Integer overflow checks */ if (date[0] > UINT_MAX || date[1] > UINT_MAX || date[2] > UINT_MAX || date[3] > UINT_MAX || date[4] > UINT_MAX) return 1; } l_time->year= 0; /* For protocol::store_time */ l_time->month= 0; l_time->day= date[0]; Loading @@ -575,6 +577,10 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, l_time->second_part= date[4]; l_time->time_type= MYSQL_TIMESTAMP_TIME; /* Check if the value is valid and fits into TIME range */ if (check_time_range(l_time, warning)) return 1; /* Check if there is garbage at end of the TIME specification */ if (str != end) { Loading @@ -582,7 +588,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, { if (!my_isspace(&my_charset_latin1,*str)) { *was_cut= 1; *warning|= MYSQL_TIME_WARN_TRUNCATED; break; } } while (++str != end); Loading @@ -591,6 +597,47 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, } /* Check 'time' value to lie in the TIME range SYNOPSIS: check_time_range() time pointer to TIME value warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range DESCRIPTION If the time value lies outside of the range [-838:59:59, 838:59:59], set it to the closest endpoint of the range and set MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable. RETURN 0 time value is valid, but was possibly truncated 1 time value is invalid */ int check_time_range(struct st_mysql_time *time, int *warning) { longlong hour; if (time->minute >= 60 || time->second >= 60) return 1; hour= time->hour + (24*time->day); if (hour <= TIME_MAX_HOUR && (hour != TIME_MAX_HOUR || time->minute != TIME_MAX_MINUTE || time->second != TIME_MAX_SECOND || !time->second_part)) return 0; time->day= 0; time->hour= TIME_MAX_HOUR; time->minute= TIME_MAX_MINUTE; time->second= TIME_MAX_SECOND; time->second_part= 0; *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE; return 0; } /* Prepare offset of system time zone from UTC for my_system_gmt_sec() func. Loading Loading @@ -776,7 +823,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) int my_time_to_str(const MYSQL_TIME *l_time, char *to) { uint extra_hours= 0; return my_sprintf(to, (to, "%s%02d:%02d:%02d", return my_sprintf(to, (to, "%s%02u:%02u:%02u", (l_time->neg ? "-" : ""), extra_hours+ l_time->hour, l_time->minute, Loading @@ -785,7 +832,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to) int my_date_to_str(const MYSQL_TIME *l_time, char *to) { return my_sprintf(to, (to, "%04d-%02d-%02d", return my_sprintf(to, (to, "%04u-%02u-%02u", l_time->year, l_time->month, l_time->day)); Loading @@ -793,7 +840,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to) int my_datetime_to_str(const MYSQL_TIME *l_time, char *to) { return my_sprintf(to, (to, "%04d-%02d-%02d %02d:%02d:%02d", return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u", l_time->year, l_time->month, l_time->day, Loading Loading
include/my_time.h +13 −1 Original line number Diff line number Diff line Loading @@ -44,12 +44,24 @@ typedef long my_time_t; #define TIME_FUZZY_DATE 1 #define TIME_DATETIME_ONLY 2 #define MYSQL_TIME_WARN_TRUNCATED 1 #define MYSQL_TIME_WARN_OUT_OF_RANGE 2 /* Limits for the TIME data type */ #define TIME_MAX_HOUR 838 #define TIME_MAX_MINUTE 59 #define TIME_MAX_SECOND 59 #define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \ TIME_MAX_SECOND) enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, uint flags, int *was_cut); bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time, int *was_cut); int *warning); int check_time_range(struct st_mysql_time *time, int *warning); long calc_daynr(uint year,uint month,uint day); Loading
mysql-test/r/func_sapdb.result +11 −4 Original line number Diff line number Diff line Loading @@ -97,7 +97,9 @@ subtime("02:01:01.999999", "01:01:01.999999") 01:00:00.000000 select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002"); timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002") 8807:59:59.999999 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '8807:59:59.999999' select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 Loading Loading @@ -208,13 +210,16 @@ NULL NULL SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test; ttt qqq -744:00:00 NULL 26305:01:02 22:58:58 -26305:01:02 -22:58:58 838:59:59 22:58:58 -838:59:59 -22:58:58 NULL 26:02:02 00:00:00 -26:02:02 NULL NULL NULL NULL 00:00:00 -24:00:00 Warnings: Warning 1292 Truncated incorrect time value: '26305:01:02' Warning 1292 Truncated incorrect time value: '-26305:01:02' drop table t1, test; select addtime("-01:01:01.01", "-23:59:59.1") as a; a Loading @@ -224,7 +229,9 @@ a 10000 select microsecond(19971231235959.01) as a; a 10000 0 Warnings: Warning 1292 Truncated incorrect time value: '19971231235959.01' select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a; a 1997-12-31 00:00:10.090000 Loading
mysql-test/r/func_time.result +90 −1 Original line number Diff line number Diff line Loading @@ -330,7 +330,9 @@ extract(DAY_MINUTE FROM "02 10:11:12") 21011 select extract(DAY_SECOND FROM "225 10:11:12"); extract(DAY_SECOND FROM "225 10:11:12") 225101112 8385959 Warnings: Warning 1292 Truncated incorrect time value: '225 10:11:12' select extract(HOUR FROM "1999-01-02 10:11:12"); extract(HOUR FROM "1999-01-02 10:11:12") 10 Loading Loading @@ -694,6 +696,93 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; SELECT SEC_TO_TIME(3300000); SEC_TO_TIME(3300000) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '3300000' SELECT SEC_TO_TIME(3300000)+0; SEC_TO_TIME(3300000)+0 8385959.000000 Warnings: Warning 1292 Truncated incorrect time value: '3300000' SELECT SEC_TO_TIME(3600 * 4294967296); SEC_TO_TIME(3600 * 4294967296) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '15461882265600' SELECT TIME_TO_SEC('916:40:00'); TIME_TO_SEC('916:40:00') 3020399 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' SELECT ADDTIME('500:00:00', '416:40:00'); ADDTIME('500:00:00', '416:40:00') 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' SELECT ADDTIME('916:40:00', '416:40:00'); ADDTIME('916:40:00', '416:40:00') 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' Warning 1292 Truncated incorrect time value: '1255:39:59' SELECT SUBTIME('916:40:00', '416:40:00'); SUBTIME('916:40:00', '416:40:00') 422:19:59 Warnings: Warning 1292 Truncated incorrect time value: '916:40:00' SELECT SUBTIME('-916:40:00', '416:40:00'); SUBTIME('-916:40:00', '416:40:00') -838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '-916:40:00' Warning 1292 Truncated incorrect time value: '-1255:39:59' SELECT MAKETIME(916,0,0); MAKETIME(916,0,0) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '916:00:00' SELECT MAKETIME(4294967296, 0, 0); MAKETIME(4294967296, 0, 0) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '4294967296:00:00' SELECT MAKETIME(-4294967296, 0, 0); MAKETIME(-4294967296, 0, 0) -838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '-4294967296:00:00' SELECT MAKETIME(0, 4294967296, 0); MAKETIME(0, 4294967296, 0) NULL SELECT MAKETIME(0, 0, 4294967296); MAKETIME(0, 0, 4294967296) NULL SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); MAKETIME(CAST(-1 AS UNSIGNED), 0, 0) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00' SELECT EXTRACT(HOUR FROM '100000:02:03'); EXTRACT(HOUR FROM '100000:02:03') 838 Warnings: Warning 1292 Truncated incorrect time value: '100000:02:03' CREATE TABLE t1(f1 TIME); INSERT INTO t1 VALUES('916:00:00 a'); Warnings: Warning 1265 Data truncated for column 'f1' at row 1 Warning 1264 Data truncated; out of range for column 'f1' at row 1 SELECT * FROM t1; f1 838:59:59 DROP TABLE t1; SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); SEC_TO_TIME(CAST(-1 AS UNSIGNED)) 838:59:59 Warnings: Warning 1292 Truncated incorrect time value: '18446744073709551615' SET NAMES latin1; SET character_set_results = NULL; SHOW VARIABLES LIKE 'character_set_results'; Loading
mysql-test/t/func_time.test +41 −0 Original line number Diff line number Diff line Loading @@ -369,6 +369,47 @@ show create table t1; drop table t1; # # Bug #11655: Wrong time is returning from nested selects - maximum time exists # # check if SEC_TO_TIME() handles out-of-range values correctly SELECT SEC_TO_TIME(3300000); SELECT SEC_TO_TIME(3300000)+0; SELECT SEC_TO_TIME(3600 * 4294967296); # check if TIME_TO_SEC() handles out-of-range values correctly SELECT TIME_TO_SEC('916:40:00'); # check if ADDTIME() handles out-of-range values correctly SELECT ADDTIME('500:00:00', '416:40:00'); SELECT ADDTIME('916:40:00', '416:40:00'); # check if SUBTIME() handles out-of-range values correctly SELECT SUBTIME('916:40:00', '416:40:00'); SELECT SUBTIME('-916:40:00', '416:40:00'); # check if MAKETIME() handles out-of-range values correctly SELECT MAKETIME(916,0,0); SELECT MAKETIME(4294967296, 0, 0); SELECT MAKETIME(-4294967296, 0, 0); SELECT MAKETIME(0, 4294967296, 0); SELECT MAKETIME(0, 0, 4294967296); SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); # check if EXTRACT() handles out-of-range values correctly SELECT EXTRACT(HOUR FROM '100000:02:03'); # check if we get proper warnings if both input string truncation # and out-of-range value occur CREATE TABLE t1(f1 TIME); INSERT INTO t1 VALUES('916:00:00 a'); SELECT * FROM t1; DROP TABLE t1; # # Bug #20927: sec_to_time treats big unsigned as signed # # check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); # 21913: DATE_FORMAT() Crashes mysql server if I use it through # mysql-connector-j driver. # Loading
sql-common/my_time.c +69 −22 Original line number Diff line number Diff line Loading @@ -402,8 +402,10 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, There may be an optional [.second_part] after seconds length Length of str l_time Store result here was_cut Set to 1 if value was cut during conversion or to 0 otherwise. warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string was cut during conversion, and/or MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is out of range. NOTES Because of the extra days argument, this function can only Loading @@ -414,16 +416,16 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, 1 error */ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *was_cut) bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *warning) { long date[5],value; ulong date[5]; ulonglong value; const char *end=str+length, *end_of_days; bool found_days,found_hours; uint state; l_time->neg=0; *was_cut= 0; *warning= 0; for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) length--; if (str != end && *str == '-') Loading @@ -438,13 +440,16 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, /* Check first if this is a full TIMESTAMP */ if (length >= 12) { /* Probably full timestamp */ int was_cut; enum enum_mysql_timestamp_type res= str_to_datetime(str, length, l_time, (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut); (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut); if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR) { if (was_cut) *warning|= MYSQL_TIME_WARN_TRUNCATED; return res == MYSQL_TIMESTAMP_ERROR; /* We need to restore was_cut flag since str_to_datetime can modify it */ *was_cut= 0; } } /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ Loading Loading @@ -524,7 +529,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, if (field_length > 0) value*= (long) log_10_int[field_length]; else if (field_length < 0) *was_cut= 1; *warning|= MYSQL_TIME_WARN_TRUNCATED; date[4]=value; } else Loading @@ -538,10 +543,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, ((str[1] == '-' || str[1] == '+') && (end - str) > 2 && my_isdigit(&my_charset_latin1, str[2])))) { *was_cut= 1; return 1; } if (internal_format_positions[7] != 255) { Loading @@ -560,12 +562,12 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, } } /* Some simple checks */ if (date[2] >= 60 || date[3] >= 60) { *was_cut= 1; /* Integer overflow checks */ if (date[0] > UINT_MAX || date[1] > UINT_MAX || date[2] > UINT_MAX || date[3] > UINT_MAX || date[4] > UINT_MAX) return 1; } l_time->year= 0; /* For protocol::store_time */ l_time->month= 0; l_time->day= date[0]; Loading @@ -575,6 +577,10 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, l_time->second_part= date[4]; l_time->time_type= MYSQL_TIMESTAMP_TIME; /* Check if the value is valid and fits into TIME range */ if (check_time_range(l_time, warning)) return 1; /* Check if there is garbage at end of the TIME specification */ if (str != end) { Loading @@ -582,7 +588,7 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, { if (!my_isspace(&my_charset_latin1,*str)) { *was_cut= 1; *warning|= MYSQL_TIME_WARN_TRUNCATED; break; } } while (++str != end); Loading @@ -591,6 +597,47 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, } /* Check 'time' value to lie in the TIME range SYNOPSIS: check_time_range() time pointer to TIME value warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range DESCRIPTION If the time value lies outside of the range [-838:59:59, 838:59:59], set it to the closest endpoint of the range and set MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable. RETURN 0 time value is valid, but was possibly truncated 1 time value is invalid */ int check_time_range(struct st_mysql_time *time, int *warning) { longlong hour; if (time->minute >= 60 || time->second >= 60) return 1; hour= time->hour + (24*time->day); if (hour <= TIME_MAX_HOUR && (hour != TIME_MAX_HOUR || time->minute != TIME_MAX_MINUTE || time->second != TIME_MAX_SECOND || !time->second_part)) return 0; time->day= 0; time->hour= TIME_MAX_HOUR; time->minute= TIME_MAX_MINUTE; time->second= TIME_MAX_SECOND; time->second_part= 0; *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE; return 0; } /* Prepare offset of system time zone from UTC for my_system_gmt_sec() func. Loading Loading @@ -776,7 +823,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) int my_time_to_str(const MYSQL_TIME *l_time, char *to) { uint extra_hours= 0; return my_sprintf(to, (to, "%s%02d:%02d:%02d", return my_sprintf(to, (to, "%s%02u:%02u:%02u", (l_time->neg ? "-" : ""), extra_hours+ l_time->hour, l_time->minute, Loading @@ -785,7 +832,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to) int my_date_to_str(const MYSQL_TIME *l_time, char *to) { return my_sprintf(to, (to, "%04d-%02d-%02d", return my_sprintf(to, (to, "%04u-%02u-%02u", l_time->year, l_time->month, l_time->day)); Loading @@ -793,7 +840,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to) int my_datetime_to_str(const MYSQL_TIME *l_time, char *to) { return my_sprintf(to, (to, "%04d-%02d-%02d %02d:%02d:%02d", return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u", l_time->year, l_time->month, l_time->day, Loading