summaryrefslogtreecommitdiff
path: root/sql/time.cc
diff options
context:
space:
mode:
authorandrey@lmy004. <>2006-04-07 09:08:58 +0200
committerandrey@lmy004. <>2006-04-07 09:08:58 +0200
commit36cfa4dfa127549cfb87a06ccfa6efc4f39077cb (patch)
tree7337e1a221b14d7b15e81d34a6ddf5c688a34716 /sql/time.cc
parent3c1f4e3cd52b5e82d518e022826b669fd4df7806 (diff)
downloadmariadb-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.cc76
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