summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorandrey@lmy004. <>2006-07-13 10:59:58 +0200
committerandrey@lmy004. <>2006-07-13 10:59:58 +0200
commitdd31d457898e129a9f22363741101780e028038f (patch)
treefb7407480fd7ae1b764e1bf59ec33047559bf6dd /sql
parent3f4e1f5c695215cd18222c359fa56eea4ab63664 (diff)
downloadmariadb-git-dd31d457898e129a9f22363741101780e028038f.tar.gz
WL #3337 (Events new architecture)
Final stroke, events should be loaded from disk on server startup. Also check the validity of their bodies if possible during loading.
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc55
-rw-r--r--sql/event_data_objects.h9
-rw-r--r--sql/event_queue.cc144
-rw-r--r--sql/event_queue.h31
-rw-r--r--sql/event_scheduler.cc114
-rw-r--r--sql/event_scheduler.h9
-rw-r--r--sql/events.cc11
-rw-r--r--sql/events.h2
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_class.cc18
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_yacc.yy7
14 files changed, 248 insertions, 161 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 8f67754a5b2..a367e058f0e 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -731,7 +731,7 @@ Event_timed::~Event_timed()
*/
Event_job_data::Event_job_data():
- thd(NULL), sphead(0), sql_mode(0)
+ thd(NULL), sphead(NULL), sql_mode(0)
{
}
@@ -745,7 +745,10 @@ Event_job_data::Event_job_data():
Event_job_data::~Event_job_data()
{
- free_sp();
+ DBUG_ENTER("Event_job_data::~Event_job_data");
+ delete sphead;
+ sphead= NULL;
+ DBUG_VOID_RETURN;
}
@@ -1606,20 +1609,6 @@ Event_job_data::get_fake_create_event(THD *thd, String *buf)
/*
- Frees the memory of the sp_head object we hold
- SYNOPSIS
- Event_job_data::free_sp()
-*/
-
-void
-Event_job_data::free_sp()
-{
- delete sphead;
- sphead= NULL;
-}
-
-
-/*
Compiles an event before it's execution. Compiles the anonymous
sp_head object held by the event
@@ -1651,9 +1640,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
CHARSET_INFO *old_character_set_client,
*old_collation_connection,
*old_character_set_results;
- Security_context *save_ctx;
- /* this one is local and not needed after exec */
- Security_context security_ctx;
+ Security_context save_ctx;
DBUG_ENTER("Event_job_data::compile");
@@ -1699,10 +1686,9 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
thd->query_length= show_create.length();
DBUG_PRINT("info", ("query:%s",thd->query));
- thd->change_security_context(definer_user, definer_host, dbname,
- &security_ctx, &save_ctx);
+ thd->change_security_context(definer_user, definer_host, dbname, &save_ctx);
thd->lex= &lex;
- lex_start(thd, (uchar*)thd->query, thd->query_length);
+ mysql_init_query(thd, (uchar*) thd->query, thd->query_length);
if (MYSQLparse((void *)thd) || thd->is_fatal_error)
{
DBUG_PRINT("error", ("error during compile or thd->is_fatal_error=%d",
@@ -1713,13 +1699,10 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
*/
sql_print_error("error during compile of %s.%s or thd->is_fatal_error=%d",
dbname.str, name.str, thd->is_fatal_error);
- if (lex.sphead)
- {
- if (&lex != thd->lex)
- thd->lex->sphead->restore_lex(thd);
- delete lex.sphead;
- lex.sphead= 0;
- }
+
+ lex.unit.cleanup();
+ delete lex.sphead;
+ sphead= lex.sphead= NULL;
ret= EVEX_COMPILE_ERROR;
goto done;
}
@@ -1734,7 +1717,7 @@ Event_job_data::compile(THD *thd, MEM_ROOT *mem_root)
done:
lex_end(&lex);
- thd->restore_security_context(save_ctx);
+ thd->restore_security_context(&save_ctx);
DBUG_PRINT("note", ("return old data on its place. set back NAMES"));
thd->lex= old_lex;
@@ -1772,20 +1755,17 @@ done:
int
Event_job_data::execute(THD *thd)
{
- Security_context *save_ctx;
+ Security_context save_ctx;
/* this one is local and not needed after exec */
- Security_context security_ctx;
int ret= 0;
DBUG_ENTER("Event_job_data::execute");
DBUG_PRINT("info", ("EXECUTING %s.%s", dbname.str, name.str));
-
if ((ret= compile(thd, NULL)))
goto done;
- thd->change_security_context(definer_user, definer_host, dbname,
- &security_ctx, &save_ctx);
+ thd->change_security_context(definer_user, definer_host, dbname, &save_ctx);
/*
THD::~THD will clean this or if there is DROP DATABASE in the SP then
it will be free there. It should not point to our buffer which is allocated
@@ -1810,9 +1790,10 @@ Event_job_data::execute(THD *thd)
ret= -99;
}
- thd->restore_security_context(save_ctx);
+ thd->restore_security_context(&save_ctx);
done:
- free_sp();
+ thd->end_statement();
+ thd->cleanup_after_query();
DBUG_PRINT("info", ("EXECUTED %s.%s ret=%d", dbname.str, name.str, ret));
diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h
index e20d698161e..cf1bd5e390a 100644
--- a/sql/event_data_objects.h
+++ b/sql/event_data_objects.h
@@ -178,15 +178,12 @@ public:
int
execute(THD *thd);
-private:
- int
- get_fake_create_event(THD *thd, String *buf);
int
compile(THD *thd, MEM_ROOT *mem_root);
-
- void
- free_sp();
+private:
+ int
+ get_fake_create_event(THD *thd, String *buf);
Event_job_data(const Event_job_data &); /* Prevent use of these */
void operator=(Event_job_data &);
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 12eceee8cfb..69114c53118 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -35,6 +35,14 @@
#define LOCK_QUEUE_DATA() lock_data(SCHED_FUNC, __LINE__)
#define UNLOCK_QUEUE_DATA() unlock_data(SCHED_FUNC, __LINE__)
+struct event_queue_param
+{
+ THD *thd;
+ Event_queue *queue;
+ pthread_mutex_t LOCK_loaded;
+ pthread_cond_t COND_loaded;
+};
+
/*
Compares the execute_at members of two Event_queue_element instances.
@@ -64,6 +72,31 @@ event_queue_element_compare_q(void *vptr, byte* a, byte *b)
}
+pthread_handler_t
+event_queue_loader_thread(void *arg)
+{
+ /* needs to be first for thread_stack */
+ THD *thd= (THD *)((struct event_queue_param *) arg)->thd;
+ struct event_queue_param *param= (struct event_queue_param *) arg;
+ thd->thread_stack= (char *) &thd;
+
+ if (post_init_event_thread(thd))
+ goto end;
+
+ DBUG_ENTER("event_queue_loader_thread");
+
+ pthread_mutex_lock(&param->LOCK_loaded);
+ param->queue->load_events_from_db(thd);
+ pthread_cond_signal(&param->COND_loaded);
+ pthread_mutex_unlock(&param->LOCK_loaded);
+
+end:
+ deinit_event_thread(thd);
+
+ DBUG_RETURN(0); // Against gcc warnings
+}
+
+
/*
Constructor of class Event_queue.
@@ -80,6 +113,8 @@ Event_queue::Event_queue()
mutex_last_attempted_lock_in_func= "";
mutex_queue_data_locked= mutex_queue_data_attempting_lock= FALSE;
+
+ queue_loaded= FALSE;
}
@@ -125,8 +160,11 @@ Event_queue::deinit_mutexes()
bool
Event_queue::init_queue(Event_db_repository *db_repo, Event_scheduler *sched)
{
- int i= 0;
- bool ret= FALSE;
+ THD *new_thd;
+ pthread_t th;
+ bool res;
+ struct event_queue_param *event_queue_param_value= NULL;
+
DBUG_ENTER("Event_queue::init_queue");
DBUG_PRINT("enter", ("this=0x%lx", this));
@@ -139,8 +177,7 @@ Event_queue::init_queue(Event_db_repository *db_repo, Event_scheduler *sched)
NULL, EVENT_QUEUE_EXTENT))
{
sql_print_error("SCHEDULER: Can't initialize the execution queue");
- ret= TRUE;
- goto end;
+ goto err;
}
if (sizeof(my_time_t) != sizeof(time_t))
@@ -148,13 +185,43 @@ Event_queue::init_queue(Event_db_repository *db_repo, Event_scheduler *sched)
sql_print_error("SCHEDULER: sizeof(my_time_t) != sizeof(time_t) ."
"The scheduler may not work correctly. Stopping.");
DBUG_ASSERT(0);
- ret= TRUE;
- goto end;
+ goto err;
}
-end:
+ if (!(new_thd= new THD))
+ goto err;
+
+ pre_init_event_thread(new_thd);
+
+ event_queue_param_value= (struct event_queue_param *)
+ my_malloc(sizeof(struct event_queue_param), MYF(0));
+ event_queue_param_value->thd= new_thd;
+ event_queue_param_value->queue= this;
+ pthread_mutex_init(&event_queue_param_value->LOCK_loaded, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&event_queue_param_value->COND_loaded, NULL);
+
+ pthread_mutex_lock(&event_queue_param_value->LOCK_loaded);
+ DBUG_PRINT("info", ("Forking new thread for scheduduler. THD=0x%lx", new_thd));
+ if (!(res= pthread_create(&th, &connection_attrib, event_queue_loader_thread,
+ (void*)event_queue_param_value)))
+ {
+ do {
+ pthread_cond_wait(&event_queue_param_value->COND_loaded,
+ &event_queue_param_value->LOCK_loaded);
+ } while (queue_loaded == FALSE);
+ }
+
+ pthread_mutex_unlock(&event_queue_param_value->LOCK_loaded);
+ pthread_mutex_destroy(&event_queue_param_value->LOCK_loaded);
+ pthread_cond_destroy(&event_queue_param_value->COND_loaded);
+ my_free((char *)event_queue_param_value, MYF(0));
+
UNLOCK_QUEUE_DATA();
- DBUG_RETURN(ret);
+ DBUG_RETURN(res);
+
+err:
+ UNLOCK_QUEUE_DATA();
+ DBUG_RETURN(TRUE);
}
@@ -498,7 +565,7 @@ Event_queue::load_events_from_db(THD *thd)
READ_RECORD read_record_info;
int ret= -1;
uint count= 0;
- bool clean_the_queue= FALSE;
+ bool clean_the_queue= TRUE;
/* Compile the events on this root but only for syntax check, then discard */
MEM_ROOT boot_root;
@@ -518,14 +585,12 @@ Event_queue::load_events_from_db(THD *thd)
if (!(et= new Event_queue_element))
{
DBUG_PRINT("info", ("Out of memory"));
- clean_the_queue= TRUE;
break;
}
DBUG_PRINT("info", ("Loading event from row."));
if ((ret= et->load_from_row(table)))
{
- clean_the_queue= TRUE;
sql_print_error("SCHEDULER: Error while loading from mysql.event. "
"Table probably corrupted");
break;
@@ -536,27 +601,6 @@ Event_queue::load_events_from_db(THD *thd)
delete et;
continue;
}
-#if 0
- init_alloc_root(&boot_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
- DBUG_PRINT("info", ("Event %s loaded from row. ", et->name.str));
-
- /* We load only on scheduler root just to check whether the body compiles */
- switch (ret= et->compile(thd, &boot_root)) {
- case EVEX_MICROSECOND_UNSUP:
- et->free_sp();
- sql_print_error("SCHEDULER: mysql.event is tampered. MICROSECOND is not "
- "supported but found in mysql.event");
- goto end;
- case EVEX_COMPILE_ERROR:
- sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load.",
- et->dbname.str, et->name.str);
- goto end;
- default:
- /* Free it, it will be compiled again on the worker thread */
- et->free_sp();
- break;
- }
- free_root(&boot_root, MYF(0));
/* let's find when to be executed */
if (et->compute_next_execution_time())
@@ -565,11 +609,40 @@ Event_queue::load_events_from_db(THD *thd)
" Skipping", et->dbname.str, et->name.str);
continue;
}
-#endif
+
+ {
+ Event_job_data temp_job_data;
+ DBUG_PRINT("info", ("Event %s loaded from row. ", et->name.str));
+
+ temp_job_data.load_from_row(table);
+
+ /* We load only on scheduler root just to check whether the body compiles */
+ switch (ret= temp_job_data.compile(thd, thd->mem_root)) {
+ case EVEX_MICROSECOND_UNSUP:
+ sql_print_error("SCHEDULER: mysql.event is tampered. MICROSECOND is not "
+ "supported but found in mysql.event");
+ break;
+ case EVEX_COMPILE_ERROR:
+ sql_print_error("SCHEDULER: Error while compiling %s.%s. Aborting load.",
+ et->dbname.str, et->name.str);
+ break;
+ default:
+ break;
+ }
+ thd->end_statement();
+ thd->cleanup_after_query();
+ }
+ if (ret)
+ {
+ delete et;
+ goto end;
+ }
+
DBUG_PRINT("load_events_from_db", ("Adding 0x%lx to the exec list."));
queue_insert_safe(&queue, (byte *) et);
count++;
}
+ clean_the_queue= FALSE;
end:
end_read_record(&read_record_info);
@@ -585,10 +658,12 @@ end:
}
/* Force close to free memory */
- thd->version--;
+ thd->version--;
close_thread_tables(thd);
+ queue_loaded= TRUE;
+
DBUG_PRINT("info", ("Status code %d. Loaded %d event(s)", ret, count));
DBUG_RETURN(ret);
}
@@ -713,6 +788,7 @@ Event_queue::empty_queue()
uint i;
DBUG_ENTER("Event_queue::empty_queue");
DBUG_PRINT("enter", ("Purging the queue. %d element(s)", queue.elements));
+ sql_print_information("SCHEDULER: Purging queue. %u events", queue.elements);
/* empty the queue */
for (i= 0; i < queue.elements; ++i)
{
diff --git a/sql/event_queue.h b/sql/event_queue.h
index b7962d14a89..3270938e881 100644
--- a/sql/event_queue.h
+++ b/sql/event_queue.h
@@ -68,12 +68,13 @@ public:
bool
dump_internal_status(THD *thd);
+ int
+ load_events_from_db(THD *thd);
+
protected:
Event_queue_element *
find_n_remove_event(LEX_STRING db, LEX_STRING name);
- int
- load_events_from_db(THD *thd);
void
drop_matching_events(THD *thd, LEX_STRING pattern,
@@ -82,11 +83,24 @@ protected:
void
empty_queue();
+ void
+ notify_observers();
+
+ void
+ dbug_dump_queue(time_t now);
+
/* LOCK_event_queue is the mutex which protects the access to the queue. */
pthread_mutex_t LOCK_event_queue;
Event_db_repository *db_repository;
+ Event_scheduler *scheduler;
+
+ /* The sorted queue with the Event_job_data objects */
+ QUEUE queue;
+
+ bool queue_loaded;
+
uint mutex_last_locked_at_line;
uint mutex_last_unlocked_at_line;
uint mutex_last_attempted_lock_at_line;
@@ -95,24 +109,13 @@ protected:
const char* mutex_last_attempted_lock_in_func;
bool mutex_queue_data_locked;
bool mutex_queue_data_attempting_lock;
-
+
/* helper functions for working with mutexes & conditionals */
void
lock_data(const char *func, uint line);
void
unlock_data(const char *func, uint line);
-
- void
- notify_observers();
-
- void
- dbug_dump_queue(time_t now);
-
- Event_scheduler *scheduler;
-
- /* The sorted queue with the Event_job_data objects */
- QUEUE queue;
};
#endif /* _EVENT_QUEUE_H_ */
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 85d357ec11e..5e6ffb090cb 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -40,9 +40,6 @@ struct scheduler_param
Event_scheduler *scheduler;
};
-struct scheduler_param scheduler_param_value;
-
-
static
LEX_STRING scheduler_states_names[] =
@@ -103,25 +100,23 @@ evex_print_warnings(THD *thd, Event_job_data *et)
/*
- Inits an scheduler thread handler, both the main and a worker
+ Performs pre- pthread_create() initialisation of THD. Do this
+ in the thread that will pass THD to the child thread. In the
+ child thread call post_init_event_thread().
SYNOPSIS
- init_event_thread()
- thd - the THD of the thread. Has to be allocated by the caller.
+ pre_init_event_thread()
+ thd The THD of the thread. Has to be allocated by the caller.
NOTES
1. The host of the thead is my_localhost
2. thd->net is initted with NULL - no communication.
-
- RETURN VALUE
- 0 OK
- -1 Error
*/
-static int
-init_scheduler_thread(THD* thd)
+void
+pre_init_event_thread(THD* thd)
{
- DBUG_ENTER("init_event_thread");
+ DBUG_ENTER("pre_init_event_thread");
thd->client_capabilities= 0;
thd->security_ctx->master_access= 0;
thd->security_ctx->db_access= 0;
@@ -148,7 +143,36 @@ init_scheduler_thread(THD* thd)
thd->version= refresh_version;
thd->set_time();
- DBUG_RETURN(0);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Performs post initialization of structures in a new thread.
+
+ SYNOPSIS
+ post_init_event_thread()
+ thd Thread
+*/
+
+bool
+post_init_event_thread(THD *thd)
+{
+ my_thread_init();
+ pthread_detach_this_thread();
+ thd->real_id= pthread_self();
+ if (init_thr_lock() || thd->store_globals())
+ {
+ thd->cleanup();
+ return TRUE;
+ }
+
+#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
+ sigset_t set;
+ VOID(sigemptyset(&set)); // Get mask in use
+ VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
+#endif
+ return FALSE;
}
@@ -160,7 +184,7 @@ init_scheduler_thread(THD* thd)
thd Thread
*/
-static void
+void
deinit_event_thread(THD *thd)
{
thd->proc_info= "Clearing";
@@ -192,29 +216,18 @@ pthread_handler_t
event_scheduler_thread(void *arg)
{
/* needs to be first for thread_stack */
- THD *thd= (THD *)(*(struct scheduler_param *) arg).thd;
+ THD *thd= (THD *)((struct scheduler_param *) arg)->thd;
+ Event_scheduler *scheduler= ((struct scheduler_param *) arg)->scheduler;
- thd->thread_stack= (char *)&thd; // remember where our stack is
- DBUG_ENTER("event_scheduler_thread");
+ my_free((char*)arg, MYF(0));
- my_thread_init();
- pthread_detach_this_thread();
- thd->real_id=pthread_self();
- if (init_thr_lock() || thd->store_globals())
- {
- thd->cleanup();
- goto end;
- }
+ thd->thread_stack= (char *)&thd; // remember where our stack is
-#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
- sigset_t set;
- VOID(sigemptyset(&set)); // Get mask in use
- VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
-#endif
+ DBUG_ENTER("event_scheduler_thread");
- ((struct scheduler_param *) arg)->scheduler->run(thd);
+ if (!post_init_event_thread(thd))
+ scheduler->run(thd);
-end:
deinit_event_thread(thd);
DBUG_RETURN(0); // Against gcc warnings
@@ -242,27 +255,13 @@ event_worker_thread(void *arg)
int ret;
thd= event->thd;
- thd->thread_stack= (char *) &thd;
+ thd->thread_stack= (char *) &thd; // remember where our stack is
+ DBUG_ENTER("event_worker_thread");
- my_thread_init();
- pthread_detach_this_thread();
- thd->real_id=pthread_self();
- if (init_thr_lock() || thd->store_globals())
- {
- thd->cleanup();
+ if (post_init_event_thread(thd))
goto end;
- }
-
-#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
- sigset_t set;
- VOID(sigemptyset(&set)); // Get mask in use
- VOID(pthread_sigmask(SIG_UNBLOCK, &set, &thd->block_signals));
-#endif
- thd->init_for_queries();
-
- DBUG_ENTER("event_worker_thread");
DBUG_PRINT("info", ("Baikonur, time is %d, BURAN reporting and operational."
"THD=0x%lx", time(NULL), thd));
@@ -375,6 +374,7 @@ Event_scheduler::start()
THD *new_thd= NULL;
bool ret= FALSE;
pthread_t th;
+ struct scheduler_param *scheduler_param_value;
DBUG_ENTER("Event_scheduler::start");
LOCK_SCHEDULER_DATA();
@@ -382,21 +382,24 @@ Event_scheduler::start()
if (state > INITIALIZED)
goto end;
- if (!(new_thd= new THD) || init_scheduler_thread(new_thd))
+ if (!(new_thd= new THD))
{
sql_print_error("SCHEDULER: Cannot init manager event thread.");
ret= TRUE;
goto end;
}
+ pre_init_event_thread(new_thd);
new_thd->system_thread= SYSTEM_THREAD_EVENT_SCHEDULER;
new_thd->command= COM_DAEMON;
- scheduler_param_value.thd= new_thd;
- scheduler_param_value.scheduler= this;
+ scheduler_param_value=
+ (struct scheduler_param *)my_malloc(sizeof(struct scheduler_param), MYF(0));
+ scheduler_param_value->thd= new_thd;
+ scheduler_param_value->scheduler= this;
DBUG_PRINT("info", ("Forking new thread for scheduduler. THD=0x%lx", new_thd));
if (pthread_create(&th, &connection_attrib, event_scheduler_thread,
- (void*)&scheduler_param_value))
+ (void*)scheduler_param_value))
{
DBUG_PRINT("error", ("cannot create a new thread"));
state= INITIALIZED;
@@ -588,9 +591,10 @@ Event_scheduler::execute_top(THD *thd, Event_job_data *job_data)
pthread_t th;
int res= 0;
DBUG_ENTER("Event_scheduler::execute_top");
- if (!(new_thd= new THD) || init_scheduler_thread(new_thd))
+ if (!(new_thd= new THD))
goto error;
+ pre_init_event_thread(new_thd);
new_thd->system_thread= SYSTEM_THREAD_EVENT_WORKER;
job_data->thd= new_thd;
DBUG_PRINT("info", ("BURAN %s@%s ready for start t-3..2..1..0..ignition",
diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h
index bf3e8e63e11..8e00b7b767f 100644
--- a/sql/event_scheduler.h
+++ b/sql/event_scheduler.h
@@ -19,6 +19,15 @@
class Event_queue;
class Event_job_data;
+void
+pre_init_event_thread(THD* thd);
+
+bool
+post_init_event_thread(THD* thd);
+
+void
+deinit_event_thread(THD *thd);
+
class Event_scheduler
{
public:
diff --git a/sql/events.cc b/sql/events.cc
index 2a4ccbaf5ef..94ef8faa83d 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -556,11 +556,16 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */)
1 Error in case the scheduler can't start
*/
-int
+bool
Events::init()
{
+ int res;
DBUG_ENTER("Events::init");
- event_queue->init_queue(db_repository, scheduler);
+ if (event_queue->init_queue(db_repository, scheduler))
+ {
+ sql_print_information("SCHEDULER: Error while loading from disk.");
+ DBUG_RETURN(TRUE);
+ }
scheduler->init_scheduler(event_queue);
/* it should be an assignment! */
@@ -571,7 +576,7 @@ Events::init()
DBUG_RETURN(scheduler->start());
}
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
diff --git a/sql/events.h b/sql/events.h
index 5f46c7bb7c5..f14aed0fbd1 100644
--- a/sql/events.h
+++ b/sql/events.h
@@ -52,7 +52,7 @@ public:
static ulong opt_event_scheduler;
static TYPELIB opt_typelib;
- int
+ bool
init();
void
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8fc6155087e..1cc52a204eb 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3675,7 +3675,8 @@ we force server id to 2, but this MySQL server will not act as a slave.");
if (!opt_noacl)
{
- Events::get_instance()->init();
+ if (Events::get_instance()->init())
+ unireg_abort(1);
}
#if defined(__NT__) || defined(HAVE_SMEM)
handle_connections_methods();
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 81f5d502ec9..d8995da7c16 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -640,10 +640,12 @@ sp_head::create(THD *thd)
sp_head::~sp_head()
{
+ DBUG_ENTER("sp_head::~sp_head");
destroy();
delete m_next_cached_sp;
if (m_thd)
restore_thd_mem_root(m_thd);
+ DBUG_VOID_RETURN;
}
void
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 47381c6aecb..6ce5a8fa01d 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2085,21 +2085,20 @@ bool Security_context::set_user(char *user_arg)
bool
THD::change_security_context(LEX_STRING user, LEX_STRING host,
- LEX_STRING db, Security_context *s_ctx,
- Security_context **backup)
+ LEX_STRING db, 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))
+
+ *backup= main_security_ctx;
+ if (acl_getroot_no_password(&main_security_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= security_ctx;
- security_ctx= s_ctx;
+ security_ctx= &main_security_ctx;
#endif
DBUG_RETURN(FALSE);
}
@@ -2119,7 +2118,10 @@ THD::restore_security_context(Security_context *backup)
DBUG_ENTER("restore_security_context");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (backup)
- security_ctx= backup;
+ {
+ main_security_ctx= *backup;
+ security_ctx= &main_security_ctx;
+ }
#endif
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 18cc53daf6d..1283f55cea6 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -871,8 +871,7 @@ public:
bool
change_security_context(LEX_STRING user, LEX_STRING host,
- LEX_STRING db, Security_context *s_ctx,
- Security_context **backup);
+ LEX_STRING db, Security_context *backup);
void
restore_security_context(Security_context *backup);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 386dece8813..1be70ea61d6 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -171,6 +171,7 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->sql_command= SQLCOM_END;
lex->duplicates= DUP_ERROR;
lex->ignore= 0;
+ lex->spname= NULL;
lex->sphead= NULL;
lex->spcont= NULL;
lex->proc_list.first= 0;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 0dd87fbfac6..a29c5f3ee16 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4652,6 +4652,13 @@ alter:
YYTHD->client_capabilities is set back to original value
*/
{
+ /*
+ It is safe to use Lex->spname because
+ ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
+ is not allowed. Lex->spname is used in the case of RENAME TO
+ If it had to be supported spname had to be added to
+ Event_parse_data.
+ */
Lex->spname= NULL;
if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))