diff options
-rw-r--r-- | .bzrignore | 5 | ||||
-rw-r--r-- | sql/event_data_objects.cc | 89 | ||||
-rw-r--r-- | sql/event_data_objects.h | 9 | ||||
-rw-r--r-- | sql/events.cc | 14 | ||||
-rw-r--r-- | sql/events.h | 13 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 3 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 11 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 41 |
9 files changed, 151 insertions, 36 deletions
diff --git a/.bzrignore b/.bzrignore index e07aa0cf86a..f9753c20fac 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1778,3 +1778,8 @@ vio/viotest-sslconnect.cpp vio/viotest.cpp zlib/*.ds? zlib/*.vcproj +libmysql/viosocket.o.6WmSJk +libmysqld/event_data_objects.cc +libmysqld/event_db_repository.cc +libmysqld/event_queue.cc +server-tools/instance-manager/net_serv.cc diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index ebd45dd1a23..6d15ad66bcb 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -22,6 +22,95 @@ #include "sp_head.h" +Event_parse_data * +Event_parse_data::new_instance(THD *thd) +{ + return new (thd->mem_root) Event_parse_data; +} + + +Event_parse_data::Event_parse_data() +{ + item_execute_at= item_expression= item_starts= item_ends= NULL; +} + + +/* + Set body of the event - what should be executed. + + SYNOPSIS + Event_timed::init_body() + thd THD + + NOTE + The body is extracted by copying all data between the + start of the body set by another method and the current pointer in Lex. + + Some questionable removal of characters is done in here, and that part + should be refactored when the parser is smarter. +*/ + +void +Event_parse_data::init_body(THD *thd) +{ + DBUG_ENTER("Event_parse_data::init_body"); + DBUG_PRINT("info", ("body=[%s] body_begin=0x%ld end=0x%ld", body_begin, + body_begin, thd->lex->ptr)); + + body.length= thd->lex->ptr - body_begin; + const uchar *body_end= body_begin + body.length - 1; + + /* Trim nuls or close-comments ('*'+'/') or spaces at the end */ + while (body_begin < body_end) + { + + if ((*body_end == '\0') || + (my_isspace(thd->variables.character_set_client, *body_end))) + { /* consume NULs and meaningless whitespace */ + --body.length; + --body_end; + continue; + } + + /* + consume closing comments + + This is arguably wrong, but it's the best we have until the parser is + changed to be smarter. FIXME PARSER + + See also the sp_head code, where something like this is done also. + + One idea is to keep in the lexer structure the count of the number of + open-comments we've entered, and scan left-to-right looking for a + closing comment IFF the count is greater than zero. + + Another idea is to remove the closing comment-characters wholly in the + parser, since that's where it "removes" the opening characters. + */ + if ((*(body_end - 1) == '*') && (*body_end == '/')) + { + DBUG_PRINT("info", ("consumend one '*" "/' comment in the query '%s'", + body_begin)); + body.length-= 2; + body_end-= 2; + continue; + } + + break; /* none were found, so we have excised all we can. */ + } + + /* the first is always whitespace which I cannot skip in the parser */ + while (my_isspace(thd->variables.character_set_client, *body_begin)) + { + ++body_begin; + --body.length; + } + body.str= thd->strmake((char *)body_begin, body.length); + + DBUG_VOID_RETURN; +} + + /* Constructor diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index 0c122211a9d..a9483465a8d 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -259,19 +259,16 @@ public: my_bool ends_null; my_bool execute_at_null; + sp_name *identifier; Item* item_expression; - Item* item_interval; longlong expression; interval_type interval; -// ulonglong created; -// ulonglong modified; - static Event_parse_data * new_instance(THD *thd); - Event_parse_data() {} - ~Event_parse_data() {} + Event_parse_data(); + ~Event_parse_data(); int init_definer(THD *thd); diff --git a/sql/events.cc b/sql/events.cc index 391ecd6ba16..679b571ff5c 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -904,8 +904,8 @@ done: */ int -Events::create_event(THD *thd, Event_timed *et, uint create_options, - uint *rows_affected) +Events::create_event(THD *thd, Event_timed *et, Event_parse_data *parse_data, + uint create_options, uint *rows_affected) { int ret; @@ -948,8 +948,8 @@ Events::create_event(THD *thd, Event_timed *et, uint create_options, */ int -Events::update_event(THD *thd, Event_timed *et, sp_name *new_name, - uint *rows_affected) +Events::update_event(THD *thd, Event_timed *et, Event_parse_data *parse_data, + sp_name *new_name, uint *rows_affected) { int ret; @@ -1054,8 +1054,8 @@ done: */ int -Events::drop_event(THD *thd, Event_timed *et, bool drop_if_exists, - uint *rows_affected) +Events::drop_event(THD *thd, Event_timed *et, Event_parse_data *parse_data, + bool drop_if_exists, uint *rows_affected) { int ret; @@ -1091,7 +1091,7 @@ Events::show_create_event(THD *thd, sp_name *spn) Event_timed *et= NULL; Open_tables_state backup; - DBUG_ENTER("evex_update_event"); + DBUG_ENTER("Events::show_create_event"); DBUG_PRINT("enter", ("name: %*s", spn->m_name.length, spn->m_name.str)); thd->reset_n_backup_open_tables_state(&backup); diff --git a/sql/events.h b/sql/events.h index 66cce6e7777..055c9a371a4 100644 --- a/sql/events.h +++ b/sql/events.h @@ -18,6 +18,7 @@ class Event_timed; +class Event_parse_data; class Events { @@ -47,16 +48,16 @@ public: }; static int - create_event(THD *thd, Event_timed *et, uint create_options, - uint *rows_affected); + create_event(THD *thd, Event_timed *et, Event_parse_data *parse_data, + uint create_options, uint *rows_affected); static int - update_event(THD *thd, Event_timed *et, sp_name *new_name, - uint *rows_affected); + update_event(THD *thd, Event_timed *et, Event_parse_data *parse_data, + sp_name *new_name, uint *rows_affected); static int - drop_event(THD *thd, Event_timed *et, bool drop_if_exists, - uint *rows_affected); + drop_event(THD *thd, Event_timed *et, Event_parse_data *parse_data, + 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/share/errmsg.txt b/sql/share/errmsg.txt index ac4f2dd9237..476bc2f2f02 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5839,6 +5839,3 @@ 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" - diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 15a94041d24..6e7456b61bc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -28,6 +28,7 @@ class sp_pcontext; class st_alter_tablespace; class partition_info; class Event_timed; +class Event_parse_data; #ifdef MYSQL_SERVER /* @@ -1017,6 +1018,7 @@ typedef struct st_lex : public Query_tables_list st_sp_chistics sp_chistics; Event_timed *et; + Event_parse_data *event_parse_data; bool et_compile_phase; bool only_view; /* used for SHOW CREATE TABLE/VIEW */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3ebf700b715..bca140739f3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3848,17 +3848,17 @@ end_with_restore_list: switch (lex->sql_command) { case SQLCOM_CREATE_EVENT: - res= Events::create_event(thd, lex->et, + res= Events::create_event(thd, lex->et, lex->event_parse_data, (uint) lex->create_info.options, &rows_affected); break; case SQLCOM_ALTER_EVENT: - res= Events::update_event(thd, lex->et, lex->spname, - &rows_affected); + 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->drop_if_exists, - &rows_affected); + 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", @@ -3880,7 +3880,6 @@ end_with_restore_list: case SQLCOM_SHOW_CREATE_EVENT: { DBUG_ASSERT(lex->spname); - DBUG_ASSERT(lex->et); if (! lex->spname->m_db.str) { my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e9e00828b7e..a40500afa90 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1280,6 +1280,8 @@ create: 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 @@ -1289,6 +1291,9 @@ create: $<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); @@ -1344,6 +1349,8 @@ create: ev_schedule_time: EVERY_SYM expr interval { + Lex->event_parse_data->item_expression= $2; + Lex->event_parse_data->interval= $3; LEX *lex=Lex; if (!lex->et_compile_phase) { @@ -1365,6 +1372,7 @@ ev_schedule_time: EVERY_SYM expr interval ev_ends | AT_SYM expr { + Lex->event_parse_data->item_execute_at= $2; LEX *lex=Lex; if (!lex->et_compile_phase) { @@ -1395,6 +1403,7 @@ ev_schedule_time: EVERY_SYM expr interval opt_ev_status: /* empty */ { $$= 0; } | ENABLE_SYM { + Lex->event_parse_data->status= Event_parse_data::ENABLED; LEX *lex=Lex; if (!lex->et_compile_phase) lex->et->status= Event_timed::ENABLED; @@ -1402,6 +1411,7 @@ opt_ev_status: /* empty */ { $$= 0; } } | DISABLE_SYM { + Lex->event_parse_data->status= Event_parse_data::DISABLED; LEX *lex=Lex; if (!lex->et_compile_phase) @@ -1412,10 +1422,12 @@ opt_ev_status: /* empty */ { $$= 0; } ev_starts: /* empty */ { + Lex->event_parse_data->item_starts= new Item_func_now_local(); Lex->et->init_starts(YYTHD, new Item_func_now_local()); } | STARTS_SYM expr { + Lex->event_parse_data->item_starts= $2; LEX *lex= Lex; if (!lex->et_compile_phase) { @@ -1443,6 +1455,7 @@ ev_starts: /* empty */ ev_ends: /* empty */ | ENDS_SYM expr { + Lex->event_parse_data->item_ends= $2; LEX *lex= Lex; if (!lex->et_compile_phase) { @@ -1467,6 +1480,8 @@ opt_ev_on_completion: /* empty */ { $$= 0; } ev_on_completion: ON COMPLETION_SYM PRESERVE_SYM { + Lex->event_parse_data->on_completion= + Event_parse_data::ON_COMPLETION_PRESERVE; LEX *lex=Lex; if (!lex->et_compile_phase) lex->et->on_completion= Event_timed::ON_COMPLETION_PRESERVE; @@ -1474,6 +1489,8 @@ ev_on_completion: } | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM { + Lex->event_parse_data->on_completion= + Event_parse_data::ON_COMPLETION_DROP; LEX *lex=Lex; if (!lex->et_compile_phase) lex->et->on_completion= Event_timed::ON_COMPLETION_DROP; @@ -1484,6 +1501,7 @@ ev_on_completion: opt_ev_comment: /* empty */ { $$= 0; } | COMMENT_SYM TEXT_STRING_sys { + Lex->comment= Lex->event_parse_data->comment= $2; LEX *lex= Lex; if (!lex->et_compile_phase) { @@ -1518,6 +1536,8 @@ ev_sql_stmt: lex->sphead->m_body_begin= lex->ptr; } + + Lex->event_parse_data->body_begin= lex->ptr; if (!lex->et_compile_phase) lex->et->body_begin= lex->ptr; @@ -1538,6 +1558,7 @@ ev_sql_stmt: lex->et->sphead= lex->sphead; lex->sphead= NULL; } + Lex->event_parse_data->init_body(YYTHD); if (!lex->et_compile_phase) { lex->et->init_body(YYTHD); @@ -4728,6 +4749,10 @@ alter: } lex->spname= 0;//defensive programming + if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD))) + YYABORT; + Lex->event_parse_data->identifier= $3; + if (!(et= new (YYTHD->mem_root) Event_timed()))// implicitly calls Event_timed::init() YYABORT; lex->et = et; @@ -4739,9 +4764,9 @@ alter: } /* - We have to turn of CLIENT_MULTI_QUERIES while parsing a - stored procedure, otherwise yylex will chop it into pieces - at each ';'. + 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; @@ -7661,6 +7686,10 @@ 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) @@ -8430,12 +8459,8 @@ show_param: } | CREATE EVENT_SYM sp_name { - Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT; Lex->spname= $3; - Lex->et= new (YYTHD->mem_root) Event_timed(); - if (!Lex->et) - YYABORT; - Lex->et->init_definer(YYTHD); + Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT; } ; |