Commit ef9a97e6 authored by unknown's avatar unknown
Browse files

WL#3337 (Event scheduler new architecture)

Third cut to simplify parsing phase. Now DROP EVENT works.

Overloaded few functions to be able to use either sp_name or pass two LEX_STRINGs
instead of a Event_timed pointer. This is transitional and eventually the old
functions will be removed. For now DROP EVENT also works, does not need anymore
a parsing object (Event_timed) and definer initialization because everyone who
has EVENT_ACL can drop events, and this is checked on execution time in sql_parse.cc
from the security context, as it should be.


sql/event_data_objects.cc:
  overload few functions
sql/event_scheduler.cc:
  Event_scheduler::drop_event() actually does not need Event_timed object
  but just an identifier, hence pass only sp_name.
  
  Overloaded Event_scheduler::find_event() to work with sp_name object. Eventually
  the old version will be removed. This is being done as transitional step to
  be able to test frequently code.
sql/event_scheduler.h:
  Event_scheduler::drop_event() actually does not need Event_timed object
  but just an identifier, hence pass only sp_name.
  
  Overloaded Event_scheduler::find_event() to work with sp_name object. Eventually
  the old version will be removed. This is being done as transitional step to
  be able to test frequently code.
sql/events.cc:
  Change db_drop_event() not to use Event_timed, either coming from parsing
  or from Event_timed::drop, but use LEX_STRINGs. sp_name is not convinient
  because in Event_timed::drop a temporary object has to be created. Hence, 
  dereference the sp_name in Events::drop_event() and pass the LEX_STRINGs.
sql/events.h:
  Change db_drop_event() not to use Event_timed, either coming from parsing
  or from Event_timed::drop, but use LEX_STRINGs. sp_name is not convinient
  because in Event_timed::drop a temporary object has to be created. Hence, 
  dereference the sp_name in Events::drop_event() and pass the LEX_STRINGs.
sql/events_priv.h:
  Change db_drop_event() not to use Event_timed, either coming from parsing
  or from Event_timed::drop, but use LEX_STRINGs. sp_name is not convinient
  because in Event_timed::drop a temporary object has to be created. Hence, 
  dereference the sp_name in Events::drop_event() and pass the LEX_STRINGs.
sql/sql_parse.cc:
  SQLCOM_DROP_EVENT does not need lex->event_parse_data object and 
  is more like SQLCOM_SHOW_CREATE_EVENT. Therefore, move it to the block that
  handles the latter.
sql/sql_yacc.yy:
  DROP EVENT does not need a parsing object, just a name.
  Store it as lex->spname. Pretty similar handling to the one of
  SHOW CREATE EVENT.
parent d2db48c6
Loading
Loading
Loading
Loading
+57 −3
Original line number Diff line number Diff line
@@ -1299,7 +1299,7 @@ Event_timed::drop(THD *thd)
  uint tmp= 0;
  DBUG_ENTER("Event_timed::drop");

  DBUG_RETURN(db_drop_event(thd, this, false, &tmp));
  DBUG_RETURN(db_drop_event(thd, dbname, name, false, &tmp));
}


@@ -1903,8 +1903,62 @@ bool
event_timed_identifier_equal(Event_timed *a, Event_timed *b)
{
  return event_timed_name_equal(a, &b->name) &&
         event_timed_db_equal(a, &b->dbname) &&
         event_timed_definer_equal(a, &b->definer);
         event_timed_db_equal(a, &b->dbname);
}


/*
  Checks whether two events have the same name

  SYNOPSIS
    event_timed_name_equal()

  RETURN VALUE
    TRUE  names are equal
    FALSE names are not equal
*/

bool
event_timed_name_equal(sp_name *name, LEX_STRING *event_name)
{
  return !sortcmp_lex_string(name->m_name, *event_name, system_charset_info);
}


/*
  Checks whether two events are in the same schema

  SYNOPSIS
    event_timed_db_equal()

  RETURN VALUE
    TRUE  schemas are equal
    FALSE schemas are not equal
*/

bool
event_timed_db_equal(sp_name *name, LEX_STRING *db)
{
  return !sortcmp_lex_string(name->m_db, *db, system_charset_info);
}


/*
  Checks whether two events are equal by identifiers

  SYNOPSIS
    event_timed_identifier_equal()

  RETURN VALUE
    TRUE   equal
    FALSE  not equal
*/

bool
event_timed_identifier_equal(sp_name *a, Event_timed *b)
{
  return event_timed_name_equal(a, &b->name) &&
         event_timed_db_equal(a, &b->dbname);
}


+46 −3
Original line number Diff line number Diff line
@@ -833,12 +833,13 @@ Event_scheduler::create_event(THD *thd, Event_timed *et, bool check_existence)
*/

bool
Event_scheduler::drop_event(THD *thd, Event_timed *et)
Event_scheduler::drop_event(THD *thd, sp_name *name)
{
  int res;
  Event_timed *et_old;
  DBUG_ENTER("Event_scheduler::drop_event");
  DBUG_PRINT("enter", ("thd=%p et=%p lock=%p",thd,et,&LOCK_scheduler_data));
  DBUG_PRINT("enter", ("thd=%p name=%p lock=%p", thd, name,
             &LOCK_scheduler_data));

  LOCK_SCHEDULER_DATA();
  if (!is_running_or_suspended())
@@ -848,7 +849,7 @@ Event_scheduler::drop_event(THD *thd, Event_timed *et)
    DBUG_RETURN(OP_OK);
  }

  if (!(et_old= find_event(et, TRUE)))
  if (!(et_old= find_event(name, TRUE)))
    DBUG_PRINT("info", ("No such event found, probably DISABLED"));

  UNLOCK_SCHEDULER_DATA();
