List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:December 1 2008 3:19pm
Subject:bzr commit into mysql-5.0-bugteam branch (kgeorge:2717) Bug#39920
View as plain text  
#At file:///home/kgeorge/mysql/work/B39920-5.0-bugteam/ based on
revid:gshchepa@stripped

 2717 Georgi Kodinov	2008-12-01
      Bug #39920: MySQL cannot deal with Leap Second expression in string literal.
                        
      Updated MySQL time handling code to react correctly on UTC leap second additions.
      MySQL functions that return the OS current time, like e.g. CURDATE(), NOW() etc
      will return :59:59 instead of :59:60 or 59:61.
      As a result the reader will receive :59:59 for 2 or 3 consecutive seconds 
      during the leap second.
      This fix will not affect the values returned by UNIX_TIMESTAMP() for leap seconds.
      But note that when converting the value returned by UNIX_TIMESTAMP() to broken 
      down time the correction of leap seconds will still be applied.
      Note that this fix will make a difference *only* if the OS is specially configured
      to return leap seconds from the OS time calls or when using a MySQL time zone 
      defintion that has leap seconds.
      Even after this change date/time literals (or other broken down time 
      representations) with leap seconds (ending on :59:60 or 59:61) will still be 
      considered illegal and discarded by the server with an error or 
      a warning depending on the sql mode.
      Added a test case to demonstrate the effect of the fix.
modified:
  mysql-test/r/timezone3.result
  mysql-test/std_data/Moscow_leap
  mysql-test/t/timezone3.test
  sql/tztime.cc
  sql/tztime.h

per-file messages:
  mysql-test/r/timezone3.result
    Bug #39920: test case
  mysql-test/std_data/Moscow_leap
    Bug #39920: updated the Moscow time zone to Dr. Olson's tzdata 2008i 
    to accomodate for the 2008 leap second
  mysql-test/t/timezone3.test
    Bug #39920: test case
  sql/tztime.cc
    Bug #39920: adjust leap seconds (:60 or :61) to :59
  sql/tztime.h
    Bug #39920: adjust leap seconds (:60 or :61) to :59
