List:Commits« Previous MessageNext Message »
From:ahristov Date:February 28 2006 11:08am
Subject:bk commit into 5.1 tree (andrey:1.2191)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of andrey. When andrey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2191 06/02/28 12:08:13 andrey@lmy004. +8 -0
  manual merge

  sql/sql_show.cc
    1.314 06/02/28 12:08:08 andrey@lmy004. +4 -3
    manual merge

  sql/event_timed.cc
    1.39 06/02/28 12:08:08 andrey@lmy004. +12 -21
    manual merge

  sql/event_executor.cc
    1.35 06/02/28 12:08:07 andrey@lmy004. +0 -3
    manual merge

  sql/sql_yacc.yy
    1.468 06/02/28 11:46:02 andrey@lmy004. +0 -0
    Auto merged

  sql/event.h
    1.25 06/02/28 11:46:00 andrey@lmy004. +0 -0
    Auto merged

  sql/event.cc
    1.34 06/02/28 11:46:00 andrey@lmy004. +0 -0
    Auto merged

  mysql-test/t/events.test
    1.22 06/02/28 11:46:00 andrey@lmy004. +0 -0
    Auto merged

  mysql-test/r/events.result
    1.26 06/02/28 11:46:00 andrey@lmy004. +0 -1
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	andrey
# Host:	lmy004.
# Root:	/work/mysql-5.1-bug16537/RESYNC

