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.
This commit is contained in:
parent
d2db48c69b
commit
ef9a97e685
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user