=== modified file 'mysql-test/r/timezone3.result'
--- a/mysql-test/r/timezone3.result	2004-11-12 15:44:17 +0000
+++ b/mysql-test/r/timezone3.result	2008-12-01 14:18:35 +0000
@@ -17,6 +17,9 @@ insert into t1 values
 insert into t1 values
 (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'),
 (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00');
+insert into t1 values
+(unix_timestamp('2009-01-01 02:59:59'),'2009-01-01 02:59:59'),
+(unix_timestamp('2009-01-01 03:00:00'),'2009-01-01 03:00:00');
 select i, from_unixtime(i), c from t1;
 i	from_unixtime(i)	c
 1072904422	2004-01-01 00:00:00	2004-01-01 00:00:00
@@ -31,6 +34,8 @@ i	from_unixtime(i)	c
 1099180821	2004-10-31 02:59:59	2004-10-31 02:59:59
 362793608	1981-07-01 03:59:59	1981-07-01 03:59:59
 362793610	1981-07-01 04:00:00	1981-07-01 04:00:00
+1230768022	2009-01-01 02:59:59	2009-01-01 02:59:59
+1230768024	2009-01-01 03:00:00	2009-01-01 03:00:00
 drop table t1;
 create table t1 (ts timestamp);
 insert into t1 values (19730101235900), (20040101235900);
@@ -39,3 +44,6 @@ ts
 1973-01-01 23:59:00
 2004-01-01 23:59:00
 drop table t1;
+SELECT FROM_UNIXTIME(1230768022), FROM_UNIXTIME(1230768023), FROM_UNIXTIME(1230768024);
+FROM_UNIXTIME(1230768022)	FROM_UNIXTIME(1230768023)	FROM_UNIXTIME(1230768024)
+2009-01-01 02:59:59	2009-01-01 02:59:59	2009-01-01 03:00:00

=== modified file 'mysql-test/std_data/Moscow_leap'
Binary files a/mysql-test/std_data/Moscow_leap	2004-11-03 17:59:03 +0000 and
b/mysql-test/std_data/Moscow_leap	2008-12-01 14:18:35 +0000 differ

=== modified file 'mysql-test/t/timezone3.test'
--- a/mysql-test/t/timezone3.test	2005-07-28 00:22:47 +0000
+++ b/mysql-test/t/timezone3.test	2008-12-01 14:18:35 +0000
@@ -45,6 +45,10 @@ insert into t1 values
   (unix_timestamp('1981-07-01 03:59:59'),'1981-07-01 03:59:59'),
   (unix_timestamp('1981-07-01 04:00:00'),'1981-07-01 04:00:00');
 
+insert into t1 values
+  (unix_timestamp('2009-01-01 02:59:59'),'2009-01-01 02:59:59'),
+  (unix_timestamp('2009-01-01 03:00:00'),'2009-01-01 03:00:00');
+
 select i, from_unixtime(i), c from t1;
 drop table t1;
 
@@ -58,4 +62,12 @@ insert into t1 values (19730101235900), 
 select * from t1;
 drop table t1;
 
+#
+# Test Bug #39920: MySQL cannot deal with Leap Second expression in string
+# literal
+#
+
+# 2009-01-01 02:59:59, 2009-01-01 02:59:60 and 2009-01-01 03:00:00
+SELECT FROM_UNIXTIME(1230768022), FROM_UNIXTIME(1230768023), FROM_UNIXTIME(1230768024);
+
 # End of 4.1 tests

=== modified file 'sql/tztime.cc'
--- a/sql/tztime.cc	2008-04-03 17:19:55 +0000
+++ b/sql/tztime.cc	2008-12-01 14:18:35 +0000
@@ -1073,6 +1073,7 @@ Time_zone_system::gmt_sec_to_TIME(MYSQL_
   localtime_r(&tmp_t, &tmp_tm);
   localtime_to_TIME(tmp, &tmp_tm);
   tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
+  adjust_leap_second(tmp);
 }
 
 
@@ -1157,6 +1158,7 @@ Time_zone_utc::gmt_sec_to_TIME(MYSQL_TIM
   gmtime_r(&tmp_t, &tmp_tm);
   localtime_to_TIME(tmp, &tmp_tm);
   tmp->time_type= MYSQL_TIMESTAMP_DATETIME;
+  adjust_leap_second(tmp);
 }
 
 
@@ -1260,6 +1262,7 @@ void
 Time_zone_db::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const
 {
   ::gmt_sec_to_TIME(tmp, t, tz_info);
+  adjust_leap_second(tmp);
 }
 
 
@@ -2373,6 +2376,25 @@ Time_zone *my_tz_find_with_opening_tz_ta
   DBUG_RETURN(tz);
 }
 
+
+/**
+  Convert leap seconds into non-leap
+
+  This function will convert the leap seconds added by the OS to 
+  non-leap seconds, e.g. 23:59:59, 23:59:60 -> 23:59:59, 00:00:01 ...
+  This check is not checking for years on purpose : although it's not a
+  complete check this way it doesn't require looking (and having installed)
+  the leap seconds table.
+
+  @param[in,out] broken down time structure as filled in by the OS
+*/
+
+void Time_zone::adjust_leap_second(MYSQL_TIME *t)
+{
+  if (t->second == 60 || t->second == 61)
+    t->second= 59;
+}
+
 #endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
 
 

=== modified file 'sql/tztime.h'
--- a/sql/tztime.h	2007-05-16 08:44:59 +0000
+++ b/sql/tztime.h	2008-12-01 14:18:35 +0000
@@ -55,6 +55,9 @@ public:
     allocated on MEM_ROOT and should not require destruction.
   */
   virtual ~Time_zone() {};
+
+protected:
+  static inline void adjust_leap_second(MYSQL_TIME *t);
 };
 
 extern Time_zone * my_tz_UTC;

Thread
bzr commit into mysql-5.0-bugteam branch (kgeorge:2717) Bug#39920Georgi Kodinov1 Dec