--- 1.313/sql/sql_show.cc	2006-02-27 16:58:33 +01:00
+++ 1.314/sql/sql_show.cc	2006-02-28 12:08:08 +01:00
@@ -3957,7 +3957,7 @@ fill_events_copy_to_schema_table(THD *th
   sch_table->field[3]->store(et.definer.str, et.definer.length, scs);
   sch_table->field[4]->store(et.body.str, et.body.length, scs);
 
-  // [9] is SQL_MODE 
+  /* [9] is SQL_MODE */
   {
     byte *sql_mode_str;
     ulong sql_mode_len=0;
@@ -3972,9 +3972,9 @@ fill_events_copy_to_schema_table(THD *th
     String show_str;
     //type
     sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs);
-    //execute_at
+    /* execute_at */
     sch_table->field[6]->set_null();
-    //interval_value
+    /* interval_value */
     //interval_type
     if (event_reconstruct_interval_expression(&show_str, et.interval,
                                               et.expression))
@@ -3986,26 +3986,24 @@ fill_events_copy_to_schema_table(THD *th
     LEX_STRING *ival= &interval_type_to_name[et.interval];
     sch_table->field[8]->set_notnull();
     sch_table->field[8]->store(ival->str, ival->length, scs);
-    //starts & ends
+
+    //starts & ends    
     sch_table->field[10]->set_notnull();
     sch_table->field[10]->store_time(&et.starts, MYSQL_TIMESTAMP_DATETIME);
-    sch_table->field[11]->set_notnull();
-    sch_table->field[11]->store_time(&et.ends, MYSQL_TIMESTAMP_DATETIME);
+
+    if (!et.ends_null)
+    {
+      sch_table->field[11]->set_notnull();
+      sch_table->field[11]->store_time(&et.ends, MYSQL_TIMESTAMP_DATETIME);
+    }
   }
   else
   {
     //type
     sch_table->field[5]->store(STRING_WITH_LEN("ONE TIME"), scs);
-    //execute_at
+
     sch_table->field[6]->set_notnull();
     sch_table->field[6]->store_time(&et.execute_at, MYSQL_TIMESTAMP_DATETIME);
-    //interval
-    sch_table->field[7]->set_null();
-    //interval_type
-    sch_table->field[8]->set_null();
-    //starts & ends
-    sch_table->field[10]->set_null();
-    sch_table->field[11]->set_null();
   }
 
   //status

--- 1.467/sql/sql_yacc.yy	2006-02-27 17:20:58 +01:00
+++ 1.468/sql/sql_yacc.yy	2006-02-28 11:46:02 +01:00
@@ -1476,6 +1476,9 @@ opt_ev_status: /* empty */ { $$= 0; }
       ;
 
 ev_starts: /* empty */
+          {
+            Lex->et->init_starts(YYTHD, new Item_func_now_local());
+          }
         | STARTS_SYM expr
           {
             LEX *lex= Lex;

--- 1.25/mysql-test/r/events.result	2006-02-24 12:00:28 +01:00
+++ 1.26/mysql-test/r/events.result	2006-02-28 11:46:00 +01:00
@@ -37,6 +37,54 @@ alter event event3 rename to event2;
 drop event event2;
 create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end;
 drop event event2;
+CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1;
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	RECURRING	NULL	10	INTERVAL_SECOND	#	#	ENABLED
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+starts IS NULL	ends IS NULL	comment
+0	1	
+ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02';
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	ONE TIME	2020-02-02 17:00:02	NULL	NULL	#	#	ENABLED
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+starts IS NULL	ends IS NULL	comment
+1	1	
+ALTER EVENT event_starts_test COMMENT "non-empty comment";
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	ONE TIME	2020-02-02 17:00:02	NULL	NULL	#	#	ENABLED
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+starts IS NULL	ends IS NULL	comment
+1	1	non-empty comment
+ALTER EVENT event_starts_test COMMENT "";
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	ONE TIME	2020-02-02 17:00:02	NULL	NULL	#	#	ENABLED
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+starts IS NULL	ends IS NULL	comment
+1	1	
+DROP EVENT event_starts_test;
+CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2;
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	RECURRING	NULL	20	INTERVAL_SECOND	#	#	ENABLED
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+starts IS NULL	ends IS NULL	comment
+0	0	
+ALTER EVENT event_starts_test COMMENT "non-empty comment";
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	RECURRING	NULL	20	INTERVAL_SECOND	#	#	ENABLED
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+starts IS NULL	ends IS NULL	comment
+0	0	non-empty comment
+ALTER EVENT event_starts_test COMMENT "";
+SHOW EVENTS;
+Db	Name	Definer	Type	Execute at	Interval value	Interval field	Starts	Ends	Status
+events_test	event_starts_test	root@localhost	RECURRING	NULL	20	INTERVAL_SECOND	#	#	ENABLED
+DROP EVENT event_starts_test;
 create event e_43 on schedule every 1 second do set @a = 5;
 set global event_scheduler = 1;
 alter event e_43 do alter event e_43 do set @a = 4;

--- 1.21/mysql-test/t/events.test	2006-02-16 16:10:54 +01:00
+++ 1.22/mysql-test/t/events.test	2006-02-28 11:46:00 +01:00
@@ -48,6 +48,38 @@ drop event event2;
 create event event2 on schedule every 2 second starts now() ends date_add(now(), interval 5 hour) comment "some" DO begin end;
 drop event event2;
 
+# BUG #16537 (Events: mysql.event.starts is null)
+CREATE EVENT event_starts_test ON SCHEDULE EVERY 10 SECOND COMMENT "" DO SELECT 1;
+--replace_column 8 # 9 #
+SHOW EVENTS;
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+ALTER EVENT event_starts_test ON SCHEDULE AT '2020-02-02 20:00:02';
+--replace_column 8 # 9 #
+SHOW EVENTS;
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+ALTER EVENT event_starts_test COMMENT "non-empty comment";
+--replace_column 8 # 9 #
+SHOW EVENTS;
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+ALTER EVENT event_starts_test COMMENT "";
+--replace_column 8 # 9 #
+SHOW EVENTS;
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+DROP EVENT event_starts_test;
+CREATE EVENT event_starts_test ON SCHEDULE EVERY 20 SECOND STARTS '2020-02-02 20:00:02' ENDS '2022-02-02 20:00:02' DO SELECT 2;
+--replace_column 8 # 9 #
+SHOW EVENTS;
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+ALTER EVENT event_starts_test COMMENT "non-empty comment";
+--replace_column 8 # 9 #
+SHOW EVENTS;
+SELECT starts IS NULL, ends IS NULL, comment FROM mysql.event WHERE db='events_test' AND name='event_starts_test';
+ALTER EVENT event_starts_test COMMENT "";
+--replace_column 8 # 9 #
+SHOW EVENTS;
+DROP EVENT event_starts_test;
+#
+#
 create event e_43 on schedule every 1 second do set @a = 5;
 set global event_scheduler = 1;
 --sleep 2

--- 1.33/sql/event.cc	2006-02-26 14:11:52 +01:00
+++ 1.34/sql/event.cc	2006-02-28 11:46:00 +01:00
@@ -637,20 +637,6 @@ evex_fill_row(THD *thd, TABLE *table, ev
       goto trunc_err;
   }
 
-  if (et->starts.year)
-  {
-    table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF
-    table->field[EVEX_FIELD_STARTS]->
-                          store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME);
-  }	   
-
-  if (et->ends.year)
-  {
-    table->field[EVEX_FIELD_ENDS]->set_notnull();
-    table->field[EVEX_FIELD_ENDS]->
-                          store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME);
-  }
-   
   if (et->expression)
   {
     table->field[EVEX_FIELD_INTERVAL_EXPR]->set_notnull();
@@ -664,18 +650,31 @@ evex_fill_row(THD *thd, TABLE *table, ev
     table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong)et->interval+1);
 
     table->field[EVEX_FIELD_EXECUTE_AT]->set_null();
+
+    if (!et->starts_null)
+    {
+      table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF
+      table->field[EVEX_FIELD_STARTS]->
+                            store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME);
+    }	   
+
+    if (!et->ends_null)
+    {
+      table->field[EVEX_FIELD_ENDS]->set_notnull();
+      table->field[EVEX_FIELD_ENDS]->
+                            store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME);
+    }
   }
   else if (et->execute_at.year)
   {
-    // fix_fields already called in init_execute_at
     table->field[EVEX_FIELD_INTERVAL_EXPR]->set_null();
     table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null();
-
+    table->field[EVEX_FIELD_STARTS]->set_null();
+    table->field[EVEX_FIELD_ENDS]->set_null();
+    
     table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull();
     table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->execute_at,
                                                     MYSQL_TIMESTAMP_DATETIME);    
