Commit c1cb8db8 authored by unknown's avatar unknown
Browse files

- last bits of unneeded error checking in sql_parse.cc thrown away

- fix a bug introduced with last commit ALTER EVENT a RENAME TO b; failed
- misc


sql/event.cc:
  - rename evex_db_find_routine_aux() to evex_db_find_event_aux() (better name)
  - change parameter order of db_update_event()
  - last bits to handle errors as close as possible to the place they occur
  - fix a bug introduced with last commit: first check for overwriting and event and then
    check whether the original one exists
sql/event.h:
  add a new error code returned by event_timed::compile() in case of 
  error
sql/event_priv.h:
  rename
sql/event_timed.cc:
  - function rename
  - add a bit of doc
sql/share/errmsg.txt:
  - extend an error message so it's more informative
  - add a new error message
sql/sql_parse.cc:
  refactor the cases for CREATE/ALTER/DROP event so use as much common
  code as possible. last bits of error checking unneeded in sql_parse.cc
  thrwon out.
parent faa8995e
Loading
Loading
Loading
Loading
+62 −44
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ TABLE *evex_open_event_table(THD *thd, enum thr_lock_type lock_type)
  Find row in open mysql.event table representing event

  SYNOPSIS
    evex_db_find_routine_aux()
    evex_db_find_event_aux()
      thd    Thread context
      dbname Name of event's database
      rname  Name of the event inside the db  
@@ -200,15 +200,15 @@ TABLE *evex_open_event_table(THD *thd, enum thr_lock_type lock_type)

  RETURN VALUE
    0                  - Routine found
    SP_KEY_NOT_FOUND- No routine with given name
    EVEX_KEY_NOT_FOUND - No routine with given name
*/

int
evex_db_find_routine_aux(THD *thd, const LEX_STRING dbname,
evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
                       const LEX_STRING ev_name, TABLE *table)
{
  byte key[MAX_KEY_LENGTH];	// db, name, optional key length type
  DBUG_ENTER("evex_db_find_routine_aux");
  byte key[MAX_KEY_LENGTH];
  DBUG_ENTER("evex_db_find_event_aux");
  DBUG_PRINT("enter", ("name: %.*s", ev_name.length, ev_name.str));

  /*
@@ -218,7 +218,8 @@ evex_db_find_routine_aux(THD *thd, const LEX_STRING dbname,
    'db' and 'name' and the first key is the primary key over the
    same fields.
  */
  if (ev_name.length > table->field[1]->field_length)
  if (dbname.length > table->field[EVEX_FIELD_DB]->field_length ||
      ev_name.length > table->field[EVEX_FIELD_NAME]->field_length)
    DBUG_RETURN(EVEX_KEY_NOT_FOUND);

  table->field[0]->store(dbname.str, dbname.length, &my_charset_bin);
@@ -337,6 +338,9 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update)
       thd  THD
       et   event_timed object containing information for the event 
   
     Return value
                        0 - OK
       EVEX_GENERAL_ERROR - Failure
   DESCRIPTION 
     Creates an event. Relies on evex_fill_row which is shared with 
     db_update_event. The name of the event is inside "et".
@@ -362,7 +366,7 @@ db_create_event(THD *thd, event_timed *et)
  }

  DBUG_PRINT("info", ("check existance of an event with the same name"));
  if (!evex_db_find_routine_aux(thd, et->dbname, et->name, table))
  if (!evex_db_find_event_aux(thd, et->dbname, et->name, table))
  {
    my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->name.str);
    goto err;    
@@ -377,7 +381,6 @@ db_create_event(THD *thd, event_timed *et)
  
  restore_record(table, s->default_values); // Get default values for fields


  if (et->name.length > table->field[EVEX_FIELD_NAME]->field_length)
  {
    my_error(ER_TOO_LONG_IDENT, MYF(0), et->name.str);
@@ -393,27 +396,27 @@ db_create_event(THD *thd, event_timed *et)
  {
    DBUG_PRINT("error", ("neither expression nor execute_at are set!"));
    my_error(ER_EVENT_NEITHER_M_EXPR_NOR_M_AT, MYF(0));    
    
    goto err;
  }

  strxmov(definer, et->definer_user.str, "@", et->definer_host.str, NullS);
  if (table->field[EVEX_FIELD_DEFINER]->
  if ((ret=table->field[EVEX_FIELD_DEFINER]->
       store(definer, et->definer_user.length + 1 + et->definer_host.length,
             system_charset_info))
             system_charset_info)))
  {
    my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str);
    my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
    goto err;
  }

  ((Field_timestamp *)table->field[EVEX_FIELD_CREATED])->set_time();

  // evex_fill_row() calls my_error() in case of error so no need to handle it here
  if ((ret= evex_fill_row(thd, table, et, false)))
    goto err; 

  ret= EVEX_OK;
  if (table->file->write_row(table->record[0]))
  {
    my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str);
    my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
    goto err;
  }
  
