summaryrefslogtreecommitdiff
path: root/sql/event_data_objects.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/event_data_objects.cc')
-rw-r--r--sql/event_data_objects.cc551
1 files changed, 166 insertions, 385 deletions
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);
}