-    
-    table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->set_null();  
   }
   else
   {
@@ -686,14 +685,17 @@ evex_fill_row(THD *thd, TABLE *table, ev
     
   ((Field_timestamp *)table->field[EVEX_FIELD_MODIFIED])->set_time();
 
-  if (et->comment.length)
-    if (table->field[field_num= EVEX_FIELD_COMMENT]->
-	store(et->comment.str, et->comment.length, system_charset_info))
+  if (et->comment.str)
+  {
+    if (table->field[field_num= EVEX_FIELD_COMMENT]->store(et->comment.str,
+                                                           et->comment.length,
+                                                           system_charset_info))
       goto trunc_err;
+  }
 
   DBUG_RETURN(0);
 trunc_err:
-  my_error(ER_EVENT_DATA_TOO_LONG, MYF(0));
+  my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), table->field[field_num]->field_name);
   DBUG_RETURN(EVEX_GENERAL_ERROR);
 }
 
@@ -806,14 +808,16 @@ db_create_event(THD *thd, event_timed *e
     my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
     goto err;
   }
-  
+
+#ifdef USE_THIS_CODE_AS_TEMPLATE_WHEN_EVENT_REPLICATION_IS_AGREED   
   if (mysql_bin_log.is_open())
   {
     thd->clear_error();
-    /* Such a statement can always go directly to binlog, no trans cache */
+    // Such a statement can always go directly to binlog, no trans cache
     thd->binlog_query(THD::MYSQL_QUERY_TYPE,
                       thd->query, thd->query_length, FALSE, FALSE);
   }
+#endif
   
   *rows_affected= 1;
 ok:

--- 1.24/sql/event.h	2006-02-24 12:00:28 +01:00
+++ 1.25/sql/event.h	2006-02-28 11:46:00 +01:00
@@ -103,6 +103,9 @@ public:
   TIME starts;
   TIME ends;
   TIME execute_at;
+  my_bool starts_null;
+  my_bool ends_null;
+  my_bool execute_at_null;
 
   longlong expression;
   interval_type interval;

