summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore5
-rw-r--r--sql/event_data_objects.cc89
-rw-r--r--sql/event_data_objects.h9
-rw-r--r--sql/events.cc14
-rw-r--r--sql/events.h13
-rw-r--r--sql/share/errmsg.txt3
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_parse.cc11
-rw-r--r--sql/sql_yacc.yy41
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;
}
;