From bcc6821b25aee9380add5d0478689b5eb2ef677e Mon Sep 17 00:00:00 2001
From: unknown <andrey@lmy004.>
Date: Fri, 3 Mar 2006 01:39:11 +0100
Subject: [PATCH] fix for bug #16396: Events: Distant-future dates become past
 dates WL#1034 (Internal CRON) timestamps does not support > y2038

mysql-test/r/events_bugs.result:
  update results
mysql-test/t/events_bugs.test:
  add tests
sql/event_timed.cc:
  fix for bug #16396: Events: Distant-future dates become past dates.
---
 mysql-test/r/events_bugs.result |  6 +++++
 mysql-test/t/events_bugs.test   | 13 +++++++++++
 sql/event_timed.cc              | 41 ++++++++++++++++++++++++++-------
 3 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result
index 0b554f97b9..c59adcd744 100644
--- a/mysql-test/r/events_bugs.result
+++ b/mysql-test/r/events_bugs.result
@@ -1,5 +1,11 @@
 create database if not exists events_test;
 use events_test;
+create event e_55 on schedule at 99990101000000 do drop table t;
+ERROR HY000: Incorrect AT value: '99990101000000'
+create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t;
+ERROR HY000: Incorrect STARTS value: '99990101000000'
+create event e_55 on schedule every 10 minute ends 99990101000000 do drop table t;
+ERROR HY000: ENDS is either invalid or before STARTS
 set global event_scheduler=0;
 "Wait a bit to settle down"
 delete from mysql.event;
diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test
index 2d4374dcb4..cf19703333 100644
--- a/mysql-test/t/events_bugs.test
+++ b/mysql-test/t/events_bugs.test
@@ -1,5 +1,18 @@
 create database if not exists events_test;
 use events_test;
+#
+# Start - 16396: Events: Distant-future dates become past dates
+#
+--error 1503
+create event e_55 on schedule at 99990101000000 do drop table t;
+--error 1503
+create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t;
+--error 1521
+create event e_55 on schedule every 10 minute ends 99990101000000 do drop table t;
+#
+# End  -  16396: Events: Distant-future dates become past dates
+#
+
 #
 # Start - 16407: Events: Changes in sql_mode won't be taken into account
 #
diff --git a/sql/event_timed.cc b/sql/event_timed.cc
index a862019766..bd5f23f980 100644
--- a/sql/event_timed.cc
+++ b/sql/event_timed.cc
@@ -150,6 +150,7 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
 {
   my_bool not_used;
   TIME ltime;
+  my_time_t t;
 
   TIME time_tmp;
   DBUG_ENTER("Event_timed::init_execute_at");
@@ -173,12 +174,18 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
       TIME_to_ulonglong_datetime(&time_tmp))
     DBUG_RETURN(EVEX_BAD_PARAMS);
 
-
   /*
     This may result in a 1970-01-01 date if ltime is > 2037-xx-xx.
     CONVERT_TZ has similar problem.
+    mysql_priv.h currently lists 
+      #define TIMESTAMP_MAX_YEAR 2038 (see TIME_to_timestamp())
   */
-  my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd,&ltime, &not_used));
+  my_tz_UTC->gmt_sec_to_TIME(&ltime,t=TIME_to_timestamp(thd,&ltime,&not_used));
+  if (!t)
+  {
+    DBUG_PRINT("error", ("Execute AT after year 2037"));
+    DBUG_RETURN(ER_WRONG_VALUE);
+  }
 
   execute_at_null= FALSE;
   execute_at= ltime;
@@ -301,6 +308,7 @@ Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
   RETURNS
     0                  OK
     EVEX_PARSE_ERROR   fix_fields failed
+    EVEX_BAD_PARAMS    starts before now
 */
 
 int
@@ -308,6 +316,7 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
 {
   my_bool not_used;
   TIME ltime, time_tmp;
+  my_time_t t;
 
   DBUG_ENTER("Event_timed::init_starts");
 
@@ -328,10 +337,17 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
     DBUG_RETURN(EVEX_BAD_PARAMS);
 
   /*
-    This may result in a 1970-01-01 date if ltime is > 2037-xx-xx
-    CONVERT_TZ has similar problem
+    This may result in a 1970-01-01 date if ltime is > 2037-xx-xx.
+    CONVERT_TZ has similar problem.
+    mysql_priv.h currently lists 
+      #define TIMESTAMP_MAX_YEAR 2038 (see TIME_to_timestamp())
   */
-  my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd, &ltime, &not_used));
+  my_tz_UTC->gmt_sec_to_TIME(&ltime,t=TIME_to_timestamp(thd, &ltime, &not_used));
+  if (!t)
+  {
+    DBUG_PRINT("error", ("STARTS after year 2037"));
+    DBUG_RETURN(EVEX_BAD_PARAMS);
+  }
 
   starts= ltime;
   starts_null= FALSE;
@@ -358,6 +374,7 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
   RETURNS
     0                  OK
     EVEX_PARSE_ERROR   fix_fields failed
+    ER_WRONG_VALUE     starts distant date (after year 2037)
     EVEX_BAD_PARAMS    ENDS before STARTS
 */
 
@@ -366,6 +383,7 @@ Event_timed::init_ends(THD *thd, Item *new_ends)
 {
   TIME ltime, ltime_now;
   my_bool not_used;
+  my_time_t t;
 
   DBUG_ENTER("Event_timed::init_ends");
 
@@ -377,11 +395,18 @@ Event_timed::init_ends(THD *thd, Item *new_ends)
     DBUG_RETURN(EVEX_BAD_PARAMS);
 
   /*
-    This may result in a 1970-01-01 date if ltime is > 2037-xx-xx ?
-    CONVERT_TZ has similar problem ?
+    This may result in a 1970-01-01 date if ltime is > 2037-xx-xx.
+    CONVERT_TZ has similar problem.
+    mysql_priv.h currently lists 
+      #define TIMESTAMP_MAX_YEAR 2038 (see TIME_to_timestamp())
   */
   DBUG_PRINT("info", ("get the UTC time"));
-  my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd, &ltime, &not_used));
+  my_tz_UTC->gmt_sec_to_TIME(&ltime,t=TIME_to_timestamp(thd, &ltime, &not_used));
+  if (!t)
+  {
+    DBUG_PRINT("error", ("ENDS after year 2037"));
+    DBUG_RETURN(EVEX_BAD_PARAMS);
+  }
 
   /* Check whether ends is after starts */
   DBUG_PRINT("info", ("ENDS after STARTS?"));
-- 
2.30.9