--- 1.34/sql/event_executor.cc	2006-02-26 14:11:52 +01:00
+++ 1.35/sql/event_executor.cc	2006-02-28 12:08:07 +01:00
@@ -523,8 +523,7 @@ restart_ticking:
     et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*);
     DBUG_PRINT("evex main thread",("got event from the queue"));
       
-    if (et->execute_at.year > 1969 &&
-        my_time_compare(&time_now, &et->execute_at) == -1)
+    if (!et->execute_at_null && my_time_compare(&time_now,&et->execute_at) == -1)
     {
       DBUG_PRINT("evex main thread",("still not the time for execution"));
       VOID(pthread_mutex_unlock(&LOCK_event_arrays));
@@ -571,8 +570,11 @@ restart_ticking:
 #else
       event_executor_worker((void *) et);
 #endif
-      if ((et->execute_at.year && !et->expression) ||
-           TIME_to_ulonglong_datetime(&et->execute_at) == 0)
+      /*
+        1. For one-time event : year is > 0 and expression is 0
+        2. For recurring, expression is != -=> check execute_at_null in this case
+      */
+      if ((et->execute_at.year && !et->expression) || et->execute_at_null)
          et->flags |= EVENT_EXEC_NO_MORE;
 
       if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED)

--- 1.38/sql/event_timed.cc	2006-02-24 14:02:14 +01:00
+++ 1.39/sql/event_timed.cc	2006-02-28 12:08:08 +01:00
@@ -41,6 +41,7 @@ event_timed::init()
   set_zero_time(&ends, MYSQL_TIMESTAMP_DATETIME);
   set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
   set_zero_time(&last_executed, MYSQL_TIMESTAMP_DATETIME);
+  starts_null= ends_null= execute_at_null= TRUE;
 
   definer_user.str= definer_host.str= 0;
   definer_user.length= definer_host.length= 0;
@@ -157,10 +158,15 @@ event_timed::init_execute_at(THD *thd, I
 
   if (expr->fix_fields(thd, &expr))
     DBUG_RETURN(EVEX_PARSE_ERROR);
-
-  /* Let's check whether time is in the past */
-  thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,
-                                            (my_time_t) thd->query_start());
+  
+  /* no starts and/or ends in case of execute_at */
+  DBUG_PRINT("info", ("starts_null && ends_null should be 1 is %d",
+              (starts_null && ends_null)))
+  DBUG_ASSERT(starts_null && ends_null);
+  
+  // let's check whether time is in the past
+  thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, 
+                                            (my_time_t) thd->query_start()); 
 
 
   if ((not_used= expr->get_date(&ltime, TIME_NO_ZERO_DATE)))
@@ -177,7 +183,7 @@ event_timed::init_execute_at(THD *thd, I
   */
   my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd,&ltime, &not_used));
 
-
+  execute_at_null= FALSE;
   execute_at= ltime;
   DBUG_RETURN(0);
 }
@@ -332,6 +338,7 @@ event_timed::init_starts(THD *thd, Item 
   my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd, &ltime, &not_used));
 
   starts= ltime;
+  starts_null= FALSE;
   DBUG_RETURN(0);
 }
 
