summaryrefslogtreecommitdiff
path: root/sql-common
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-06-06 20:28:15 +0200
committerSergei Golubchik <sergii@pisem.net>2011-06-06 20:28:15 +0200
commit4d128777dde904c5f0adab9b093e854c9c580d41 (patch)
tree36875e84e65be596def46c5d7ce621e60abcbdae /sql-common
parentc1a92f9caeb368021d5ffbe0df237ded29692c1a (diff)
downloadmariadb-git-4d128777dde904c5f0adab9b093e854c9c580d41.tar.gz
revert a suggested "optimization" that introduced a bug
compilation error in mysys/my_getsystime.c fixed some redundant code removed sec_to_time, time_to_sec, from_unixtime, unix_timestamp, @@timestamp now use decimal, not double for numbers with a fractional part. purge_master_logs_before_date() fixed many bugs in corner cases fixed mysys/my_getsystime.c: compilation failure fixed sql/sql_parse.cc: don't cut corners. it backfires.
Diffstat (limited to 'sql-common')
-rw-r--r--sql-common/my_time.c47
1 files changed, 28 insertions, 19 deletions
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 264fc5b957b..6958c8e3517 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -18,6 +18,7 @@
#include <m_ctype.h>
/* Windows version of localtime_r() is declared in my_ptrhead.h */
#include <my_pthread.h>
+#include <mysqld_error.h>
ulonglong log_10_int[20]=
{
@@ -730,7 +731,7 @@ void my_init_time(void)
time_t seconds;
struct tm *l_time,tm_tmp;
MYSQL_TIME my_time;
- my_bool not_used;
+ uint not_used;
seconds= (time_t) time((time_t*) 0);
localtime_r(&seconds,&tm_tmp);
@@ -811,7 +812,11 @@ long calc_daynr(uint year,uint month,uint day)
t - time value to be converted
my_timezone - pointer to long where offset of system time zone
from UTC will be stored for caching
- in_dst_time_gap - set to true if time falls into spring time-gap
+ 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).
NOTES
The idea is to cache the time zone offset from UTC (including daylight
@@ -825,8 +830,7 @@ long calc_daynr(uint year,uint month,uint day)
Time in UTC seconds since Unix Epoch representation.
*/
my_time_t
-my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
- my_bool *in_dst_time_gap)
+my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone, uint *error_code)
{
uint loop;
time_t tmp= 0;
@@ -843,7 +847,11 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
memcpy(&tmp_time, t_src, sizeof(MYSQL_TIME));
if (!validate_timestamp_range(t))
+ {
+ *error_code= ER_WARN_DATA_OUT_OF_RANGE;
return 0;
+ }
+ *error_code= 0;
/*
Calculate the gmt time based on current time and timezone
@@ -989,7 +997,7 @@ my_system_gmt_sec(const MYSQL_TIME *t_src, long *my_timezone,
else if (diff == -3600)
tmp-=t->minute*60 + t->second; /* Move to previous hour */
- *in_dst_time_gap= 1;
+ *error_code= ER_WARN_INVALID_TIMESTAMP;
}
*my_timezone= current_timezone;
@@ -1130,7 +1138,7 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, int digits)
Datetime value in YYYYMMDDHHMMSS format.
*/
-longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
+longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
uint flags, int *was_cut)
{
long part1,part2;
@@ -1139,7 +1147,7 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
bzero((char*) time_res, sizeof(*time_res));
time_res->time_type=MYSQL_TIMESTAMP_DATE;
- if (nr == LL(0) || nr >= LL(10000101000000))
+ if (nr == 0 || nr >= 10000101000000LL || sec_part)
{
time_res->time_type=MYSQL_TIMESTAMP_DATETIME;
goto ok;
@@ -1189,11 +1197,13 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
time_res->hour= (int) (part2/10000L); part2%=10000L;
time_res->minute=(int) part2 / 100;
time_res->second=(int) part2 % 100;
+ time_res->second_part= sec_part;
if (time_res->year <= 9999 && time_res->month <= 12 &&
time_res->day <= 31 && time_res->hour <= 23 &&
time_res->minute <= 59 && time_res->second <= 59 &&
- !check_date(time_res, (nr != 0), flags, was_cut))
+ sec_part <= TIME_MAX_SECOND_PART &&
+ !check_date(time_res, nr || sec_part, flags, was_cut))
return nr;
/* Don't want to have was_cut get set if NO_ZERO_DATE was violated. */
@@ -1206,7 +1216,7 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
}
/*
- Convert a double to a MYSQL_TIME struct.
+ Convert a pair of integers to a MYSQL_TIME struct.
@param[in] nr a number to convert
@param[out] ltime Date to check.
@@ -1223,28 +1233,27 @@ longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
0 time value is valid, but was possibly truncated
1 time value is invalid
*/
-int number_to_time(double nr, MYSQL_TIME *ltime, int *was_cut)
+int number_to_time(my_bool neg, longlong nr, ulong sec_part,
+ MYSQL_TIME *ltime, int *was_cut)
{
- ulong tmp;
*was_cut= 0;
ltime->year= ltime->month= ltime->day= 0;
ltime->time_type= MYSQL_TIMESTAMP_TIME;
- if ((ltime->neg= nr < 0))
- nr= -nr;
+ ltime->neg= neg;
if (nr > TIME_MAX_VALUE)
{
nr= TIME_MAX_VALUE;
+ sec_part= TIME_MAX_SECOND_PART;
*was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE;
}
- tmp=(ulong)floor(nr);
- ltime->hour = tmp/100/100;
- ltime->minute= tmp/100%100;
- ltime->second= tmp%100;
- ltime->second_part= (ulong)((nr-tmp)*TIME_SECOND_PART_FACTOR);
+ ltime->hour = nr/100/100;
+ ltime->minute= nr/100%100;
+ ltime->second= nr%100;
+ ltime->second_part= sec_part;
- if (ltime->minute < 60 && ltime->second < 60)
+ if (ltime->minute < 60 && ltime->second < 60 && sec_part <= TIME_MAX_SECOND_PART)
return 0;
*was_cut= MYSQL_TIME_WARN_TRUNCATED;