@@ -438,7 +441,7 @@ db_create_event(THD *thd, event_timed *et)


/*
   Used to execute ALTER EVENT
   Used to execute ALTER EVENT. Pendant to evex_update_event().

   SYNOPSIS
     db_update_event()
@@ -452,7 +455,7 @@ db_create_event(THD *thd, event_timed *et)
*/

static int
db_update_event(THD *thd, sp_name *new_name, event_timed *et)
db_update_event(THD *thd, event_timed *et, sp_name *new_name)
{
  TABLE *table;
  int ret= EVEX_OPEN_TABLE_FAILED;
@@ -468,13 +471,27 @@ db_update_event(THD *thd, sp_name *new_name, event_timed *et)
    goto err;
  }
  
  if (EVEX_KEY_NOT_FOUND == evex_db_find_routine_aux(thd, et->dbname, et->name,
  // first look whether we overwrite
  if (new_name && !evex_db_find_event_aux(thd, new_name->m_db, new_name->m_name,
                                            table))
  {
    my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), new_name->m_name.str);
    goto err;    
  }
  /*
    ...and then whether there is such an event. don't exchange the blocks
    because you will get error 120 from table handler because new_name will
    overwrite the key and SE will tell us that it cannot find the already found
    row (copied into record[1] later
  */
  if (EVEX_KEY_NOT_FOUND == evex_db_find_event_aux(thd, et->dbname, et->name,
                                                     table))
  {
    my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->name.str);
    goto err;    
  }

  
  store_record(table,record[1]);
  
  // Don't update create on row update.
@@ -494,7 +511,7 @@ db_update_event(THD *thd, sp_name *new_name, event_timed *et)

  if ((ret= table->file->update_row(table->record[1], table->record[0])))
  {
    my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str);
    my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
    goto err;
  }

@@ -545,7 +562,7 @@ db_find_event(THD *thd, sp_name *name, event_timed **ett, TABLE *tbl)
    goto done;
  }

  if ((ret= evex_db_find_routine_aux(thd, name->m_db, name->m_name, table)))
  if ((ret= evex_db_find_event_aux(thd, name->m_db, name->m_name, table)))
  {
    my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name->m_name.str);
    goto done;    
@@ -816,20 +833,20 @@ evex_create_event(THD *thd, event_timed *et, uint create_options)
*/

