Commit cace147c authored by unknown's avatar unknown

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|
parent ef9a97e6
......@@ -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"
......@@ -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,7 +1258,33 @@ create:
lex->name=$4.str;
lex->create_info.options=$3;
}
| CREATE EVENT_SYM opt_if_not_exists sp_name
| 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_or_event
{}
| CREATE USER clear_privileges grant_list
{
Lex->sql_command = SQLCOM_CREATE_USER;
}
| CREATE LOGFILE_SYM GROUP logfile_group_info
{
LEX *lex= Lex;
lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
}
| CREATE TABLESPACE tablespace_info
{
LEX *lex= Lex;
lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
}
;
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
......@@ -1268,15 +1295,14 @@ create:
if (lex->et)
{
/*
Recursive events are not possible because recursive SPs
are not also possible. lex->sp_head is not stacked.
Recursive CREATE EVENT statement 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;
lex->create_info.options= $2;
if (!(lex->et= new(YYTHD->mem_root) Event_timed())) // implicitly calls Event_timed::init()
YYABORT;
......@@ -1292,11 +1318,11 @@ create:
YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
lex->event_parse_data->identifier= $4;
lex->event_parse_data->identifier= $3;
if (!lex->et_compile_phase)
{
lex->et->init_name(YYTHD, $4);
lex->et->init_name(YYTHD, $3);
lex->et->init_definer(YYTHD);
}
}
......@@ -1308,13 +1334,12 @@ create:
{
/*
Restore flag if it was cleared above
$1 - CREATE
$2 - EVENT_SYM
$3 - opt_if_not_exists
$4 - sp_name
$5 - the block above
$1 - EVENT_SYM
$2 - opt_if_not_exists
$3 - sp_name
$4 - the block above
*/
YYTHD->client_capabilities |= $<ulong_num>5;
YYTHD->client_capabilities |= $<ulong_num>4;
/*
sql_command is set here because some rules in ev_sql_stmt
......@@ -1322,29 +1347,6 @@ create:
*/
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
{}
| CREATE USER clear_privileges grant_list
{
Lex->sql_command = SQLCOM_CREATE_USER;
}
| CREATE LOGFILE_SYM GROUP logfile_group_info
{
LEX *lex= Lex;
lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
}
| CREATE TABLESPACE tablespace_info
{
LEX *lex= Lex;
lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
}
;
ev_schedule_time: EVERY_SYM expr interval
......@@ -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);
my_error(ER_EVENT_RECURSIVITY_FORBIDDEN, MYF(0));
YYABORT;
}
if (!(lex->sphead= new sp_head()))
YYABORT;
sp->m_type= TYPE_ENUM_PROCEDURE;
lex->sphead->reset_thd_mem_root(YYTHD);
lex->sphead->init(lex);
lex->sphead= sp;
lex->sphead->m_type= TYPE_ENUM_PROCEDURE;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
lex->sphead->m_chistics= &lex->sp_chistics;
lex->sphead->m_body_begin= lex->ptr;
}
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
{}
;
/**************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment