diff options
-rw-r--r-- | sql/event_data_objects.cc | 60 | ||||
-rw-r--r-- | sql/event_scheduler.cc | 49 | ||||
-rw-r--r-- | sql/event_scheduler.h | 6 | ||||
-rw-r--r-- | sql/events.cc | 27 | ||||
-rw-r--r-- | sql/events.h | 5 | ||||
-rw-r--r-- | sql/events_priv.h | 17 | ||||
-rw-r--r-- | sql/sql_parse.cc | 22 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 30 |
8 files changed, 158 insertions, 58 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 6d15ad66bcb..71739bf0f1c 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -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); } diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index fc2ad75b272..f83bc5f25a3 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -833,12 +833,13 @@ end: */ 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(); @@ -1050,6 +1051,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 diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h index 5ae310bab2a..183ef450be2 100644 --- a/sql/event_scheduler.h +++ b/sql/event_scheduler.h @@ -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 @@ public: LEX_STRING *new_name); bool - drop_event(THD *thd, Event_timed *et); + drop_event(THD *thd, sp_name *name); int @@ -136,6 +137,9 @@ private: 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(); diff --git a/sql/events.cc b/sql/events.cc index 679b571ff5c..c9d05994873 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -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 @@ done: 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 @@ done: */ 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); } diff --git a/sql/events.h b/sql/events.h index 055c9a371a4..d56a544493d 100644 --- a/sql/events.h +++ b/sql/events.h @@ -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 @@ public: 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); diff --git a/sql/events_priv.h b/sql/events_priv.h index ed02cb7055b..fe208ace280 100644 --- a/sql/events_priv.h +++ b/sql/events_priv.h @@ -25,6 +25,7 @@ #define EVEX_MAX_INTERVAL_VALUE 2147483647L class Event_timed; +class sp_name; int evex_db_find_event_by_name(THD *thd, const LEX_STRING dbname, @@ -32,7 +33,7 @@ evex_db_find_event_by_name(THD *thd, const LEX_STRING dbname, TABLE *table); int -db_drop_event(THD *thd, Event_timed *et, bool drop_if_exists, +db_drop_event(THD *thd, LEX_STRING db, LEX_STRING name, bool drop_if_exists, uint *rows_affected); int db_find_event(THD *thd, sp_name *name, Event_timed **ett, TABLE *tbl, @@ -68,6 +69,20 @@ bool event_timed_identifier_equal(Event_timed *a, Event_timed *b); + +/* Compares only the name part of the identifier */ +bool +event_timed_name_equal(sp_name *name, LEX_STRING *event_name); + +/* Compares only the schema part of the identifier */ +bool +event_timed_db_equal(sp_name *name, LEX_STRING *db); + +/* Compares the whole identifier*/ +bool +event_timed_identifier_equal(sp_name *a, Event_timed *b); + + bool change_security_context(THD *thd, LEX_STRING user, LEX_STRING host, LEX_STRING db, Security_context *s_ctx, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bca140739f3..4f75339e5a2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3819,7 +3819,6 @@ end_with_restore_list: } case SQLCOM_CREATE_EVENT: case SQLCOM_ALTER_EVENT: - case SQLCOM_DROP_EVENT: { uint rows_affected= 1; DBUG_ASSERT(lex->et); @@ -3856,9 +3855,6 @@ end_with_restore_list: res= Events::update_event(thd, lex->et, lex->event_parse_data, lex->spname, &rows_affected); break; - case SQLCOM_DROP_EVENT: - res= Events::drop_event(thd, lex->et, lex->event_parse_data, - lex->drop_if_exists, &rows_affected); default:; } DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d", @@ -3877,6 +3873,7 @@ end_with_restore_list: break; } + case SQLCOM_DROP_EVENT: case SQLCOM_SHOW_CREATE_EVENT: { DBUG_ASSERT(lex->spname); @@ -3893,9 +3890,24 @@ end_with_restore_list: if (lex->spname->m_name.length > NAME_LEN) { my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str); + /* this jumps to the end of the function and skips own messaging */ goto error; } - res= Events::show_create_event(thd, lex->spname); + + if (lex->sql_command == SQLCOM_SHOW_CREATE_EVENT) + res= Events::show_create_event(thd, lex->spname); + else + { + uint rows_affected= 1; + if (end_active_trans(thd)) + { + res= -1; + break; + } + if (!(res= Events::drop_event(thd, lex->spname, lex->drop_if_exists, + &rows_affected))) + send_ok(thd, rows_affected); + } break; } #ifndef DBUG_OFF diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a40500afa90..4dfabbf0c27 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7686,33 +7686,9 @@ drop: } | DROP EVENT_SYM if_exists sp_name { - if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD))) - YYABORT; - Lex->event_parse_data->identifier= $4; - - LEX *lex=Lex; - - if (lex->et) - { - /* - Recursive events are not possible because recursive SPs - are not also possible. lex->sp_head is not stacked. - */ - my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT"); - YYABORT; - } - - if (!(lex->et= new (YYTHD->mem_root) Event_timed())) - YYABORT; - - if (!lex->et_compile_phase) - { - lex->et->init_name(YYTHD, $4); - lex->et->init_definer(YYTHD); - } - - lex->sql_command = SQLCOM_DROP_EVENT; - lex->drop_if_exists= $3; + Lex->drop_if_exists= $3; + Lex->spname= $4; + Lex->sql_command = SQLCOM_DROP_EVENT; } | DROP TRIGGER_SYM sp_name { |