summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/event_data_objects.cc60
-rw-r--r--sql/event_scheduler.cc49
-rw-r--r--sql/event_scheduler.h6
-rw-r--r--sql/events.cc27
-rw-r--r--sql/events.h5
-rw-r--r--sql/events_priv.h17
-rw-r--r--sql/sql_parse.cc22
-rw-r--r--sql/sql_yacc.yy30
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
{