diff options
author | andrey@lmy004. <> | 2006-04-07 09:08:58 +0200 |
---|---|---|
committer | andrey@lmy004. <> | 2006-04-07 09:08:58 +0200 |
commit | 36cfa4dfa127549cfb87a06ccfa6efc4f39077cb (patch) | |
tree | 7337e1a221b14d7b15e81d34a6ddf5c688a34716 /sql/time.cc | |
parent | 3c1f4e3cd52b5e82d518e022826b669fd4df7806 (diff) | |
download | mariadb-git-36cfa4dfa127549cfb87a06ccfa6efc4f39077cb.tar.gz |
fix for bug #17494 (The algorithm for calculating execution times is not fully correct)
This also should fix 17493 and 17346, and probably 16397 (not tested).
WL#1034 (Internal CRON)
(post-review commit)
Diffstat (limited to 'sql/time.cc')
-rw-r--r-- | sql/time.cc | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/sql/time.cc b/sql/time.cc index efe1cbf1c09..3c654de23bb 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -833,4 +833,80 @@ invalid_date: } +/* + Calculate difference between two datetime values as seconds + microseconds. + + SYNOPSIS + calc_time_diff() + l_time1 - TIME/DATE/DATETIME value + l_time2 - TIME/DATE/DATETIME value + l_sign - 1 absolute values are substracted, + -1 absolute values are added. + seconds_out - Out parameter where difference between + l_time1 and l_time2 in seconds is stored. + microseconds_out- Out parameter where microsecond part of difference + between l_time1 and l_time2 is stored. + + NOTE + This function calculates difference between l_time1 and l_time2 absolute + values. So one should set l_sign and correct result if he want to take + signs into account (i.e. for TIME values). + + RETURN VALUES + Returns sign of difference. + 1 means negative result + 0 means positive result + +*/ + +bool +calc_time_diff(TIME *l_time1, TIME *l_time2, int l_sign, longlong *seconds_out, + long *microseconds_out) +{ + long days; + bool neg; + longlong microseconds; + + /* + We suppose that if first argument is MYSQL_TIMESTAMP_TIME + the second argument should be TIMESTAMP_TIME also. + We should check it before calc_time_diff call. + */ + if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value + days= (long)l_time1->day - l_sign * (long)l_time2->day; + else + { + days= calc_daynr((uint) l_time1->year, + (uint) l_time1->month, + (uint) l_time1->day); + if (l_time2->time_type == MYSQL_TIMESTAMP_TIME) + days-= l_sign * (long)l_time2->day; + else + days-= l_sign*calc_daynr((uint) l_time2->year, + (uint) l_time2->month, + (uint) l_time2->day); + } + + microseconds= ((longlong)days*LL(86400) + + (longlong)(l_time1->hour*3600L + + l_time1->minute*60L + + l_time1->second) - + l_sign*(longlong)(l_time2->hour*3600L + + l_time2->minute*60L + + l_time2->second)) * LL(1000000) + + (longlong)l_time1->second_part - + l_sign*(longlong)l_time2->second_part; + + neg= 0; + if (microseconds < 0) + { + microseconds= -microseconds; + neg= 1; + } + *seconds_out= microseconds/1000000L; + *microseconds_out= (long) (microseconds%1000000L); + return neg; +} + + #endif |