Commit 6bd58a2a authored by unknown's avatar unknown
Browse files

- fix bug #16435 (Weekly events execute every second) (WL#1034 Internal CRON)

Before the interval expression was considered to be in seconds, now it is
just a number and the type of interval is considered.

- this changeset introduces also fix for bug#16432 (Events: error re interval
  misrepresents the facts)
  the code of event_timed::set_interval() was refactored anyway so it is meaningful to
  fix the bug in the same changeset.


include/my_time.h:
  - move enum interval_type to include/my_time.h so it can be used by functions
    in the whole server
sql/event.cc:
  - don't use second_part
  - fix small problem with create event xyz, when xyz exists -> make it error
    instead of warning if create_if_not is false.
sql/event.h:
  pass thd to mark_last_executed() to be able to call thd->end_time()
sql/event_executor.cc:
  - pass thd to event_timed::compute_next_execution_time()
  - a bit more DBUG info in the server log
  - handle error returned by event_timed::compute_next_execution_time()
sql/event_priv.h:
  - define the maximal possible value for interval_value
sql/event_timed.cc:
  - more docs
  - add static get_next_time() which sums a TIME with an interval
  - fix bug #16435 (Weekly events execute every second)
  Before the interval expression was considered to be in seconds, now it is
  just a number and the type of interval is considered.
  - fix for bug#16432 (Events: error re interval misrepresents the facts)
    (return an error if a value is too big or is negative - errmsg changed)
sql/item_timefunc.cc:
  - export get_interval_date()
  - refactor Item_date_add_interval::get_date() and extract the core
    to date_add_interval() in time.cc so it can be reused by the
    scheduler code in event_timed.cc
sql/item_timefunc.h:
  - export get_interval_value() so it can be reused in event_timed.cc in
    function static get_next_time()
  - move enum interval_type to include/my_time.h so it can be used by functions
    in the whole server
sql/mysql_priv.h:
  export the new function date_add_interval() added to time.cc
sql/share/errmsg.txt:
  - change error message to be appropriate as fix for bug#16432
    (Events: error re interval misrepresents the facts)
sql/sql_yacc.yy:
  - change error message to be appropriate as fix for bug#16432
    (Events: error re interval misrepresents the facts)
sql/time.cc:
  extract the core of Item_date_add_interval::get_date()
  to a function per Serg's request. The code can be reused
  to add und substract interval from a date.
parent ef3a6106
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -89,6 +89,21 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to);
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);

/*
  The following must be sorted so that simple intervals comes first.
  (get_interval_value() depends on this)
*/

enum interval_type
{
  INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR,
  INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND ,
  INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE,
  INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND,
  INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND,
  INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND
};

C_MODE_END

#endif /* _my_time_h_ */
+15 −4
Original line number Diff line number Diff line
@@ -88,8 +88,14 @@ int sortcmp_lex_string(LEX_STRING s, LEX_STRING t, CHARSET_INFO *cs)
int
my_time_compare(TIME *a, TIME *b)
{

#ifdef ENABLE_WHEN_WE_HAVE_MILLISECOND_IN_TIMESTAMPS
  my_ulonglong a_t= TIME_to_ulonglong_datetime(a)*100L + a->second_part;
  my_ulonglong b_t= TIME_to_ulonglong_datetime(b)*100L + b->second_part;
#else
  my_ulonglong a_t= TIME_to_ulonglong_datetime(a);
  my_ulonglong b_t= TIME_to_ulonglong_datetime(b);
#endif

  if (a_t > b_t)
    return 1;
@@ -354,12 +360,17 @@ db_create_event(THD *thd, event_timed *et, my_bool create_if_not,

  DBUG_PRINT("info", ("check existance of an event with the same name"));
  if (!evex_db_find_event_aux(thd, et->dbname, et->name, table))
  {
    if (create_if_not)
    {
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
		          ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS),
		          et->name.str);
      goto ok;    
    }
    my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->name.str);
    goto err;
  }

  DBUG_PRINT("info", ("non-existant, go forward"));
  if ((ret= sp_use_new_db(thd, et->dbname.str,olddb, sizeof(olddb),0, &dbchanged)))
+2 −2
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ class event_timed
  compute_next_execution_time();  

  void
  mark_last_executed();
  mark_last_executed(THD *thd);
  
  int
  drop(THD *thd);
+19 −4
Original line number Diff line number Diff line
@@ -334,9 +334,19 @@ event_executor_main(void *arg)
    {
      pthread_t th;

      DBUG_PRINT("evex main thread",("mark_last_executed"));
      et->mark_last_executed();
      et->compute_next_execution_time();
      DBUG_PRINT("evex main thread", ("[%10s] this exec at [%llu]", et->name.str,
                               TIME_to_ulonglong_datetime(&et->execute_at)));
      et->mark_last_executed(thd);
      if (et->compute_next_execution_time())
      {
        sql_print_error("Error while computing time of %s.%s . "
                        "Disabling after execution.",
                        et->dbname.str, et->name.str);
        et->status= MYSQL_EVENT_DISABLED;
      }
      DBUG_PRINT("evex main thread", ("[%10s] next exec at [%llu]", et->name.str,
                               TIME_to_ulonglong_datetime(&et->execute_at)));

      et->update_fields(thd);
      DBUG_PRINT("info", ("  Spawning a thread %d", ++iter_num));
#ifndef DBUG_FAULTY_THR
@@ -599,7 +609,12 @@ evex_load_events_from_db(THD *thd)
    }
    
    // let's find when to be executed  
    et->compute_next_execution_time();
    if (et->compute_next_execution_time())
    {
      sql_print_error("Error while computing execution time of %s.%s. Skipping",
                       et->dbname.str, et->name.str);
      continue;
    }
    
    DBUG_PRINT("evex_load_events_from_db", ("Adding to the exec list."));

+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ enum evex_table_field

#define EVEX_DB_FIELD_LEN 64
#define EVEX_NAME_FIELD_LEN 64
#define EVEX_MAX_INTERVAL_VALUE 2147483647L

int
my_time_compare(TIME *a, TIME *b);
Loading