@@ -361,8 +368,7 @@ event_timed::init_starts(THD *thd, Item 
 int
 event_timed::init_ends(THD *thd, Item *new_ends)
 {
-  TIME ltime;
-  my_time_t my_time_tmp;
+  TIME ltime, ltime_now;
   my_bool not_used;
 
   DBUG_ENTER("event_timed::init_ends");
@@ -370,20 +376,34 @@ event_timed::init_ends(THD *thd, Item *n
   if (new_ends->fix_fields(thd, &new_ends))
     DBUG_RETURN(EVEX_PARSE_ERROR);
 
-  /* The field was already fixed in init_ends */
+  DBUG_PRINT("info", ("convert to TIME"));
   if ((not_used= new_ends->get_date(&ltime, TIME_NO_ZERO_DATE)))
     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 ?
   */
+  DBUG_PRINT("info", ("get the UTC time"));
   my_tz_UTC->gmt_sec_to_TIME(&ltime, TIME_to_timestamp(thd, &ltime, &not_used));
 
-  if (starts.year && my_time_compare(&starts, &ltime) != -1)
+  /* Check whether ends is after starts */
+  DBUG_PRINT("info", ("ENDS after STARTS?"));
+  if (!starts_null && my_time_compare(&starts, &ltime) != -1)
+    DBUG_RETURN(EVEX_BAD_PARAMS);
+
+  /*
+    The parser forces starts to be provided but one day STARTS could be
+    set before NOW() and in this case the following check should be done.
+    Check whether ENDS is not in the past.
+  */
+  DBUG_PRINT("info", ("ENDS after NOW?"));
+  my_tz_UTC->gmt_sec_to_TIME(&ltime_now, thd->query_start());  
+  if (my_time_compare(&ltime_now, &ltime) == 1)
     DBUG_RETURN(EVEX_BAD_PARAMS);
 
   ends= ltime;
+  ends_null= FALSE;
   DBUG_RETURN(0);
 }
 
@@ -403,7 +423,7 @@ event_timed::init_comment(THD *thd, LEX_
   DBUG_ENTER("event_timed::init_comment");
 
   comment.str= strmake_root(thd->mem_root, set_comment->str,
-                              comment.length= set_comment->length);
+                            comment.length= set_comment->length);
 
   DBUG_VOID_RETURN;
 }
@@ -517,29 +537,38 @@ event_timed::load_from_row(MEM_ROOT *mem
   len= et->definer.length - len - 1; //1 is because of @
   et->definer_host.str= strmake_root(mem_root, ptr + 1, len);//1: because of @
   et->definer_host.length= len;
+  
+  et->starts_null= table->field[EVEX_FIELD_STARTS]->is_null();
+  res1= table->field[EVEX_FIELD_STARTS]->get_date(&et->starts,TIME_NO_ZERO_DATE);
 
-  res1= table->field[EVEX_FIELD_STARTS]->
-                     get_date(&et->starts, TIME_NO_ZERO_DATE);
-
-  res2= table->field[EVEX_FIELD_ENDS]->
-                     get_date(&et->ends, TIME_NO_ZERO_DATE);
-
-  et->expression= table->field[EVEX_FIELD_INTERVAL_EXPR]->val_int();
-
+  et->ends_null= table->field[EVEX_FIELD_ENDS]->is_null();
+  res2= table->field[EVEX_FIELD_ENDS]->get_date(&et->ends, TIME_NO_ZERO_DATE);
+  
+  if (!table->field[EVEX_FIELD_INTERVAL_EXPR]->is_null())
+    et->expression= table->field[EVEX_FIELD_INTERVAL_EXPR]->val_int();
+  else
+    et->expression= 0;
   /*
     If res1 and res2 are true then both fields are empty.
     Hence if EVEX_FIELD_EXECUTE_AT is empty there is an error.
   */
-  if (res1 && res2 && !et->expression && table->field[EVEX_FIELD_EXECUTE_AT]->
-                get_date(&et->execute_at, TIME_NO_ZERO_DATE))
+  et->execute_at_null= table->field[EVEX_FIELD_EXECUTE_AT]->is_null();
+  DBUG_ASSERT(!(et->starts_null && et->ends_null && !et->expression &&
+              et->execute_at_null));
+  if (!et->expression &&
+      table->field[EVEX_FIELD_EXECUTE_AT]->get_date(&et->execute_at,
+                                                     TIME_NO_ZERO_DATE))
     goto error;
 
   /*
     In DB the values start from 1 but enum interval_type starts
     from 0
   */
-  et->interval= (interval_type)
+  if (!table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->is_null())
+    et->interval= (interval_type)
        ((ulonglong) table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->val_int() - 1);
+  else
+    et->interval= (interval_type) 0;
 
   et->modified= table->field[EVEX_FIELD_CREATED]->val_int();
   et->created= table->field[EVEX_FIELD_MODIFIED]->val_int();
@@ -698,14 +727,11 @@ event_timed::compute_next_execution_time
     /* Let's check whether it was executed */
     if (last_executed.year)
     {
-      DBUG_PRINT("compute_next_execution_time",
-                ("One-time event %s was already executed", name.str));
-      if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
-      {
-        DBUG_PRINT("compute_next_execution_time",
-                          ("One-time event will be dropped."));
-        dropped= true;
-      }
+      DBUG_PRINT("info",("One-time event %s.%s of was already executed",
+                         dbname.str, name.str, definer.str));
+      dropped= (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP);
+      DBUG_PRINT("info",("One-time event will be dropped=%d.", dropped));
+
       status= MYSQL_EVENT_DISABLED;
       status_changed= true;
     }
@@ -731,11 +757,12 @@ event_timed::compute_next_execution_time
                         last_executed.second);
 #endif
 
-  /* If time_now is after ends don't execute anymore */
-  if (ends.year && (tmp= my_time_compare(&ends, &time_now)) == -1)
+  /* if time_now is after ends don't execute anymore */
+  if (!ends_null && (tmp= my_time_compare(&ends, &time_now)) == -1)
   {
     /* time_now is after ends. don't execute anymore */
     set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
+    execute_at_null= TRUE;
     if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
       dropped= true;
     status= MYSQL_EVENT_DISABLED;
@@ -749,7 +776,7 @@ event_timed::compute_next_execution_time
     Let's check whether time_now is before starts.
     If so schedule for starts.
   */
-  if (starts.year && (tmp= my_time_compare(&time_now, &starts)) < 1)
+  if (!starts_null && (tmp= my_time_compare(&time_now, &starts)) < 1)
   {
     if (tmp == 0 && my_time_compare(&starts, &last_executed) == 0)
     {
@@ -765,11 +792,12 @@ event_timed::compute_next_execution_time
         time_now before starts. Scheduling for starts
       */
       execute_at= starts;
+      execute_at_null= FALSE;
       goto ret;
     }
   }
-
-  if (starts.year && ends.year)
+  
+  if (!starts_null && !ends_null)
   {
     /*
       Both starts and m_ends are set and time_now is between them (incl.)
@@ -778,7 +806,10 @@ event_timed::compute_next_execution_time
       If not set then schedule for now.
     */
     if (!last_executed.year)
+    {
       execute_at= time_now;
+      execute_at_null= FALSE;
+    }
     else
     {
       TIME next_exec;
@@ -791,15 +822,19 @@ event_timed::compute_next_execution_time
       {
         /* Next execution after ends. No more executions */
         set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
+        execute_at_null= TRUE;
         if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
           dropped= true;
       }
       else
+      {
         execute_at= next_exec;
+        execute_at_null= FALSE;
+      }
     }
     goto ret;
   }
-  else if (!starts.year && !ends.year)
+  else if (starts_null && ends_null)
   {
     /*
       Both starts and m_ends are not set, so we schedule for the next
@@ -815,11 +850,12 @@ event_timed::compute_next_execution_time
       /* last_executed not set. Schedule the event for now */
       execute_at= time_now;
     }
+    execute_at_null= FALSE;
   }
   else
   {
-    /* Either starts or m_ends is set */
-    if (starts.year)
+    /* either starts or m_ends is set */
+    if (!starts_null)
     {
       /*
         - starts is set.
@@ -834,6 +870,7 @@ event_timed::compute_next_execution_time
       }
       else
         execute_at= starts;
+      execute_at_null= FALSE;
     }
     else
     {
@@ -856,11 +893,15 @@ event_timed::compute_next_execution_time
         if (my_time_compare(&ends, &next_exec) == -1)
         {
           set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
+          execute_at_null= TRUE;
           if (on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
             dropped= true;
         }
         else
+        {
           execute_at= next_exec;
+          execute_at_null= FALSE;
+        }
       }
     }
     goto ret;
@@ -1324,10 +1365,7 @@ event_timed::compile(THD *thd, MEM_ROOT 
 
   sphead= lex.et->sphead;
   sphead->m_db= dbname;
-  /*
-    Ccopy also chistics since they will vanish otherwise we get 0x0 pointer
-    TODO: Handle sql_mode!!
-  */
+
   sphead->set_definer(definer.str, definer.length);
   sphead->set_info(0, 0, &lex.sp_chistics, sql_mode);
   sphead->optimize();
Thread
bk commit into 5.1 tree (andrey:1.2191)ahristov28 Feb