@@ -1049,6 +1050,48 @@ Event_scheduler::find_event(Event_timed *etn, bool remove_from_q)
}


/*
  Searches for an event in the scheduler queue

  SYNOPSIS
    Event_scheduler::find_event()
      name           The event to find
      comparator     The function to use for comparing
      remove_from_q  If found whether to remove from the Q

  RETURN VALUE
    NULL       Not found
    otherwise  Address

  NOTE
    The caller should do the locking also the caller is responsible for
    actual signalling in case an event is removed from the queue 
    (signalling COND_new_work for instance).
*/

Event_timed *
Event_scheduler::find_event(sp_name *name, bool remove_from_q)
{
  uint i;
  DBUG_ENTER("Event_scheduler::find_event");

  for (i= 0; i < queue.elements; ++i)
  {
    Event_timed *et= (Event_timed *) queue_element(&queue, i);
    DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?", name->m_db.str, name->m_name.str,
                        et->dbname.str, et->name.str));
    if (event_timed_identifier_equal(name, et))
    {
      if (remove_from_q)
        queue_remove(&queue, i);
      DBUG_RETURN(et);
    }
  }

  DBUG_RETURN(NULL);
}


/*
  Drops all events from the in-memory queue and disk that match
  certain pattern evaluated by a comparator function
+5 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

class sp_name;
class Event_timed;

class THD;
@@ -73,7 +74,7 @@ class Event_scheduler
                LEX_STRING *new_name);

  bool
  drop_event(THD *thd, Event_timed *et);
  drop_event(THD *thd, sp_name *name);


  int
@@ -136,6 +137,9 @@ class Event_scheduler
  Event_timed *
  find_event(Event_timed *etn, bool remove_from_q);

  Event_timed *
  find_event(sp_name *name, bool remove_from_q);

  uint
  workers_count();

+12 −15
Original line number Diff line number Diff line
@@ -988,14 +988,15 @@ Events::update_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
    !0  Error (my_error() called)
*/

int db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists,
                  uint *rows_affected)
int db_drop_event(THD *thd, LEX_STRING db, LEX_STRING name,
                  bool drop_if_exists, uint *rows_affected)
{
  TABLE *table;
  Open_tables_state backup;
  int ret;

  DBUG_ENTER("db_drop_event");
  DBUG_PRINT("enter", ("db=%s name=%s", db.str, name.str));
  ret= EVEX_OPEN_TABLE_FAILED;

  thd->reset_n_backup_open_tables_state(&backup);
@@ -1005,13 +1006,10 @@ int db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists,
    goto done;
  }

  if (!(ret= evex_db_find_event_aux(thd, et, table)))
  if (!(ret= evex_db_find_event_by_name(thd, db, name, table)))
  {
    if ((ret= table->file->ha_delete_row(table->record[0])))
    { 	
      my_error(ER_EVENT_CANNOT_DELETE, MYF(0));
      goto done;
    }
  }
  else if (ret == EVEX_KEY_NOT_FOUND)
  { 
@@ -1019,14 +1017,12 @@ int db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists,
    {
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                          ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
                          "Event", et->name.str);
                          "Event", name.str);
      ret= 0;
    } else
      my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->name.str);
    goto done;
      my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name.str);
  }


done:
  /*
    evex_drop_event() is used by Event_timed::drop therefore
@@ -1044,7 +1040,7 @@ int db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists,
  SYNOPSIS
    Events::drop_event()
      thd             THD
      et              event's name
      name            event's name
      drop_if_exists  if set and the event not existing => warning onto the stack
      rows_affected   affected number of rows is returned heres

@@ -1054,16 +1050,17 @@ int db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists,
*/

int
Events::drop_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
                   bool drop_if_exists, uint *rows_affected)
Events::drop_event(THD *thd, sp_name *name, bool drop_if_exists,
                   uint *rows_affected)
{
  int ret;

  DBUG_ENTER("Events::drop_event");
  if (!(ret= db_drop_event(thd, et, drop_if_exists, rows_affected)))
  if (!(ret= db_drop_event(thd, name->m_db, name->m_name, drop_if_exists,
                           rows_affected)))
  {
    Event_scheduler *scheduler= Event_scheduler::get_instance();
    if (scheduler->initialized() && (ret= scheduler->drop_event(thd, et)))
    if (scheduler->initialized() && (ret= scheduler->drop_event(thd, name)))
      my_error(ER_EVENT_MODIFY_QUEUE_ERROR, MYF(0), ret);
  }

+2 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


class sp_name;
class Event_timed;
class Event_parse_data;

@@ -56,8 +56,7 @@ class Events
               sp_name *new_name, uint *rows_affected);

  static int
  drop_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
             bool drop_if_exists, uint *rows_affected);
  drop_event(THD *thd, sp_name *name, bool drop_if_exists, uint *rows_affected);

  static int
  open_event_table(THD *thd, enum thr_lock_type lock_type, TABLE **table);
Loading