summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/events.result4
-rw-r--r--mysql-test/t/events.test4
-rw-r--r--sql/event_data_objects.cc551
-rw-r--r--sql/event_data_objects.h63
-rw-r--r--sql/event_db_repository.cc381
-rw-r--r--sql/event_db_repository.h15
-rw-r--r--sql/event_scheduler.cc78
-rw-r--r--sql/event_scheduler.h11
-rw-r--r--sql/events.cc32
-rw-r--r--sql/events.h10
-rw-r--r--sql/sql_lex.cc4
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_parse.cc88
-rw-r--r--sql/sql_yacc.yy151
14 files changed, 569 insertions, 826 deletions
diff --git a/mysql-test/r/events.result b/mysql-test/r/events.result
index f95953cdc86..473acbd5984 100644
--- a/mysql-test/r/events.result
+++ b/mysql-test/r/events.result
@@ -297,9 +297,9 @@ select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_comp
db name body definer convert_tz(execute_at, 'UTC', 'SYSTEM') on_completion
events_test e_26 set @a = 5 root@localhost 2017-01-01 00:00:00 DROP
drop event e_26;
-create event e_26 on schedule at NULL disabled do set @a = 5;
+create event e_26 on schedule at NULL disable do set @a = 5;
ERROR HY000: Incorrect AT value: 'NULL'
-create event e_26 on schedule at 'definitely not a datetime' disabled do set @a = 5;
+create event e_26 on schedule at 'definitely not a datetime' disable do set @a = 5;
ERROR HY000: Incorrect AT value: 'definitely not a datetime'
set names utf8;
create event задачка on schedule every 123 minute starts now() ends now() + interval 1 month do select 1;
diff --git a/mysql-test/t/events.test b/mysql-test/t/events.test
index 1940016a7a1..5dff48c203b 100644
--- a/mysql-test/t/events.test
+++ b/mysql-test/t/events.test
@@ -255,9 +255,9 @@ create event e_26 on schedule at '2017-01-01 00:00:00' disable do set @a = 5;
select db, name, body, definer, convert_tz(execute_at, 'UTC', 'SYSTEM'), on_completion from mysql.event;
drop event e_26;
--error ER_WRONG_VALUE
-create event e_26 on schedule at NULL disabled do set @a = 5;
+create event e_26 on schedule at NULL disable do set @a = 5;
--error ER_WRONG_VALUE
-create event e_26 on schedule at 'definitely not a datetime' disabled do set @a = 5;
+create event e_26 on schedule at 'definitely not a datetime' disable do set @a = 5;
set names utf8;
create event задачка on schedule every 123 minute starts now() ends now() + interval 1 month do select 1;
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 228f1a4ff4a..a47a3e9e936 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -35,186 +35,18 @@ Event_parse_data::new_instance(THD *thd)
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
-
- SYNOPSIS
- Event_timed::Event_timed()
-*/
-
-Event_timed::Event_timed():in_spawned_thread(0),locked_by_thread_id(0),
- running(0), thread_id(0), status_changed(false),
- last_executed_changed(false), expression(0),
- created(0), modified(0),
- on_completion(Event_timed::ON_COMPLETION_DROP),
- status(Event_timed::ENABLED), sphead(0),
- sql_mode(0), body_begin(0), dropped(false),
- free_sphead_on_delete(true), flags(0)
-
-{
- pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&this->COND_finished, NULL);
- init();
-}
-
-
-/*
- Destructor
-
- SYNOPSIS
- Event_timed::~Event_timed()
-*/
-
-Event_timed::~Event_timed()
-{
- deinit_mutexes();
-
- if (free_sphead_on_delete)
- free_sp();
-}
-
-
-/*
- Destructor
-
- SYNOPSIS
- Event_timed::~deinit_mutexes()
-*/
-
-void
-Event_timed::deinit_mutexes()
-{
- pthread_mutex_destroy(&this->LOCK_running);
- pthread_cond_destroy(&this->COND_finished);
-}
-
-
-/*
- Checks whether the event is running
-
- SYNOPSIS
- Event_timed::is_running()
-*/
-
-bool
-Event_timed::is_running()
-{
- bool ret;
-
- VOID(pthread_mutex_lock(&this->LOCK_running));
- ret= running;
- VOID(pthread_mutex_unlock(&this->LOCK_running));
-
- return ret;
-}
-
-
-/*
- Init all member variables
-
- SYNOPSIS
- Event_timed::init()
-*/
-
-void
-Event_timed::init()
-{
- DBUG_ENTER("Event_timed::init");
-
- dbname.str= name.str= body.str= comment.str= 0;
- dbname.length= name.length= body.length= comment.length= 0;
+ status= ENABLED;
+ on_completion= ON_COMPLETION_DROP;
+ expression= 0;
+ /* Actually in the parser STARTS is always set */
set_zero_time(&starts, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&ends, MYSQL_TIMESTAMP_DATETIME);
set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
- set_zero_time(&last_executed, MYSQL_TIMESTAMP_DATETIME);
starts_null= ends_null= execute_at_null= TRUE;
- definer_user.str= definer_host.str= 0;
- definer_user.length= definer_host.length= 0;
-
- sql_mode= 0;
-
- DBUG_VOID_RETURN;
+ body.str= comment.str= 0;
+ body.length= comment.length= 0;
}
@@ -222,37 +54,25 @@ Event_timed::init()
Set a name of the event
SYNOPSIS
- Event_timed::init_name()
+ Event_parse_data::init_name()
thd THD
spn the name extracted in the parser
*/
void
-Event_timed::init_name(THD *thd, sp_name *spn)
+Event_parse_data::init_name(THD *thd, sp_name *spn)
{
- DBUG_ENTER("Event_timed::init_name");
- /* During parsing, we must use thd->mem_root */
- MEM_ROOT *root= thd->mem_root;
+ DBUG_ENTER("Event_parse_data::init_name");
/* We have to copy strings to get them into the right memroot */
- if (spn)
- {
- dbname.length= spn->m_db.length;
- if (spn->m_db.length == 0)
- dbname.str= NULL;
- else
- dbname.str= strmake_root(root, spn->m_db.str, spn->m_db.length);
- name.length= spn->m_name.length;
- name.str= strmake_root(root, spn->m_name.str, spn->m_name.length);
-
- if (spn->m_qname.length == 0)
- spn->init_qname(thd);
- }
- else if (thd->db)
- {
- dbname.length= thd->db_length;
- dbname.str= strmake_root(root, thd->db, dbname.length);
- }
+ DBUG_ASSERT(spn);
+ dbname.length= spn->m_db.length;
+ if (spn->m_db.length == 0)
+ dbname.str= NULL;
+ else
+ dbname.str= thd->strmake(spn->m_db.str, spn->m_db.length);
+ name.length= spn->m_name.length;
+ name.str= thd->strmake(spn->m_name.str, spn->m_name.length);
DBUG_PRINT("dbname", ("len=%d db=%s",dbname.length, dbname.str));
DBUG_PRINT("name", ("len=%d name=%s",name.length, name.str));
@@ -265,7 +85,7 @@ Event_timed::init_name(THD *thd, sp_name *spn)
Set body of the event - what should be executed.
SYNOPSIS
- Event_timed::init_body()
+ Event_parse_data::init_body()
thd THD
NOTE
@@ -277,9 +97,9 @@ Event_timed::init_name(THD *thd, sp_name *spn)
*/
void
-Event_timed::init_body(THD *thd)
+Event_parse_data::init_body(THD *thd)
{
- DBUG_ENTER("Event_timed::init_body");
+ 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));
@@ -331,17 +151,60 @@ Event_timed::init_body(THD *thd)
++body_begin;
--body.length;
}
- body.str= strmake_root(thd->mem_root, (char *)body_begin, body.length);
+ body.str= thd->strmake((char *)body_begin, body.length);
DBUG_VOID_RETURN;
}
/*
+ Inits definer (definer_user and definer_host) during parsing.
+
+ SYNOPSIS
+ Event_parse_data::init_definer()
+
+ RETURN VALUE
+ 0 OK
+*/
+
+int
+Event_parse_data::init_definer(THD *thd)
+{
+ int definer_user_len;
+ int definer_host_len;
+ DBUG_ENTER("Event_parse_data::init_definer");
+
+ DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
+ "thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
+ thd->security_ctx->priv_user));
+
+ definer_user_len= strlen(thd->security_ctx->priv_user);
+ definer_host_len= strlen(thd->security_ctx->priv_host);
+
+ /* + 1 for @ */
+ DBUG_PRINT("info",("init definer as whole"));
+ definer.length= definer_user_len + definer_host_len + 1;
+ definer.str= thd->alloc(definer.length + 1);
+
+ DBUG_PRINT("info",("copy the user"));
+ memcpy(definer.str, thd->security_ctx->priv_user, definer_user_len);
+ definer.str[definer_user_len]= '@';
+
+ DBUG_PRINT("info",("copy the host"));
+ memcpy(definer.str + definer_user_len + 1, thd->security_ctx->priv_host,
+ definer_host_len);
+ definer.str[definer.length]= '\0';
+ DBUG_PRINT("info",("definer [%s] initted", definer.str));
+
+ DBUG_RETURN(0);
+}
+
+
+/*
Set time for execution for one time events.
SYNOPSIS
- Event_timed::init_execute_at()
+ Event_parse_data::init_execute_at()
expr when (datetime)
RETURN VALUE
@@ -352,14 +215,14 @@ Event_timed::init_body(THD *thd)
*/
int
-Event_timed::init_execute_at(THD *thd, Item *expr)
+Event_parse_data::init_execute_at(THD *thd, Item *expr)
{
my_bool not_used;
TIME ltime;
my_time_t t;
TIME time_tmp;
- DBUG_ENTER("Event_timed::init_execute_at");
+ DBUG_ENTER("Event_parse_data::init_execute_at");
if (expr->fix_fields(thd, &expr))
DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -368,7 +231,7 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
DBUG_PRINT("info", ("starts_null && ends_null should be 1 is %d",
(starts_null && ends_null)));
DBUG_ASSERT(starts_null && ends_null);
-
+
/* let's check whether time is in the past */
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,
(my_time_t) thd->query_start());
@@ -403,7 +266,7 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
Set time for execution for transient events.
SYNOPSIS
- Event_timed::init_interval()
+ Event_parse_data::init_interval()
expr how much?
new_interval what is the interval
@@ -415,12 +278,12 @@ Event_timed::init_execute_at(THD *thd, Item *expr)
*/
int
-Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
+Event_parse_data::init_interval(THD *thd, Item *expr, interval_type new_interval)
{
String value;
INTERVAL interval_tmp;
- DBUG_ENTER("Event_timed::init_interval");
+ DBUG_ENTER("Event_parse_data::init_interval");
if (expr->fix_fields(thd, &expr))
DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -504,9 +367,9 @@ Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
Set activation time.
SYNOPSIS
- Event_timed::init_starts()
- expr how much?
- interval what is the interval
+ Event_parse_data::init_starts()
+ expr how much?
+ interval what is the interval
NOTES
Note that activation time is not execution time.
@@ -523,13 +386,13 @@ Event_timed::init_interval(THD *thd, Item *expr, interval_type new_interval)
*/
int
-Event_timed::init_starts(THD *thd, Item *new_starts)
+Event_parse_data::init_starts(THD *thd, Item *new_starts)
{
my_bool not_used;
TIME ltime, time_tmp;
my_time_t t;
- DBUG_ENTER("Event_timed::init_starts");
+ DBUG_ENTER("Event_parse_data::init_starts");
if (new_starts->fix_fields(thd, &new_starts))
DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -570,7 +433,7 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
Set deactivation time.
SYNOPSIS
- Event_timed::init_ends()
+ Event_parse_data::init_ends()
thd THD
new_ends when?
@@ -590,13 +453,13 @@ Event_timed::init_starts(THD *thd, Item *new_starts)
*/
int
-Event_timed::init_ends(THD *thd, Item *new_ends)
+Event_parse_data::init_ends(THD *thd, Item *new_ends)
{
TIME ltime, ltime_now;
my_bool not_used;
my_time_t t;
- DBUG_ENTER("Event_timed::init_ends");
+ DBUG_ENTER("Event_parse_data::init_ends");
if (new_ends->fix_fields(thd, &new_ends))
DBUG_RETURN(EVEX_PARSE_ERROR);
@@ -641,67 +504,106 @@ Event_timed::init_ends(THD *thd, Item *new_ends)
/*
- Sets comment.
+ Constructor
SYNOPSIS
- Event_timed::init_comment()
- thd THD - used for memory allocation
- comment the string.
+ Event_timed::Event_timed()
*/
-void
-Event_timed::init_comment(THD *thd, LEX_STRING *set_comment)
+Event_timed::Event_timed():in_spawned_thread(0),locked_by_thread_id(0),
+ running(0), thread_id(0), status_changed(false),
+ last_executed_changed(false), expression(0),
+ created(0), modified(0),
+ on_completion(Event_timed::ON_COMPLETION_DROP),
+ status(Event_timed::ENABLED), sphead(0),
+ sql_mode(0), dropped(false),
+ free_sphead_on_delete(true), flags(0)
+
{
- DBUG_ENTER("Event_timed::init_comment");
+ pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&this->COND_finished, NULL);
+ init();
+}
- comment.str= strmake_root(thd->mem_root, set_comment->str,
- comment.length= set_comment->length);
- DBUG_VOID_RETURN;
+/*
+ Destructor
+
+ SYNOPSIS
+ Event_timed::~Event_timed()
+*/
+
+Event_timed::~Event_timed()
+{
+ deinit_mutexes();
+
+ if (free_sphead_on_delete)
+ free_sp();
}
/*
- Inits definer (definer_user and definer_host) during parsing.
+ Destructor
SYNOPSIS
- Event_timed::init_definer()
-
- RETURN VALUE
- 0 OK
+ Event_timed::deinit_mutexes()
*/
-int
-Event_timed::init_definer(THD *thd)
+void
+Event_timed::deinit_mutexes()
{
- DBUG_ENTER("Event_timed::init_definer");
+ pthread_mutex_destroy(&this->LOCK_running);
+ pthread_cond_destroy(&this->COND_finished);
+}
- DBUG_PRINT("info",("init definer_user thd->mem_root=0x%lx "
- "thd->sec_ctx->priv_user=0x%lx", thd->mem_root,
- thd->security_ctx->priv_user));
- definer_user.str= strdup_root(thd->mem_root, thd->security_ctx->priv_user);
- definer_user.length= strlen(thd->security_ctx->priv_user);
- DBUG_PRINT("info",("init definer_host thd->s_c->priv_host=0x%lx",
- thd->security_ctx->priv_host));
- definer_host.str= strdup_root(thd->mem_root, thd->security_ctx->priv_host);
- definer_host.length= strlen(thd->security_ctx->priv_host);
+/*
+ Checks whether the event is running
- DBUG_PRINT("info",("init definer as whole"));
- definer.length= definer_user.length + definer_host.length + 1;
- definer.str= alloc_root(thd->mem_root, definer.length + 1);
+ SYNOPSIS
+ Event_timed::is_running()
+*/
- DBUG_PRINT("info",("copy the user"));
- memcpy(definer.str, definer_user.str, definer_user.length);
- definer.str[definer_user.length]= '@';
+bool
+Event_timed::is_running()
+{
+ bool ret;
- DBUG_PRINT("info",("copy the host"));
- memcpy(definer.str + definer_user.length + 1, definer_host.str,
- definer_host.length);
- definer.str[definer.length]= '\0';
- DBUG_PRINT("info",("definer initted"));
+ VOID(pthread_mutex_lock(&this->LOCK_running));
+ ret= running;
+ VOID(pthread_mutex_unlock(&this->LOCK_running));
- DBUG_RETURN(0);
+ return ret;
+}
+
+
+/*
+ Init all member variables
+
+ SYNOPSIS
+ Event_timed::init()
+*/
+
+void
+Event_timed::init()
+{
+ DBUG_ENTER("Event_timed::init");
+
+ dbname.str= name.str= body.str= comment.str= 0;
+ dbname.length= name.length= body.length= comment.length= 0;
+
+ set_zero_time(&starts, MYSQL_TIMESTAMP_DATETIME);
+ set_zero_time(&ends, MYSQL_TIMESTAMP_DATETIME);
+ set_zero_time(&execute_at, MYSQL_TIMESTAMP_DATETIME);
+ set_zero_time(&last_executed, MYSQL_TIMESTAMP_DATETIME);
+ starts_null= ends_null= execute_at_null= TRUE;
+
+ definer_user.str= definer_host.str= 0;
+ definer_user.length= definer_host.length= 0;
+
+ sql_mode= 0;
+
+ DBUG_VOID_RETURN;
}
@@ -739,20 +641,17 @@ Event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
if (table->s->fields != ET_FIELD_COUNT)
goto error;
- if ((et->dbname.str= get_field(mem_root,
- table->field[ET_FIELD_DB])) == NULL)
+ if ((et->dbname.str= get_field(mem_root, table->field[ET_FIELD_DB])) == NULL)
goto error;
et->dbname.length= strlen(et->dbname.str);
- if ((et->name.str= get_field(mem_root,
- table->field[ET_FIELD_NAME])) == NULL)
+ if ((et->name.str= get_field(mem_root, table->field[ET_FIELD_NAME])) == NULL)
goto error;
et->name.length= strlen(et->name.str);
- if ((et->body.str= get_field(mem_root,
- table->field[ET_FIELD_BODY])) == NULL)
+ if ((et->body.str= get_field(mem_root, table->field[ET_FIELD_BODY])) == NULL)
goto error;
et->body.length= strlen(et->body.str);
@@ -837,7 +736,6 @@ Event_timed::load_from_row(MEM_ROOT *mem_root, TABLE *table)
et->comment.length= strlen(et->comment.str);
else
et->comment.length= 0;
-
et->sql_mode= (ulong) table->field[ET_FIELD_SQL_MODE]->val_int();
@@ -858,7 +756,7 @@ error:
time_now current time
i_value quantity of time type interval to add
i_type type of interval to add (SECOND, MINUTE, HOUR, WEEK ...)
-
+
RETURN VALUE
0 OK
1 Error
@@ -1639,7 +1537,6 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
&security_ctx, &save_ctx);
thd->lex= &lex;
lex_start(thd, (uchar*)thd->query, thd->query_length);
- lex.et_compile_phase= TRUE;
if (MYSQLparse((void *)thd) || thd->is_fatal_error)
{
DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d",
@@ -1662,7 +1559,7 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
}
DBUG_PRINT("note", ("success compiling %s.%s", dbname.str, name.str));
- sphead= lex.et->sphead;
+ sphead= lex.sphead;
sphead->m_db= dbname;
sphead->set_definer(definer.str, definer.length);
@@ -1670,8 +1567,6 @@ Event_timed::compile(THD *thd, MEM_ROOT *mem_root)
sphead->optimize();
ret= 0;
done:
- lex.et->free_sphead_on_delete= false;
- lex.et->deinit_mutexes();
lex_end(&lex);
thd->restore_security_context(save_ctx);
@@ -1709,7 +1604,7 @@ extern pthread_attr_t connection_attrib;
int
Event_timed::spawn_now(void * (*thread_func)(void*), void *arg)
-{
+{
THD *thd= current_thd;
int ret= EVENT_EXEC_STARTED;
DBUG_ENTER("Event_timed::spawn_now");
@@ -1875,7 +1770,6 @@ event_timed_db_equal(Event_timed *et, LEX_STRING *db)
}
-
/*
Checks whether two events are equal by identifiers
@@ -1888,121 +1782,8 @@ event_timed_db_equal(Event_timed *et, LEX_STRING *db)
*/
bool
-event_timed_identifier_equal(Event_timed *a, Event_timed *b)
+event_timed_identifier_equal(LEX_STRING db, LEX_STRING name, Event_timed *b)
{
- return event_timed_name_equal(a, &b->name) &&
- 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);
-}
-
-
-/*
- Switches the security context
- SYNOPSIS
- change_security_context()
- thd Thread
- user The user
- host The host of the user
- db The schema for which the security_ctx will be loaded
- s_ctx Security context to load state into
- backup Where to store the old context
-
- RETURN VALUE
- 0 - OK
- 1 - Error (generates error too)
-*/
-
-bool
-change_security_context(THD *thd, LEX_STRING user, LEX_STRING host,
- LEX_STRING db, Security_context *s_ctx,
- Security_context **backup)
-{
- DBUG_ENTER("change_security_context");
- DBUG_PRINT("info",("%s@%s@%s", user.str, host.str, db.str));
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- s_ctx->init();
- *backup= 0;
- if (acl_getroot_no_password(s_ctx, user.str, host.str, host.str, db.str))
- {
- my_error(ER_NO_SUCH_USER, MYF(0), user.str, host.str);
- DBUG_RETURN(TRUE);
- }
- *backup= thd->security_ctx;
- thd->security_ctx= s_ctx;
-#endif
- DBUG_RETURN(FALSE);
-}
-
-
-/*
- Restores the security context
- SYNOPSIS
- restore_security_context()
- thd - thread
- backup - switch to this context
-*/
-
-void
-restore_security_context(THD *thd, Security_context *backup)
-{
- DBUG_ENTER("restore_security_context");
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (backup)
- thd->security_ctx= backup;
-#endif
- DBUG_VOID_RETURN;
+ return !sortcmp_lex_string(name, b->name, system_charset_info) &&
+ !sortcmp_lex_string(db, b->dbname, system_charset_info);
}
diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h
index ff547cebd5b..d8df8dd1e6c 100644
--- a/sql/event_data_objects.h
+++ b/sql/event_data_objects.h
@@ -54,19 +54,9 @@ class Event_timed;
bool
event_timed_db_equal(Event_timed *et, LEX_STRING *db);
-
-/* Compares the whole identifier*/
-bool
-event_timed_identifier_equal(Event_timed *a, Event_timed *b);
-
-/* 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);
+event_timed_identifier_equal(LEX_STRING db, LEX_STRING name, Event_timed *b);
class Event_timed
@@ -123,7 +113,6 @@ public:
enum enum_status status;
sp_head *sphead;
ulong sql_mode;
- const uchar *body_begin;
bool dropped;
bool free_sphead_on_delete;
@@ -138,9 +127,6 @@ public:
DBUG_RETURN(p);
}
- static void *operator new(size_t size, MEM_ROOT *mem_root)
- { return (void*) alloc_root(mem_root, (uint) size); }
-
static void operator delete(void *ptr, size_t size)
{
DBUG_ENTER("Event_timed::delete(ptr,size)");
@@ -150,17 +136,6 @@ public:
DBUG_VOID_RETURN;
}
- static void operator delete(void *ptr, MEM_ROOT *mem_root)
- {
- /*
- Don't free the memory it will be done by the mem_root but
- we need to call the destructor because we free other resources
- which are not allocated on the root but on the heap, or we
- deinit mutexes.
- */
- DBUG_ASSERT(0);
- }
-
Event_timed();
~Event_timed();
@@ -172,30 +147,6 @@ public:
deinit_mutexes();
int
- init_definer(THD *thd);
-
- int
- init_execute_at(THD *thd, Item *expr);
-
- int
- init_interval(THD *thd, Item *expr, interval_type new_interval);
-
- void
- init_name(THD *thd, sp_name *spn);
-
- int
- init_starts(THD *thd, Item *starts);
-
- int
- init_ends(THD *thd, Item *ends);
-
- void
- init_body(THD *thd);
-
- void
- init_comment(THD *thd, LEX_STRING *set_comment);
-
- int
load_from_row(MEM_ROOT *mem_root, TABLE *table);
bool
@@ -231,9 +182,6 @@ public:
void
free_sp();
- bool
- has_equal_db(Event_timed *etn);
-
int
kill_thread(THD *thd);
@@ -268,12 +216,9 @@ public:
LEX_STRING dbname;
LEX_STRING name;
LEX_STRING body;
-
- LEX_STRING definer_user;
- LEX_STRING definer_host;
LEX_STRING definer;// combination of user and host
-
LEX_STRING comment;
+
Item* item_starts;
Item* item_ends;
Item* item_execute_at;
@@ -316,10 +261,6 @@ public:
void
init_body(THD *thd);
-
- void
- init_comment(THD *thd, LEX_STRING *set_comment);
-
};
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index fc771b6bac3..68d8234cc90 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -34,7 +34,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
{(char *) STRING_WITH_LEN("db")},
{(char *) STRING_WITH_LEN("char(64)")},
{(char *) STRING_WITH_LEN("utf8")}
- },
+ },
{
{(char *) STRING_WITH_LEN("name")},
{(char *) STRING_WITH_LEN("char(64)")},
@@ -44,7 +44,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
{(char *) STRING_WITH_LEN("body")},
{(char *) STRING_WITH_LEN("longblob")},
{NULL, 0}
- },
+ },
{
{(char *) STRING_WITH_LEN("definer")},
{(char *) STRING_WITH_LEN("char(77)")},
@@ -54,7 +54,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
{(char *) STRING_WITH_LEN("execute_at")},
{(char *) STRING_WITH_LEN("datetime")},
{NULL, 0}
- },
+ },
{
{(char *) STRING_WITH_LEN("interval_value")},
{(char *) STRING_WITH_LEN("int(11)")},
@@ -68,7 +68,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
"'DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND',"
"'SECOND_MICROSECOND')")},
{NULL, 0}
- },
+ },
{
{(char *) STRING_WITH_LEN("created")},
{(char *) STRING_WITH_LEN("timestamp")},
@@ -78,7 +78,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
{(char *) STRING_WITH_LEN("modified")},
{(char *) STRING_WITH_LEN("timestamp")},
{NULL, 0}
- },
+ },
{
{(char *) STRING_WITH_LEN("last_executed")},
{(char *) STRING_WITH_LEN("datetime")},
@@ -88,7 +88,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
{(char *) STRING_WITH_LEN("starts")},
{(char *) STRING_WITH_LEN("datetime")},
{NULL, 0}
- },
+ },
{
{(char *) STRING_WITH_LEN("ends")},
{(char *) STRING_WITH_LEN("datetime")},
@@ -98,7 +98,7 @@ TABLE_FIELD_W_TYPE event_table_fields[ET_FIELD_COUNT] = {
{(char *) STRING_WITH_LEN("status")},
{(char *) STRING_WITH_LEN("enum('ENABLED','DISABLED')")},
{NULL, 0}
- },
+ },
{
{(char *) STRING_WITH_LEN("on_completion")},
{(char *) STRING_WITH_LEN("enum('DROP','PRESERVE')")},
@@ -206,6 +206,133 @@ evex_fill_row(THD *thd, TABLE *table, Event_timed *et, my_bool is_update)
table->field[ET_FIELD_STARTS]->set_notnull();
table->field[ET_FIELD_STARTS]->
store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME);
+ }
+
+ if (!et->ends_null)
+ {
+ table->field[ET_FIELD_ENDS]->set_notnull();
+ table->field[ET_FIELD_ENDS]->
+ store_time(&et->ends, MYSQL_TIMESTAMP_DATETIME);
+ }
+ }
+ else if (et->execute_at.year)
+ {
+ table->field[ET_FIELD_INTERVAL_EXPR]->set_null();
+ table->field[ET_FIELD_TRANSIENT_INTERVAL]->set_null();
+ table->field[ET_FIELD_STARTS]->set_null();
+ table->field[ET_FIELD_ENDS]->set_null();
+
+ table->field[ET_FIELD_EXECUTE_AT]->set_notnull();
+ table->field[ET_FIELD_EXECUTE_AT]->
+ store_time(&et->execute_at, MYSQL_TIMESTAMP_DATETIME);
+ }
+ else
+ {
+ DBUG_ASSERT(is_update);
+ /*
+ it is normal to be here when the action is update
+ this is an error if the action is create. something is borked
+ */
+ }
+
+ ((Field_timestamp *)table->field[ET_FIELD_MODIFIED])->set_time();
+
+ if (et->comment.str)
+ {
+ if (table->field[field_num= ET_FIELD_COMMENT]->
+ store(et->comment.str, et->comment.length, scs))
+ goto err_truncate;
+ }
+
+ DBUG_RETURN(0);
+err_truncate:
+ my_error(ER_EVENT_DATA_TOO_LONG, MYF(0), table->field[field_num]->field_name);
+ DBUG_RETURN(EVEX_GENERAL_ERROR);
+}
+
+
+/*
+ Puts some data common to CREATE and ALTER EVENT into a row.
+
+ SYNOPSIS
+ evex_fill_row()
+ thd THD
+ table the row to fill out
+ et Event's data
+
+ RETURN VALUE
+ 0 - OK
+ EVEX_GENERAL_ERROR - bad data
+ EVEX_GET_FIELD_FAILED - field count does not match. table corrupted?
+
+ DESCRIPTION
+ Used both when an event is created and when it is altered.
+*/
+
+static int
+evex_fill_row(THD *thd, TABLE *table, Event_parse_data *et, my_bool is_update)
+{
+ CHARSET_INFO *scs= system_charset_info;
+ enum enum_events_table_field field_num;
+
+ DBUG_ENTER("evex_fill_row");
+
+ DBUG_PRINT("info", ("dbname=[%s]", et->dbname.str));
+ DBUG_PRINT("info", ("name =[%s]", et->name.str));
+ DBUG_PRINT("info", ("body =[%s]", et->body.str));
+
+ if (table->field[field_num= ET_FIELD_DEFINER]->
+ store(et->definer.str, et->definer.length, scs))
+ goto err_truncate;
+
+ if (table->field[field_num= ET_FIELD_DB]->
+ store(et->dbname.str, et->dbname.length, scs))
+ goto err_truncate;
+
+ if (table->field[field_num= ET_FIELD_NAME]->
+ store(et->name.str, et->name.length, scs))
+ goto err_truncate;
+
+ /* both ON_COMPLETION and STATUS are NOT NULL thus not calling set_notnull()*/
+ table->field[ET_FIELD_ON_COMPLETION]->
+ store((longlong)et->on_completion, true);
+
+ table->field[ET_FIELD_STATUS]->store((longlong)et->status, true);
+
+ /*
+ Change the SQL_MODE only if body was present in an ALTER EVENT and of course
+ always during CREATE EVENT.
+ */
+ if (et->body.str)
+ {
+ table->field[ET_FIELD_SQL_MODE]->
+ store((longlong)thd->variables.sql_mode, true);
+
+ if (table->field[field_num= ET_FIELD_BODY]->
+ store(et->body.str, et->body.length, scs))
+ goto err_truncate;
+ }
+
+ if (et->expression)
+ {
+ table->field[ET_FIELD_INTERVAL_EXPR]->set_notnull();
+ table->field[ET_FIELD_INTERVAL_EXPR]->store((longlong)et->expression, true);
+
+ table->field[ET_FIELD_TRANSIENT_INTERVAL]->set_notnull();
+ /*
+ In the enum (C) intervals start from 0 but in mysql enum valid values start
+ from 1. Thus +1 offset is needed!
+ */
+ table->field[ET_FIELD_TRANSIENT_INTERVAL]->
+ store((longlong)et->interval+1, true);
+
+ table->field[ET_FIELD_EXECUTE_AT]->set_null();
+
+ if (!et->starts_null)
+ {
+ table->field[ET_FIELD_STARTS]->set_notnull();
+ table->field[ET_FIELD_STARTS]->
+ store_time(&et->starts, MYSQL_TIMESTAMP_DATETIME);
}
if (!et->ends_null)
@@ -462,14 +589,15 @@ Event_db_repository::fill_schema_events(THD *thd, TABLE_LIST *tables, char *db)
*/
int
-Event_db_repository::find_event(THD *thd, sp_name *name, Event_timed **ett,
+Event_db_repository::find_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
+ Event_timed **ett,
TABLE *tbl, MEM_ROOT *root)
{
TABLE *table;
int ret;
Event_timed *et= NULL;
DBUG_ENTER("db_find_event");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %*s", name.length, name.str));
if (tbl)
table= tbl;
@@ -480,22 +608,22 @@ Event_db_repository::find_event(THD *thd, sp_name *name, Event_timed **ett,
goto done;
}
- if ((ret= evex_db_find_event_by_name(thd, name->m_db, name->m_name, table)))
+ if ((ret= evex_db_find_event_by_name(thd, dbname, name, table)))
{
- my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name->m_name.str);
- goto done;
+ my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), name.str);
+ goto done;
}
et= new Event_timed;
-
+
/*
- 1)The table should not be closed beforehand. ::load_from_row() only loads
+ 1)The table should not be closed beforehand. ::load_from_row() only loads
and does not compile
2)::load_from_row() is silent on error therefore we emit error msg here
*/
if ((ret= et->load_from_row(root, table)))
{
- my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0));
+ my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "event");
goto done;
}
@@ -557,7 +685,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
if (simple_open_n_lock_tables(thd, &tables))
DBUG_RETURN(1);
-
+
if (table_check_intact(tables.table, ET_FIELD_COUNT,
event_table_fields,
&mysql_event_last_create_time,
@@ -573,6 +701,118 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
/*
+ Checks parameters which we got from the parsing phase.
+
+ SYNOPSIS
+ evex_check_params()
+ thd THD
+ et event's data
+
+ RETURNS
+ 0 OK
+ EVEX_BAD_PARAMS Error
+
+ REMARKS
+ Issues error messages
+*/
+
+int
+evex_check_params(THD *thd, Event_parse_data *parse_data)
+{
+ const char *pos= NULL;
+ Item *bad_item;
+
+ DBUG_ENTER("evex_check_timing_params");
+ DBUG_PRINT("info", ("execute_at=0x%d expr=0x%d starts=0x%d ends=0x%d",
+ parse_data->item_execute_at,
+ parse_data->item_expression,
+ parse_data->item_starts,
+ parse_data->item_ends));
+
+ parse_data->init_name(thd, parse_data->identifier);
+ parse_data->init_definer(thd);
+
+ if (!parse_data->dbname.str ||
+ (thd->lex->sql_command == SQLCOM_ALTER_EVENT && thd->lex->spname &&
+ !thd->lex->spname->m_db.str))
+ {
+ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
+ DBUG_RETURN(EVEX_BAD_PARAMS);
+ }
+
+ if (check_access(thd, EVENT_ACL, parse_data->dbname.str, 0, 0, 0,
+ is_schema_db(parse_data->dbname.str)) ||
+ (thd->lex->sql_command == SQLCOM_ALTER_EVENT && thd->lex->spname &&
+ (check_access(thd, EVENT_ACL, thd->lex->spname->m_db.str, 0, 0, 0,
+ is_schema_db(thd->lex->spname->m_db.str)))))
+ DBUG_RETURN(EVEX_BAD_PARAMS);
+
+ if (parse_data->item_execute_at)
+ {
+ DBUG_PRINT("info", ("ONE TIME"));
+ if (parse_data->init_execute_at(thd, parse_data->item_execute_at))
+ {
+ pos= "AT";
+ bad_item= parse_data->item_execute_at;
+ goto wrong_value;
+ }
+ }
+ else
+ {
+ int res;
+ DBUG_PRINT("info", ("RECURRING"));
+
+ if (parse_data->item_expression &&
+ (res= parse_data->init_interval(thd, parse_data->item_expression,
+ parse_data->interval)))
+ {
+ switch (res) {
+ case EVEX_BAD_PARAMS:
+ my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0));
+ break;
+ case EVEX_MICROSECOND_UNSUP:
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND");
+ break;
+ default:
+ pos= "INTERVAL";
+ bad_item= parse_data->item_expression;
+ goto wrong_value;
+ }
+ DBUG_RETURN(EVEX_BAD_PARAMS);
+ }
+
+ if (parse_data->item_starts &&
+ parse_data->init_starts(thd, parse_data->item_starts))
+ {
+ pos= "STARTS";
+ bad_item= parse_data->item_starts;
+ goto wrong_value;
+ }
+
+ if (parse_data->item_ends &&
+ parse_data->init_ends(thd, parse_data->item_ends))
+ {
+ /*
+ despite the error name the value is
+ eng "ENDS is either invalid or before STARTS"
+ */
+ my_error(ER_EVENT_ENDS_BEFORE_STARTS, MYF(0));
+ DBUG_RETURN(EVEX_BAD_PARAMS);
+ }
+ }
+ DBUG_RETURN(0);
+wrong_value:
+ {
+ char buff[120];
+ String str(buff,(uint32) sizeof(buff), system_charset_info);
+ String *str2= bad_item->fixed? bad_item->val_str(&str):NULL;
+ my_error(ER_WRONG_VALUE, MYF(0), pos, str2? str2->c_ptr():"NULL");
+ DBUG_RETURN(EVEX_BAD_PARAMS);
+ }
+}
+
+
+/*
Creates an event in mysql.event
SYNOPSIS
@@ -592,7 +832,7 @@ Event_db_repository::open_event_table(THD *thd, enum thr_lock_type lock_type,
*/
int
-Event_db_repository::create_event(THD *thd, Event_timed *et,
+Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
my_bool create_if_not, uint *rows_affected)
{
int ret= 0;
@@ -601,7 +841,6 @@ Event_db_repository::create_event(THD *thd, Event_timed *et,
char olddb[128];
bool dbchanged= false;
DBUG_ENTER("Event_db_repository::create_event");
- DBUG_PRINT("enter", ("name: %.*s", et->name.length, et->name.str));
*rows_affected= 0;
DBUG_PRINT("info", ("open mysql.event for update"));
@@ -611,22 +850,28 @@ Event_db_repository::create_event(THD *thd, Event_timed *et,
goto err;
}
+ if (evex_check_params(thd, parse_data))
+ goto err;
+
+ DBUG_PRINT("info", ("name: %.*s", parse_data->name.length,
+ parse_data->name.str));
+
DBUG_PRINT("info", ("check existance of an event with the same name"));
- if (!evex_db_find_event_by_name(thd, et->dbname, et->name, table))
+ if (!evex_db_find_event_by_name(thd, parse_data->dbname, parse_data->name, table))
{
if (create_if_not)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_EVENT_ALREADY_EXISTS, ER(ER_EVENT_ALREADY_EXISTS),
- et->name.str);
+ parse_data->name.str);
goto ok;
}
- my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->name.str);
+ my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), parse_data->name.str);
goto err;
}
DBUG_PRINT("info", ("non-existant, go forward"));
- if ((ret= sp_use_new_db(thd, et->dbname.str,olddb, sizeof(olddb),0,
+ if ((ret= sp_use_new_db(thd, parse_data->dbname.str, olddb, sizeof(olddb), 0,
&dbchanged)))
{
my_error(ER_BAD_DB_ERROR, MYF(0));
@@ -635,28 +880,30 @@ Event_db_repository::create_event(THD *thd, Event_timed *et,
restore_record(table, s->default_values); // Get default values for fields
- if (system_charset_info->cset->numchars(system_charset_info, et->dbname.str,
- et->dbname.str + et->dbname.length)
- > EVEX_DB_FIELD_LEN)
+ if (system_charset_info->cset->
+ numchars(system_charset_info, parse_data->dbname.str,
+ parse_data->dbname.str +
+ parse_data->dbname.length) > EVEX_DB_FIELD_LEN)
{
- my_error(ER_TOO_LONG_IDENT, MYF(0), et->dbname.str);
+ my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->dbname.str);
goto err;
}
- if (system_charset_info->cset->numchars(system_charset_info, et->name.str,
- et->name.str + et->name.length)
- > EVEX_DB_FIELD_LEN)
+ if (system_charset_info->cset->
+ numchars(system_charset_info, parse_data->name.str,
+ parse_data->name.str +
+ parse_data->name.length) > EVEX_DB_FIELD_LEN)
{
- my_error(ER_TOO_LONG_IDENT, MYF(0), et->name.str);
+ my_error(ER_TOO_LONG_IDENT, MYF(0), parse_data->name.str);
goto err;
}
- if (et->body.length > table->field[ET_FIELD_BODY]->field_length)
+ if (parse_data->body.length > table->field[ET_FIELD_BODY]->field_length)
{
- my_error(ER_TOO_LONG_BODY, MYF(0), et->name.str);
+ my_error(ER_TOO_LONG_BODY, MYF(0), parse_data->name.str);
goto err;
}
- if (!(et->expression) && !(et->execute_at.year))
+ if (!(parse_data->expression) && !(parse_data->execute_at.year))
{
DBUG_PRINT("error", ("neither expression nor execute_at are set!"));
my_error(ER_EVENT_NEITHER_M_EXPR_NOR_M_AT, MYF(0));
@@ -669,12 +916,16 @@ Event_db_repository::create_event(THD *thd, Event_timed *et,
evex_fill_row() calls my_error() in case of error so no need to
handle it here
*/
- if ((ret= evex_fill_row(thd, table, et, false)))
+ if ((ret= evex_fill_row(thd, table, parse_data, false)))
goto err;
+ /* Close active transaction only if We are going to modify disk */
+ if (end_active_trans(thd))
+ goto err;
+
if (table->file->ha_write_row(table->record[0]))
{
- my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
+ my_error(ER_EVENT_STORE_FAILED, MYF(0), parse_data->name.str, ret);
goto err;
}
@@ -724,40 +975,44 @@ err:
*/
int
-Event_db_repository::update_event(THD *thd, Event_timed *et, sp_name *new_name)
+Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
+ sp_name *new_name)
{
CHARSET_INFO *scs= system_charset_info;
TABLE *table;
int ret= EVEX_OPEN_TABLE_FAILED;
DBUG_ENTER("Event_db_repository::update_event");
- DBUG_PRINT("enter", ("dbname: %.*s", et->dbname.length, et->dbname.str));
- DBUG_PRINT("enter", ("name: %.*s", et->name.length, et->name.str));
- DBUG_PRINT("enter", ("user: %.*s", et->definer.length, et->definer.str));
- if (new_name)
- DBUG_PRINT("enter", ("rename to: %.*s", new_name->m_name.length,
- new_name->m_name.str));
if (open_event_table(thd, TL_WRITE, &table))
{
my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0));
goto err;
}
-
+
+ if (evex_check_params(thd, parse_data))
+ goto err;
+
+ DBUG_PRINT("info", ("dbname: %s", parse_data->dbname.str));
+ DBUG_PRINT("info", ("name: %s", parse_data->name.str));
+ DBUG_PRINT("info", ("user: %s", parse_data->definer.str));
+ if (new_name)
+ DBUG_PRINT("info", ("rename to: %s", new_name->m_name.str));
+
/* first look whether we overwrite */
if (new_name)
{
- if (!sortcmp_lex_string(et->name, new_name->m_name, scs) &&
- !sortcmp_lex_string(et->dbname, new_name->m_db, scs))
+ if (!sortcmp_lex_string(parse_data->name, new_name->m_name, scs) &&
+ !sortcmp_lex_string(parse_data->dbname, new_name->m_db, scs))
{
- my_error(ER_EVENT_SAME_NAME, MYF(0), et->name.str);
- goto err;
+ my_error(ER_EVENT_SAME_NAME, MYF(0), parse_data->name.str);
+ goto err;
}
-
+
if (!evex_db_find_event_by_name(thd,new_name->m_db,new_name->m_name,table))
{
my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), new_name->m_name.str);
goto err;
- }
+ }
}
/*
...and then if there is such an event. Don't exchange the blocks
@@ -765,9 +1020,10 @@ Event_db_repository::update_event(THD *thd, Event_timed *et, sp_name *new_name)
overwrite the key and SE will tell us that it cannot find the already found
row (copied into record[1] later
*/
- if (EVEX_KEY_NOT_FOUND == find_event_by_name(thd, et->dbname, et->name, table))
+ if (EVEX_KEY_NOT_FOUND == find_event_by_name(thd, parse_data->dbname,
+ parse_data->name, table))
{
- my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->name.str);
+ my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), parse_data->name.str);
goto err;
}
@@ -780,20 +1036,24 @@ Event_db_repository::update_event(THD *thd, Event_timed *et, sp_name *new_name)
evex_fill_row() calls my_error() in case of error so no need to
handle it here
*/
- if ((ret= evex_fill_row(thd, table, et, true)))
+ if ((ret= evex_fill_row(thd, table, parse_data, true)))
goto err;
if (new_name)
- {
+ {
table->field[ET_FIELD_DB]->
store(new_name->m_db.str, new_name->m_db.length, scs);
table->field[ET_FIELD_NAME]->
store(new_name->m_name.str, new_name->m_name.length, scs);
}
+ /* Close active transaction only if We are going to modify disk */
+ if (end_active_trans(thd))
+ goto err;
+
if ((ret= table->file->ha_update_row(table->record[1], table->record[0])))
{
- my_error(ER_EVENT_STORE_FAILED, MYF(0), et->name.str, ret);
+ my_error(ER_EVENT_STORE_FAILED, MYF(0), parse_data->name.str, ret);
goto err;
}
@@ -845,6 +1105,10 @@ Event_db_repository::drop_event(THD *thd, LEX_STRING db, LEX_STRING name,
if (!(ret= evex_db_find_event_by_name(thd, db, name, table)))
{
+ /* Close active transaction only if We are going to modify disk */
+ if ((ret= end_active_trans(thd)))
+ goto done;
+
if ((ret= table->file->ha_delete_row(table->record[0])))
my_error(ER_EVENT_CANNOT_DELETE, MYF(0));
}
@@ -998,7 +1262,7 @@ Event_db_repository::drop_events_by_field(THD *thd,
*/
int
-Event_db_repository::load_named_event(THD *thd, Event_timed *etn,
+Event_db_repository::load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name,
Event_timed **etn_new)
{
int ret= 0;
@@ -1007,14 +1271,11 @@ Event_db_repository::load_named_event(THD *thd, Event_timed *etn,
Open_tables_state backup;
DBUG_ENTER("Event_scheduler::load_and_compile_event");
- DBUG_PRINT("enter",("thd=%p name:%*s",thd, etn->name.length, etn->name.str));
+ DBUG_PRINT("enter",("thd=%p name:%*s",thd, name.length, name.str));
thd->reset_n_backup_open_tables_state(&backup);
/* No need to use my_error() here because db_find_event() has done it */
- {
- sp_name spn(etn->dbname, etn->name);
- ret= find_event(thd, &spn, &et_loaded, NULL, &repo_root);
- }
+ ret= find_event(thd, dbname, name, &et_loaded, NULL, &repo_root);
thd->restore_backup_open_tables_state(&backup);
/* In this case no memory was allocated so we don't need to clean */
if (ret)
diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h
index 1cbee96b68f..625d5bfb993 100644
--- a/sql/event_db_repository.h
+++ b/sql/event_db_repository.h
@@ -53,7 +53,8 @@ events_table_scan_all(THD *thd, TABLE *schema_table, TABLE *event_table);
int
fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */);
-
+class Event_timed;
+class Event_parse_data;
class Event_queue_element;
class Event_db_repository
@@ -69,11 +70,11 @@ public:
deinit_repository();
int
- create_event(THD *thd, Event_timed *et, my_bool create_if_not,
- uint *rows_affected);
+ create_event(THD *thd, Event_parse_data *parse_data, my_bool create_if_not,
+ uint *rows_affected);
int
- update_event(THD *thd, Event_timed *et, sp_name *new_name);
+ update_event(THD *thd, Event_parse_data *parse_data, sp_name *new_name);
int
drop_event(THD *thd, LEX_STRING db, LEX_STRING name, bool drop_if_exists,
@@ -86,11 +87,11 @@ public:
drop_user_events(THD *thd, LEX_STRING definer);
int
- find_event(THD *thd, sp_name *name, Event_timed **ett, TABLE *tbl,
- MEM_ROOT *root);
+ find_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_timed **ett,
+ TABLE *tbl, MEM_ROOT *root);
int
- load_named_event(THD *thd, Event_timed *etn, Event_timed **etn_new);
+ load_named_event(THD *thd, LEX_STRING dbname, LEX_STRING name, Event_timed **etn_new);
int
find_event_by_name(THD *thd, LEX_STRING db, LEX_STRING name, TABLE *table);
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index cb500de53b9..35c30e5fc5a 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -785,7 +785,7 @@ Event_scheduler::destroy()
*/
int
-Event_scheduler::create_event(THD *thd, Event_timed *et, bool check_existence)
+Event_scheduler::create_event(THD *thd, Event_parse_data *et, bool check_existence)
{
int res;
Event_timed *et_new;
@@ -799,14 +799,15 @@ Event_scheduler::create_event(THD *thd, Event_timed *et, bool check_existence)
UNLOCK_SCHEDULER_DATA();
DBUG_RETURN(OP_OK);
}
- if (check_existence && find_event(et, FALSE))
+ if (check_existence && find_event(et->dbname, et->name, FALSE))
{
res= OP_ALREADY_EXISTS;
goto end;
}
/* We need to load the event on scheduler_root */
- if (!(res= db_repository->load_named_event(thd, et, &et_new)))
+ if (!(res= db_repository->
+ load_named_event(thd, et->dbname, et->name, &et_new)))
{
queue_insert_safe(&queue, (byte *) et_new);
DBUG_PRINT("info", ("Sending COND_new_work"));
@@ -850,7 +851,7 @@ Event_scheduler::drop_event(THD *thd, sp_name *name)
DBUG_RETURN(OP_OK);
}
- if (!(et_old= find_event(name, TRUE)))
+ if (!(et_old= find_event(name->m_db, name->m_name, TRUE)))
DBUG_PRINT("info", ("No such event found, probably DISABLED"));
UNLOCK_SCHEDULER_DATA();
@@ -906,7 +907,7 @@ Event_scheduler::drop_event(THD *thd, sp_name *name)
*/
int
-Event_scheduler::update_event(THD *thd, Event_timed *et,
+Event_scheduler::update_event(THD *thd, Event_parse_data *et,
LEX_STRING *new_schema,
LEX_STRING *new_name)
{
@@ -931,7 +932,7 @@ Event_scheduler::update_event(THD *thd, Event_timed *et,
DBUG_RETURN(OP_OK);
}
- if (!(et_old= find_event(et, TRUE)))
+ if (!(et_old= find_event(et->dbname, et->name, TRUE)))
DBUG_PRINT("info", ("%s.%s not found cached, probably was DISABLED",
et->dbname.str, et->name.str));
@@ -948,7 +949,8 @@ Event_scheduler::update_event(THD *thd, Event_timed *et,
1. Error occured
2. If the replace is DISABLED, we don't load it into the queue.
*/
- if (!(res= db_repository->load_named_event(thd, et, &et_new)))
+ if (!(res= db_repository->
+ load_named_event(thd, et->dbname, et->name, &et_new)))
{
queue_insert_safe(&queue, (byte *) et_new);
DBUG_PRINT("info", ("Sending COND_new_work"));
@@ -1014,50 +1016,8 @@ Event_scheduler::update_event(THD *thd, Event_timed *et,
SYNOPSIS
Event_scheduler::find_event()
- etn 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(Event_timed *etn, 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]?", etn->dbname.str, etn->name.str,
- et->dbname.str, et->name.str));
- if (event_timed_identifier_equal(etn, et))
- {
- if (remove_from_q)
- queue_remove(&queue, i);
- DBUG_RETURN(et);
- }
- }
-
- DBUG_RETURN(NULL);
-}
-
-
-/*
- Searches for an event in the scheduler queue
-
- SYNOPSIS
- Event_scheduler::find_event()
+ db The schema of the event to find
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
@@ -1071,7 +1031,7 @@ Event_scheduler::find_event(Event_timed *etn, bool remove_from_q)
*/
Event_timed *
-Event_scheduler::find_event(sp_name *name, bool remove_from_q)
+Event_scheduler::find_event(LEX_STRING db, LEX_STRING name, bool remove_from_q)
{
uint i;
DBUG_ENTER("Event_scheduler::find_event");
@@ -1079,9 +1039,9 @@ Event_scheduler::find_event(sp_name *name, bool remove_from_q)
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,
+ DBUG_PRINT("info", ("[%s.%s]==[%s.%s]?", db.str, name.str,
et->dbname.str, et->name.str));
- if (event_timed_identifier_equal(name, et))
+ if (event_timed_identifier_equal(db, name, et))
{
if (remove_from_q)
queue_remove(&queue, i);
@@ -1624,7 +1584,7 @@ Event_scheduler::clean_queue(THD *thd)
SYNOPSIS
Event_scheduler::stop_all_running_events()
thd Thread
-
+
NOTE
LOCK_scheduler data must be acquired prior to call to this method
*/
@@ -1726,7 +1686,7 @@ Event_scheduler::stop()
/*
One situation to be here is if there was a start that forked a new
thread but the new thread did not acquire yet LOCK_scheduler_data.
- Hence, in this case return an error.
+ Hence, in this case return an error.
*/
DBUG_PRINT("info", ("manager not running but %d. doing nothing", state));
UNLOCK_SCHEDULER_DATA();
@@ -1841,7 +1801,7 @@ Event_scheduler::workers_count()
}
VOID(pthread_mutex_unlock(&LOCK_thread_count));
DBUG_PRINT("exit", ("%d", count));
- DBUG_RETURN(count);
+ DBUG_RETURN(count);
}
@@ -1851,7 +1811,7 @@ Event_scheduler::workers_count()
SYNOPSIS
Event_scheduler::check_n_suspend_if_needed()
thd Thread
-
+
RETURN VALUE
FALSE Not suspended, we haven't slept
TRUE We were suspended. LOCK_scheduler_data is unlocked.
@@ -1936,7 +1896,7 @@ Event_scheduler::check_n_wait_for_non_empty_queue(THD *thd)
if (!queue.elements)
thd->enter_cond(&cond_vars[COND_new_work], &LOCK_scheduler_data,
- "Empty queue, sleeping");
+ "Empty queue, sleeping");
/* Wait in a loop protecting against catching spurious signals */
while (!queue.elements && state == RUNNING)
@@ -2079,7 +2039,7 @@ Event_scheduler::get_state()
SYNOPSIS
Event_scheduler::initialized()
-
+
RETURN VALUE
FALSE Was not initialized so far
TRUE Was initialized
diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h
index bd099d10839..a274636b38b 100644
--- a/sql/event_scheduler.h
+++ b/sql/event_scheduler.h
@@ -57,11 +57,11 @@ public:
/* Methods for queue management follow */
int
- create_event(THD *thd, Event_timed *et, bool check_existence);
+ create_event(THD *thd, Event_parse_data *et, bool check_existence);
int
- update_event(THD *thd, Event_timed *et, LEX_STRING *new_schema,
- LEX_STRING *new_name);
+ update_event(THD *thd, Event_parse_data *et, LEX_STRING *new_schema,
+ LEX_STRING *new_name);
bool
drop_event(THD *thd, sp_name *name);
@@ -129,10 +129,7 @@ public:
private:
Event_timed *
- find_event(Event_timed *etn, bool remove_from_q);
-
- Event_timed *
- find_event(sp_name *name, bool remove_from_q);
+ find_event(LEX_STRING db, LEX_STRING name, bool remove_from_q);
uint
workers_count();
diff --git a/sql/events.cc b/sql/events.cc
index 5fe5f019c87..28c57d6b493 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -186,7 +186,7 @@ common_1_lev_code:
expr= tmp_expr - (tmp_expr/60)*60;
/* the code after the switch will finish */
}
- break;
+ break;
case INTERVAL_DAY_SECOND:
{
ulonglong tmp_expr= expr;
@@ -283,23 +283,19 @@ Events::open_event_table(THD *thd, enum thr_lock_type lock_type,
*/
int
-Events::create_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
- uint create_options, uint *rows_affected)
+Events::create_event(THD *thd, Event_parse_data *parse_data, uint create_options,
+ uint *rows_affected)
{
int ret;
-
DBUG_ENTER("Events::create_event");
- DBUG_PRINT("enter", ("name: %*s options:%d", et->name.length,
- et->name.str, create_options));
-
if (!(ret= db_repository->
- create_event(thd, et,
+ create_event(thd, parse_data,
create_options & HA_LEX_CREATE_IF_NOT_EXISTS,
rows_affected)))
{
Event_scheduler *scheduler= Event_scheduler::get_instance();
if (scheduler->initialized() &&
- (ret= scheduler->create_event(thd, et, true)))
+ (ret= scheduler->create_event(thd, parse_data, true)))
my_error(ER_EVENT_MODIFY_QUEUE_ERROR, MYF(0), ret);
}
/* No need to close the table, it will be closed in sql_parse::do_command */
@@ -315,7 +311,7 @@ Events::create_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
Events::update_event()
thd THD
et event's data
- new_name set in case of RENAME TO.
+ new_name set in case of RENAME TO.
RETURN VALUE
0 OK
@@ -328,25 +324,23 @@ Events::create_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
*/
int
-Events::update_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
- sp_name *new_name, uint *rows_affected)
+Events::update_event(THD *thd, Event_parse_data *parse_data, sp_name *new_name,
+ uint *rows_affected)
{
int ret;
-
DBUG_ENTER("Events::update_event");
- DBUG_PRINT("enter", ("name: %*s", et->name.length, et->name.str));
/*
db_update_event() opens & closes the table to prevent
crash later in the code when loading and compiling the new definition.
Also on error conditions my_error() is called so no need to handle here
*/
- if (!(ret= db_repository->update_event(thd, et, new_name)))
+ if (!(ret= db_repository->update_event(thd, parse_data, new_name)))
{
Event_scheduler *scheduler= Event_scheduler::get_instance();
if (scheduler->initialized() &&
- (ret= scheduler->update_event(thd, et,
- new_name? &new_name->m_db: NULL,
- new_name? &new_name->m_name: NULL)))
+ (ret= scheduler->update_event(thd, parse_data,
+ new_name? &new_name->m_db: NULL,
+ new_name? &new_name->m_name: NULL)))
my_error(ER_EVENT_MODIFY_QUEUE_ERROR, MYF(0), ret);
}
DBUG_RETURN(ret);
@@ -411,7 +405,7 @@ Events::show_create_event(THD *thd, sp_name *spn)
DBUG_PRINT("enter", ("name: %*s", spn->m_name.length, spn->m_name.str));
thd->reset_n_backup_open_tables_state(&backup);
- ret= db_repository->find_event(thd, spn, &et, NULL, thd->mem_root);
+ ret= db_repository->find_event(thd, spn->m_db, spn->m_name, &et, NULL, thd->mem_root);
thd->restore_backup_open_tables_state(&backup);
if (!ret)
diff --git a/sql/events.h b/sql/events.h
index 45a0db13980..1239cf58c7d 100644
--- a/sql/events.h
+++ b/sql/events.h
@@ -17,7 +17,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class sp_name;
-class Event_timed;
class Event_parse_data;
class Event_db_repository;
@@ -45,7 +44,6 @@ public:
Event_timed::drop() and Event_timed is fixed not do drop directly
or other scheme will be found.
*/
- friend class Event_timed;
static ulong opt_event_scheduler;
static TYPELIB opt_typelib;
@@ -66,12 +64,12 @@ public:
get_instance();
int
- create_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
- uint create_options, uint *rows_affected);
+ create_event(THD *thd, Event_parse_data *parse_data, uint create_options,
+ uint *rows_affected);
int
- update_event(THD *thd, Event_timed *et, Event_parse_data *parse_data,
- sp_name *new_name, uint *rows_affected);
+ update_event(THD *thd, Event_parse_data *parse_data, sp_name *new_name,
+ uint *rows_affected);
int
drop_event(THD *thd, sp_name *name, bool drop_if_exists, uint *rows_affected);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f6031a1f2fd..386dece8813 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -174,11 +174,11 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->sphead= NULL;
lex->spcont= NULL;
lex->proc_list.first= 0;
- lex->escape_used= lex->et_compile_phase= FALSE;
+ lex->escape_used= FALSE;
lex->reset_query_tables_list(FALSE);
lex->name= 0;
- lex->et= NULL;
+ lex->event_parse_data= NULL;
lex->nest_level=0 ;
lex->allow_sum_func= 0;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e2cf213cd17..0558d60bc28 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -27,7 +27,6 @@ class sp_instr;
class sp_pcontext;
class st_alter_tablespace;
class partition_info;
-class Event_timed;
class Event_parse_data;
#ifdef MYSQL_SERVER
@@ -1017,9 +1016,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 5ec4e7b3b68..80e5fff5a58 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3833,57 +3833,31 @@ end_with_restore_list:
case SQLCOM_ALTER_EVENT:
{
uint rows_affected= 1;
- DBUG_ASSERT(lex->et);
- do {
- if (! lex->et->dbname.str ||
- (lex->sql_command == SQLCOM_ALTER_EVENT && lex->spname &&
- !lex->spname->m_db.str))
- {
- my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
- res= true;
- break;
- }
-
- if (check_access(thd, EVENT_ACL, lex->et->dbname.str, 0, 0, 0,
- is_schema_db(lex->et->dbname.str)) ||
- (lex->sql_command == SQLCOM_ALTER_EVENT && lex->spname &&
- (check_access(thd, EVENT_ACL, lex->spname->m_db.str, 0, 0, 0,
- is_schema_db(lex->spname->m_db.str)))))
- break;
-
- if (end_active_trans(thd))
- {
- res= -1;
- break;
- }
-
- switch (lex->sql_command) {
- case SQLCOM_CREATE_EVENT:
- res= Events::get_instance()->
- create_event(thd, lex->et, lex->event_parse_data,
- (uint) lex->create_info.options, &rows_affected);
- break;
- case SQLCOM_ALTER_EVENT:
- res= Events::get_instance()->
- update_event(thd, lex->et, lex->event_parse_data,
- lex->spname, &rows_affected);
- break;
- default:;
- }
- DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d",
- res, rows_affected));
- if (!res)
- send_ok(thd, rows_affected);
+ DBUG_ASSERT(lex->event_parse_data);
+ switch (lex->sql_command) {
+ case SQLCOM_CREATE_EVENT:
+ res= Events::get_instance()->create_event(thd, lex->event_parse_data,
+ (uint) lex->create_info.options,
+ &rows_affected);
+ break;
+ case SQLCOM_ALTER_EVENT:
+ res= Events::get_instance()->update_event(thd, lex->event_parse_data,
+ lex->spname, &rows_affected);
+ break;
+ default:;
+ }
+ DBUG_PRINT("info", ("CREATE/ALTER/DROP returned error code=%d af_rows=%d",
+ res, rows_affected));
+ if (!res)
+ send_ok(thd, rows_affected);
- /* lex->unit.cleanup() is called outside, no need to call it here */
- } while (0);
if (!thd->spcont)
{
- lex->et->free_sphead_on_delete= true;
- lex->et->free_sp();
- lex->et->deinit_mutexes();
+ delete lex->sphead;
+ lex->sphead= NULL;
}
-
+
+ /* lex->unit.cleanup() is called outside, no need to call it here */
break;
}
case SQLCOM_DROP_EVENT:
@@ -3912,11 +3886,6 @@ end_with_restore_list:
else
{
uint rows_affected= 1;
- if (end_active_trans(thd))
- {
- res= -1;
- break;
- }
if (!(res= Events::get_instance()->drop_event(thd, lex->spname,
lex->drop_if_exists,
&rows_affected)))
@@ -6020,14 +5989,6 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
{
delete lex->sphead;
lex->sphead= NULL;
- if (lex->et)
- {
- lex->et->free_sphead_on_delete= true;
- /* alloced on thd->mem_root so no real memory free but dtor call */
- lex->et->free_sp();
- lex->et->deinit_mutexes();
- lex->et= NULL;
- }
}
else
{
@@ -6064,13 +6025,6 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
delete lex->sphead;
lex->sphead= NULL;
}
- if (lex->et)
- {
- lex->et->free_sphead_on_delete= true;
- lex->et->free_sp();
- lex->et->deinit_mutexes();
- lex->et= NULL;
- }
}
thd->proc_info="freeing items";
thd->end_statement();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index bda51faeeb8..453e3634ef4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1290,24 +1290,11 @@ event_tail:
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;
+ 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)))
+ if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
YYABORT;
+ Lex->event_parse_data->identifier= $3;
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
@@ -1316,15 +1303,6 @@ event_tail:
*/
$<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
@@ -1353,52 +1331,12 @@ 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)
- {
- switch (lex->et->init_interval(YYTHD , $2, $3)) {
- case EVEX_PARSE_ERROR:
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- break;
- case EVEX_BAD_PARAMS:
- my_error(ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG, MYF(0));
- case EVEX_MICROSECOND_UNSUP:
- my_error(ER_NOT_SUPPORTED_YET, MYF(0), "MICROSECOND");
- YYABORT;
- break;
- }
- }
}
ev_starts
ev_ends
| AT_SYM expr
{
Lex->event_parse_data->item_execute_at= $2;
- LEX *lex=Lex;
- if (!lex->et_compile_phase)
- {
- switch (lex->et->init_execute_at(YYTHD, $2)) {
- case EVEX_PARSE_ERROR:
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- break;
- case ER_WRONG_VALUE:
- {
- char buff[120];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- String *str2= $2->val_str(&str);
- my_error(ER_WRONG_VALUE, MYF(0), "AT",
- str2? str2->c_ptr_safe():"NULL");
- YYABORT;
- break;
- }
- case EVEX_BAD_PARAMS:
- my_error(ER_EVENT_EXEC_TIME_IN_THE_PAST, MYF(0));
- YYABORT;
- break;
- }
- }
}
;
@@ -1406,18 +1344,11 @@ 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;
$$= 1;
}
| DISABLE_SYM
{
Lex->event_parse_data->status= Event_parse_data::DISABLED;
- LEX *lex=Lex;
-
- if (!lex->et_compile_phase)
- lex->et->status= Event_timed::DISABLED;
$$= 1;
}
;
@@ -1425,32 +1356,10 @@ 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)
- {
-
- switch (lex->et->init_starts(YYTHD, $2)) {
- case EVEX_PARSE_ERROR:
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- break;
- case EVEX_BAD_PARAMS:
- {
- char buff[20];
- String str(buff,(uint32) sizeof(buff), system_charset_info);
- String *str2= $2->val_str(&str);
- my_error(ER_WRONG_VALUE, MYF(0), "STARTS",
- str2 ? str2->c_ptr_safe() : NULL);
- YYABORT;
- break;
- }
- }
- }
}
;
@@ -1458,20 +1367,6 @@ ev_ends: /* empty */
| ENDS_SYM expr
{
Lex->event_parse_data->item_ends= $2;
- LEX *lex= Lex;
- if (!lex->et_compile_phase)
- {
- switch (lex->et->init_ends(YYTHD, $2)) {
- case EVEX_PARSE_ERROR:
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- break;
- case EVEX_BAD_PARAMS:
- my_error(ER_EVENT_ENDS_BEFORE_STARTS, MYF(0));
- YYABORT;
- break;
- }
- }
}
;
@@ -1484,18 +1379,12 @@ ev_on_completion:
{
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;
$$= 1;
}
| 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;
$$= 1;
}
;
@@ -1504,20 +1393,12 @@ 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)
- {
- lex->comment= $2;
- lex->et->init_comment(YYTHD, &$2);
- }
- $$= 1;
}
;
ev_sql_stmt:
{
LEX *lex= Lex;
- sp_head *sp;
/*
This stops the following :
@@ -1557,8 +1438,6 @@ ev_sql_stmt:
Lex->event_parse_data->body_begin= lex->ptr;
- if (!lex->et_compile_phase)
- lex->et->body_begin= lex->ptr;
}
ev_sql_stmt_inner
{
@@ -1570,14 +1449,7 @@ ev_sql_stmt:
lex->sp_chistics.suid= SP_IS_SUID;//always the definer!
- 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);
- }
}
;
@@ -4753,25 +4625,12 @@ alter:
YYTHD->client_capabilities is set back to original value
*/
{
- LEX *lex=Lex;
- Event_timed *et;
-
- lex->spname= NULL;
+ Lex->spname= NULL;
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;
-
- if (!lex->et_compile_phase)
- {
- et->init_definer(YYTHD);
- et->init_name(YYTHD, $3);
- }
-
/*
We have to turn of CLIENT_MULTI_QUERIES while parsing a
stored procedure, otherwise yylex will chop it into pieces
@@ -4838,7 +4697,7 @@ opt_ev_rename_to: /* empty */ { $$= 0;}
{
LEX *lex=Lex;
lex->spname= $3; //use lex's spname to hold the new name
- //the original name is in the Event_timed object
+ //the original name is in the Event_parse_data object
$$= 1;
}
;