int
evex_update_event(THD *thd, event_timed *et, sp_name *name)
evex_update_event(THD *thd, event_timed *et, sp_name *new_name)
{
  int ret, i;
  bool need_second_pass= true;
  sp_name *spn= 0;

  DBUG_ENTER("evex_update_event");
  DBUG_PRINT("enter", ("name: %*s", et->name.length, et->name.str));

  /*
    db_update_event() opens & closes the table to prevent
    crash later in the code when loading and compiling the new definition
    crash later in the code when loading and compiling the new definition.
    Also on error conditions my_error() is called so no need to handle here
  */
  if ((ret= db_update_event(thd, name, et)))
  if ((ret= db_update_event(thd, et, new_name)))
    goto done;

  VOID(pthread_mutex_lock(&LOCK_evex_running));
@@ -839,22 +856,20 @@ evex_update_event(THD *thd, event_timed *et, sp_name *name)
  VOID(pthread_mutex_lock(&LOCK_event_arrays));
  evex_remove_from_cache(&et->dbname, &et->name, false);
  if (et->status == MYSQL_EVENT_ENABLED)
    if (name)
      ret= evex_load_and_compile_event(thd, name, false);
  {
    if (new_name)
      ret= evex_load_and_compile_event(thd, new_name, false);
    else
    {
      spn= new sp_name(et->dbname, et->name);
      ret= evex_load_and_compile_event(thd, spn, false);
      delete spn;
      sp_name spn(et->dbname, et->name);
      ret= evex_load_and_compile_event(thd, &spn, false);
    }
    if (ret == EVEX_COMPILE_ERROR)
      my_error(ER_EVENT_COMPILE_ERROR, MYF(0));
  }
  VOID(pthread_mutex_unlock(&LOCK_event_arrays));
  VOID(pthread_mutex_unlock(&LOCK_evex_running));

  /*
    It is possible that 2 (or 1) pass(es) won't find the event in memory.
    The reason is that DISABLED events are not cached.
  */

done:
  DBUG_RETURN(ret);
}
@@ -885,7 +900,7 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
    goto done;
  }

  if (!(ret= evex_db_find_routine_aux(thd, et->dbname, et->name, table)))
  if (!(ret= evex_db_find_event_aux(thd, et->dbname, et->name, table)))
  {
    if ((ret= table->file->delete_row(table->record[0])))
    { 	
@@ -893,15 +908,18 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
      goto done;
    }
  }
  else if (ret == SP_KEY_NOT_FOUND && drop_if_exists)
  else if (ret == EVEX_KEY_NOT_FOUND)
  { 
    if (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", et->name.str);
      ret= 0;
     goto done;
    } else
      my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->name.str);
    goto done;
  }

  VOID(pthread_mutex_lock(&LOCK_evex_running));
  if (evex_is_running)
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ extern ulong opt_event_executor;
#define EVEX_PARSE_ERROR        SP_PARSE_ERROR
#define EVEX_INTERNAL_ERROR     SP_INTERNAL_ERROR
#define EVEX_NO_DB_ERROR        SP_NO_DB_ERROR
#define EVEX_COMPILE_ERROR     -19
#define EVEX_GENERAL_ERROR     -20
#define EVEX_BAD_IDENTIFIER     SP_BAD_IDENTIFIER
#define EVEX_BODY_TOO_LONG      SP_BODY_TOO_LONG
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ int
my_time_compare(TIME *a, TIME *b);

int
evex_db_find_routine_aux(THD *thd, const LEX_STRING dbname,
evex_db_find_event_aux(THD *thd, const LEX_STRING dbname,
                       const LEX_STRING rname, TABLE *table);
                       
TABLE *
+10 −2
Original line number Diff line number Diff line
@@ -740,7 +740,7 @@ event_timed::update_fields(THD *thd)
  if (!(table= evex_open_event_table(thd, TL_WRITE)))
    DBUG_RETURN(SP_OPEN_TABLE_FAILED);

  if ((ret= evex_db_find_routine_aux(thd, dbname, name, table)))
  if ((ret= evex_db_find_event_aux(thd, dbname, name, table)))
    goto done;

  store_record(table,record[1]);
@@ -893,6 +893,14 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
}


/*
  Returns
                     0 - Success
    EVEX_COMPILE_ERROR - Error during compilation

*/


int
event_timed::compile(THD *thd, MEM_ROOT *mem_root)
{
@@ -936,7 +944,7 @@ event_timed::compile(THD *thd, MEM_ROOT *mem_root)
    // QQ: anything else ?
    lex_end(&lex);
    thd->lex= old_lex;
    DBUG_RETURN(-1);
    DBUG_RETURN(EVEX_COMPILE_ERROR);
  }
  
  sphead= lex.sphead;
+3 −1
Original line number Diff line number Diff line
@@ -5724,7 +5724,7 @@ ER_PLUGIN_IS_NOT_LOADED
ER_EVENT_ALREADY_EXISTS
        eng "Event %s already exists"
ER_EVENT_STORE_FAILED
        eng "Failed to create event %s"
        eng "Failed to store event %s. Error code %d from storage engine."
ER_EVENT_DOES_NOT_EXIST
        eng "Event %s does not exist"
ER_EVENT_CANT_ALTER
@@ -5747,3 +5747,5 @@ ER_EVENT_CANNOT_LOAD_FROM_TABLE
        eng "Cannot load from mysql.event. Table probably corrupted"
ER_EVENT_CANNOT_DELETE
        eng "Failed to delete the event from mysql.event"
ER_EVENT_COMPILE_ERROR
        eng "Error during compilation of event's body"
Loading