WL#3337 (Event scheduler new architecture) Fourth cut of refactoring
the parsing. Next step will be to refactor of usage of Event_timed during Events::create_event() and Events::update_event(). Disallow: - CREATE EVENT ... DO CREATE EVENT ...; - ALTER EVENT ... DO CREATE EVENT ...; - CREATE EVENT ... DO ALTER EVENT DO ....; - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END| Allowed: - CREATE EVENT ... DO DROP EVENT yyy; - CREATE EVENT ... DO ALTER EVENT yyy; (the nested ALTER EVENT can have anything but DO clause) - ALTER EVENT ... DO ALTER EVENT yyy; (the nested ALTER EVENT can have anything but DO clause) - ALTER EVENT ... DO DROP EVENT yyy; - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END| (the nested ALTER EVENT can have anything but DO clause) - CREATE PROCEDURE ... BEGIN DROP EVENT ... END| mysql-test/r/events.result: update results mysql-test/r/events_bugs.result: update results mysql-test/t/events.test: use number as error, mysql-test-run does not like the name. will come back to this later, now it's enough to pass the test. disable nested events / events in SP, when the nested event has a body. If no body is provided, namely DROP EVENT or ALTER that changes the characteristics, then these are allowed. mysql-test/t/events_bugs.test: use number as error, mysql-test-run does not like the name. will come back to this later, now it's enough to pass the test. disable nested events / events in SP, when the nested event has a body. If no body is provided, namely DROP EVENT or ALTER that changes the characteristics, then these are allowed. sql/share/errmsg.txt: new message sql/sql_yacc.yy: refactor CREATE EVENT parsing to fit into the structure CREATE DEFINER=xxx EVENT The actual definer part is not used, but parsed, for now. Disable nested CREATE EVENTS, CREATE EVENT inside CREATE PROCEDURE. And an event DDL with body inside an ALTER. This stops the following : - CREATE EVENT ... DO CREATE EVENT ...; - ALTER EVENT ... DO CREATE EVENT ...; - CREATE EVENT ... DO ALTER EVENT DO ....; - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END| This allows: - CREATE EVENT ... DO DROP EVENT yyy; - CREATE EVENT ... DO ALTER EVENT yyy; (the nested ALTER EVENT can have anything but DO clause) - ALTER EVENT ... DO ALTER EVENT yyy; (the nested ALTER EVENT can have anything but DO clause) - ALTER EVENT ... DO DROP EVENT yyy; - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END| (the nested ALTER EVENT can have anything but DO clause) - CREATE PROCEDURE ... BEGIN DROP EVENT ... END|
This commit is contained in:
parent
ef9a97e685
commit
cace147c63
@ -85,13 +85,25 @@ SHOW EVENTS;
|
||||
Db Name Definer Type Execute at Interval value Interval field Starts Ends Status
|
||||
events_test event_starts_test root@localhost RECURRING NULL 20 SECOND # # ENABLED
|
||||
DROP EVENT event_starts_test;
|
||||
create table test_nested(a int);
|
||||
create event e_43 on schedule every 1 second do set @a = 5;
|
||||
set global event_scheduler = 1;
|
||||
alter event e_43 do alter event e_43 do set @a = 4;
|
||||
ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present
|
||||
alter event e_43 do
|
||||
begin
|
||||
alter event e_43 on schedule every 5 minute;
|
||||
insert into test_nested values(1);
|
||||
end|
|
||||
set global event_scheduler = 1;
|
||||
select db, name, body, status, interval_field, interval_value from mysql.event;
|
||||
db name body status interval_field interval_value
|
||||
events_test e_43 set @a = 4 ENABLED SECOND 1
|
||||
events_test e_43 begin
|
||||
alter event e_43 on schedule every 5 minute;
|
||||
insert into test_nested values(1);
|
||||
end ENABLED MINUTE 5
|
||||
drop event e_43;
|
||||
drop table test_nested;
|
||||
"Let's check whether we can use non-qualified names"
|
||||
create table non_qualif(a int);
|
||||
create event non_qualif_ev on schedule every 10 minute do insert into non_qualif values (800219);
|
||||
@ -358,7 +370,7 @@ root localhost events_test Connect User lock select get_lock("test_lock2_1", 20)
|
||||
drop event закачка21;
|
||||
create table t_16 (s1 int);
|
||||
create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5;
|
||||
ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
|
||||
ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present
|
||||
drop table t_16;
|
||||
create event white_space
|
||||
on schedule every 10 hour
|
||||
|
@ -17,18 +17,7 @@ DROP EVENT ДОЛЕН_регистър_утф8;
|
||||
SET NAMES latin1;
|
||||
set @a=3;
|
||||
CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5;
|
||||
call p_16();
|
||||
"Here we used to crash!"
|
||||
call p_16();
|
||||
ERROR HY000: Event 'e_16' already exists
|
||||
call p_16();
|
||||
ERROR HY000: Event 'e_16' already exists
|
||||
DROP EVENT e_16;
|
||||
CALL p_16();
|
||||
CALL p_16();
|
||||
ERROR HY000: Event 'e_16' already exists
|
||||
DROP PROCEDURE p_16;
|
||||
DROP EVENT e_16;
|
||||
ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present
|
||||
create event e_55 on schedule at 99990101000000 do drop table t;
|
||||
ERROR HY000: Incorrect AT value: '99990101000000'
|
||||
create event e_55 on schedule every 10 hour starts 99990101000000 do drop table t;
|
||||
|
@ -81,14 +81,23 @@ SHOW EVENTS;
|
||||
DROP EVENT event_starts_test;
|
||||
#
|
||||
#
|
||||
create table test_nested(a int);
|
||||
create event e_43 on schedule every 1 second do set @a = 5;
|
||||
set global event_scheduler = 1;
|
||||
--sleep 2
|
||||
--error 1562
|
||||
alter event e_43 do alter event e_43 do set @a = 4;
|
||||
--sleep 2
|
||||
delimiter |;
|
||||
alter event e_43 do
|
||||
begin
|
||||
alter event e_43 on schedule every 5 minute;
|
||||
insert into test_nested values(1);
|
||||
end|
|
||||
delimiter ;|
|
||||
set global event_scheduler = 1;
|
||||
--sleep 1
|
||||
select db, name, body, status, interval_field, interval_value from mysql.event;
|
||||
drop event e_43;
|
||||
--sleep 1
|
||||
drop table test_nested;
|
||||
|
||||
--echo "Let's check whether we can use non-qualified names"
|
||||
create table non_qualif(a int);
|
||||
@ -315,7 +324,7 @@ drop event закачка21;
|
||||
# Bug #16410 Events: CREATE EVENT is legal in a CREATE TRIGGER statement
|
||||
#
|
||||
create table t_16 (s1 int);
|
||||
--error 1422
|
||||
--error 1562
|
||||
create trigger t_16_bi before insert on t_16 for each row create event e_16 on schedule every 1 second do set @a=5;
|
||||
drop table t_16;
|
||||
#
|
||||
|
@ -30,19 +30,8 @@ SET NAMES latin1;
|
||||
# START - BUG#16408: Events: crash for an event in a procedure
|
||||
#
|
||||
set @a=3;
|
||||
--error 1562
|
||||
CREATE PROCEDURE p_16 () CREATE EVENT e_16 ON SCHEDULE EVERY @a SECOND DO SET @a=5;
|
||||
call p_16();
|
||||
--echo "Here we used to crash!"
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
call p_16();
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
call p_16();
|
||||
DROP EVENT e_16;
|
||||
CALL p_16();
|
||||
--error ER_EVENT_ALREADY_EXISTS
|
||||
CALL p_16();
|
||||
DROP PROCEDURE p_16;
|
||||
DROP EVENT e_16;
|
||||
#
|
||||
# END - BUG#16408: Events: crash for an event in a procedure
|
||||
#
|
||||
|
@ -5839,3 +5839,6 @@ ER_CANT_ACTIVATE_LOG
|
||||
eng "Cannot activate '%-.64s' log."
|
||||
ER_RBR_NOT_AVAILABLE
|
||||
eng "The server was not built with row-based replication"
|
||||
ER_EVENT_RECURSIVITY_FORBIDDEN
|
||||
eng "Recursivity of EVENT DDL statements is forbidden when body is present"
|
||||
|
||||
|
222
sql/sql_yacc.yy
222
sql/sql_yacc.yy
@ -880,7 +880,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
|
||||
load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
|
||||
definer view_replace_or_algorithm view_replace view_algorithm_opt
|
||||
view_algorithm view_or_trigger_or_sp view_or_trigger_or_sp_tail
|
||||
view_algorithm view_or_trigger_or_sp_or_event
|
||||
view_or_trigger_or_sp_or_event_tail
|
||||
view_suid view_tail view_list_opt view_list view_select
|
||||
view_check_option trigger_tail sp_tail
|
||||
install uninstall partition_entry binlog_base64_event
|
||||
@ -1257,78 +1258,13 @@ create:
|
||||
lex->name=$4.str;
|
||||
lex->create_info.options=$3;
|
||||
}
|
||||
| CREATE EVENT_SYM opt_if_not_exists sp_name
|
||||
/*
|
||||
BE CAREFUL when you add a new rule to update the block where
|
||||
YYTHD->client_capabilities is set back to original value
|
||||
*/
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
|
||||
if (lex->et)
|
||||
{
|
||||
/*
|
||||
Recursive events are not possible because recursive SPs
|
||||
are not also possible. lex->sp_head is not stacked.
|
||||
*/
|
||||
// ToDo Andrey : Change the error message
|
||||
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "EVENT");
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
lex->create_info.options= $3;
|
||||
|
||||
if (!(lex->et= new(YYTHD->mem_root) Event_timed())) // implicitly calls Event_timed::init()
|
||||
YYABORT;
|
||||
if (!(lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
|
||||
YYABORT;
|
||||
|
||||
/*
|
||||
We have to turn of CLIENT_MULTI_QUERIES while parsing a
|
||||
stored procedure, otherwise yylex will chop it into pieces
|
||||
at each ';'.
|
||||
*/
|
||||
$<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
|
||||
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
|
||||
|
||||
|
||||
lex->event_parse_data->identifier= $4;
|
||||
|
||||
if (!lex->et_compile_phase)
|
||||
{
|
||||
lex->et->init_name(YYTHD, $4);
|
||||
lex->et->init_definer(YYTHD);
|
||||
}
|
||||
}
|
||||
ON SCHEDULE_SYM ev_schedule_time
|
||||
opt_ev_on_completion
|
||||
opt_ev_status
|
||||
opt_ev_comment
|
||||
DO_SYM ev_sql_stmt
|
||||
{
|
||||
/*
|
||||
Restore flag if it was cleared above
|
||||
$1 - CREATE
|
||||
$2 - EVENT_SYM
|
||||
$3 - opt_if_not_exists
|
||||
$4 - sp_name
|
||||
$5 - the block above
|
||||
*/
|
||||
YYTHD->client_capabilities |= $<ulong_num>5;
|
||||
|
||||
/*
|
||||
sql_command is set here because some rules in ev_sql_stmt
|
||||
can overwrite it
|
||||
*/
|
||||
Lex->sql_command= SQLCOM_CREATE_EVENT;
|
||||
}
|
||||
| CREATE
|
||||
{
|
||||
Lex->create_view_mode= VIEW_CREATE_NEW;
|
||||
Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
|
||||
Lex->create_view_suid= TRUE;
|
||||
}
|
||||
view_or_trigger_or_sp
|
||||
view_or_trigger_or_sp_or_event
|
||||
{}
|
||||
| CREATE USER clear_privileges grant_list
|
||||
{
|
||||
@ -1347,6 +1283,72 @@ create:
|
||||
;
|
||||
|
||||
|
||||
event_tail:
|
||||
EVENT_SYM opt_if_not_exists sp_name
|
||||
/*
|
||||
BE CAREFUL when you add a new rule to update the block where
|
||||
YYTHD->client_capabilities is set back to original value
|
||||
*/
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
|
||||
if (lex->et)
|
||||
{
|
||||
/*
|
||||
Recursive CREATE EVENT statement 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;
|
||||
}
|
||||
|
||||
lex->create_info.options= $2;
|
||||
|
||||
if (!(lex->et= new(YYTHD->mem_root) Event_timed())) // implicitly calls Event_timed::init()
|
||||
YYABORT;
|
||||
if (!(lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
|
||||
YYABORT;
|
||||
|
||||
/*
|
||||
We have to turn of CLIENT_MULTI_QUERIES while parsing a
|
||||
stored procedure, otherwise yylex will chop it into pieces
|
||||
at each ';'.
|
||||
*/
|
||||
$<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
|
||||
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
|
||||
|
||||
|
||||
lex->event_parse_data->identifier= $3;
|
||||
|
||||
if (!lex->et_compile_phase)
|
||||
{
|
||||
lex->et->init_name(YYTHD, $3);
|
||||
lex->et->init_definer(YYTHD);
|
||||
}
|
||||
}
|
||||
ON SCHEDULE_SYM ev_schedule_time
|
||||
opt_ev_on_completion
|
||||
opt_ev_status
|
||||
opt_ev_comment
|
||||
DO_SYM ev_sql_stmt
|
||||
{
|
||||
/*
|
||||
Restore flag if it was cleared above
|
||||
$1 - EVENT_SYM
|
||||
$2 - opt_if_not_exists
|
||||
$3 - sp_name
|
||||
$4 - the block above
|
||||
*/
|
||||
YYTHD->client_capabilities |= $<ulong_num>4;
|
||||
|
||||
/*
|
||||
sql_command is set here because some rules in ev_sql_stmt
|
||||
can overwrite it
|
||||
*/
|
||||
Lex->sql_command= SQLCOM_CREATE_EVENT;
|
||||
}
|
||||
|
||||
|
||||
ev_schedule_time: EVERY_SYM expr interval
|
||||
{
|
||||
Lex->event_parse_data->item_expression= $2;
|
||||
@ -1517,25 +1519,41 @@ ev_sql_stmt:
|
||||
LEX *lex= Lex;
|
||||
sp_head *sp;
|
||||
|
||||
$<sphead>$= lex->sphead;
|
||||
|
||||
if (!lex->sphead)
|
||||
/*
|
||||
This stops the following :
|
||||
- CREATE EVENT ... DO CREATE EVENT ...;
|
||||
- ALTER EVENT ... DO CREATE EVENT ...;
|
||||
- CREATE EVENT ... DO ALTER EVENT DO ....;
|
||||
- CREATE PROCEDURE ... BEGIN CREATE EVENT ... END|
|
||||
This allows:
|
||||
- CREATE EVENT ... DO DROP EVENT yyy;
|
||||
- CREATE EVENT ... DO ALTER EVENT yyy;
|
||||
(the nested ALTER EVENT can have anything but DO clause)
|
||||
- ALTER EVENT ... DO ALTER EVENT yyy;
|
||||
(the nested ALTER EVENT can have anything but DO clause)
|
||||
- ALTER EVENT ... DO DROP EVENT yyy;
|
||||
- CREATE PROCEDURE ... BEGIN ALTER EVENT ... END|
|
||||
(the nested ALTER EVENT can have anything but DO clause)
|
||||
- CREATE PROCEDURE ... BEGIN DROP EVENT ... END|
|
||||
*/
|
||||
if (lex->sphead)
|
||||
{
|
||||
if (!(sp= new sp_head()))
|
||||
YYABORT;
|
||||
|
||||
sp->reset_thd_mem_root(YYTHD);
|
||||
sp->init(lex);
|
||||
|
||||
sp->m_type= TYPE_ENUM_PROCEDURE;
|
||||
|
||||
lex->sphead= sp;
|
||||
|
||||
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
|
||||
lex->sphead->m_chistics= &lex->sp_chistics;
|
||||
|
||||
lex->sphead->m_body_begin= lex->ptr;
|
||||
my_error(ER_EVENT_RECURSIVITY_FORBIDDEN, MYF(0));
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
if (!(lex->sphead= new sp_head()))
|
||||
YYABORT;
|
||||
|
||||
lex->sphead->reset_thd_mem_root(YYTHD);
|
||||
lex->sphead->init(lex);
|
||||
|
||||
lex->sphead->m_type= TYPE_ENUM_PROCEDURE;
|
||||
|
||||
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
|
||||
lex->sphead->m_chistics= &lex->sp_chistics;
|
||||
|
||||
lex->sphead->m_body_begin= lex->ptr;
|
||||
|
||||
Lex->event_parse_data->body_begin= lex->ptr;
|
||||
|
||||
@ -1546,18 +1564,15 @@ ev_sql_stmt:
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
|
||||
if (!$<sphead>1)
|
||||
{
|
||||
sp_head *sp= lex->sphead;
|
||||
// return back to the original memory root ASAP
|
||||
sp->init_strings(YYTHD, lex, NULL);
|
||||
sp->restore_thd_mem_root(YYTHD);
|
||||
// return back to the original memory root ASAP
|
||||
lex->sphead->init_strings(YYTHD, lex, NULL);
|
||||
lex->sphead->restore_thd_mem_root(YYTHD);
|
||||
|
||||
lex->sp_chistics.suid= SP_IS_SUID;//always the definer!
|
||||
lex->sp_chistics.suid= SP_IS_SUID;//always the definer!
|
||||
|
||||
lex->et->sphead= lex->sphead;
|
||||
lex->sphead= NULL;
|
||||
|
||||
lex->et->sphead= lex->sphead;
|
||||
lex->sphead= NULL;
|
||||
}
|
||||
Lex->event_parse_data->init_body(YYTHD);
|
||||
if (!lex->et_compile_phase)
|
||||
{
|
||||
@ -4738,16 +4753,7 @@ alter:
|
||||
LEX *lex=Lex;
|
||||
Event_timed *et;
|
||||
|
||||
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;
|
||||
}
|
||||
lex->spname= 0;//defensive programming
|
||||
lex->spname= NULL;
|
||||
|
||||
if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
|
||||
YYABORT;
|
||||
@ -10767,20 +10773,22 @@ subselect_end:
|
||||
|
||||
**************************************************************************/
|
||||
|
||||
view_or_trigger_or_sp:
|
||||
definer view_or_trigger_or_sp_tail
|
||||
view_or_trigger_or_sp_or_event:
|
||||
definer view_or_trigger_or_sp_or_event_tail
|
||||
{}
|
||||
| view_replace_or_algorithm definer view_tail
|
||||
{}
|
||||
;
|
||||
|
||||
view_or_trigger_or_sp_tail:
|
||||
view_or_trigger_or_sp_or_event_tail:
|
||||
view_tail
|
||||
{}
|
||||
| trigger_tail
|
||||
{}
|
||||
| sp_tail
|
||||
{}
|
||||
| event_tail
|
||||
{}
|
||||
;
|
||||
|
||||
/**************************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user