Commit 9b323387 authored by unknown's avatar unknown

WL #1034 update

- fix one bug found by PeterG, namely bug #51

#there is a major problem currently after removing the specialised DYNAMIC_ARRAY as 
  storage for the events. I have to reintroduce similar storage, this time probably some
  linked list or maybe some API on top of DYNAMIC_ARRAY.


sql/event.cc:
  close the table
sql/event.h:
  change definition
sql/event_executor.cc:
  don't start the thread in advance
sql/event_timed.cc:
  - don't call evex_drop_event
  - quote the name during compilation to make create event `the rain in spain goes into the drain` not fail.
parent a820fa4f
...@@ -877,7 +877,6 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists) ...@@ -877,7 +877,6 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
{ {
TABLE *table; TABLE *table;
int ret= EVEX_OPEN_TABLE_FAILED; int ret= EVEX_OPEN_TABLE_FAILED;
bool opened;
DBUG_ENTER("evex_drop_event"); DBUG_ENTER("evex_drop_event");
if (evex_open_event_table(thd, TL_WRITE, &table)) if (evex_open_event_table(thd, TL_WRITE, &table))
...@@ -914,9 +913,10 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists) ...@@ -914,9 +913,10 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists)
done: done:
/* /*
No need to close the table, it will be closed in sql_parse::do_command() evex_drop_event() is used by event_timed::drop therefore
and evex_remove_from_cache does not try to open a table we have to close our thread tables.
*/ */
close_thread_tables(thd);
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
......
...@@ -102,13 +102,13 @@ public: ...@@ -102,13 +102,13 @@ public:
free_sphead_on_delete(true), flags(0) free_sphead_on_delete(true), flags(0)
{ {
pthread_mutex_init(&LOCK_running, MY_MUTEX_INIT_FAST); pthread_mutex_init(&this->LOCK_running, MY_MUTEX_INIT_FAST);
init(); init();
} }
~event_timed() ~event_timed()
{ {
pthread_mutex_destroy(&LOCK_running); pthread_mutex_destroy(&this->LOCK_running);
if (free_sphead_on_delete) if (free_sphead_on_delete)
free_sp(); free_sp();
} }
...@@ -149,7 +149,7 @@ public: ...@@ -149,7 +149,7 @@ public:
void void
mark_last_executed(); mark_last_executed();
bool int
drop(THD *thd); drop(THD *thd);
bool bool
......
...@@ -91,6 +91,8 @@ init_events() ...@@ -91,6 +91,8 @@ init_events()
evex_is_running= false; evex_is_running= false;
VOID(pthread_mutex_unlock(&LOCK_evex_running)); VOID(pthread_mutex_unlock(&LOCK_evex_running));
if (event_executor_running_global_var)
{
#ifndef DBUG_FAULTY_THR #ifndef DBUG_FAULTY_THR
//TODO Andrey: Change the error code returned! //TODO Andrey: Change the error code returned!
if (pthread_create(&th, NULL, event_executor_main, (void*)NULL)) if (pthread_create(&th, NULL, event_executor_main, (void*)NULL))
...@@ -98,6 +100,7 @@ init_events() ...@@ -98,6 +100,7 @@ init_events()
#else #else
event_executor_main(NULL); event_executor_main(NULL);
#endif #endif
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -249,6 +252,17 @@ event_executor_main(void *arg) ...@@ -249,6 +252,17 @@ event_executor_main(void *arg)
continue; continue;
} }
et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*); et= evex_queue_first_element(&EVEX_EQ_NAME, event_timed*);
if (et->status == MYSQL_EVENT_DISABLED)
{
DBUG_PRINT("evex_load_events_from_db",("Now it is disabled-exec no more"));
if (et->dropped)
et->drop(thd);
delete et;
evex_queue_delete_element(&EVEX_EQ_NAME, 1);// 1 is top
VOID(pthread_mutex_unlock(&LOCK_event_arrays));
sql_print_information("Event found disabled, dropping.");
continue;
}
time(&now); time(&now);
my_tz_UTC->gmt_sec_to_TIME(&time_now, now); my_tz_UTC->gmt_sec_to_TIME(&time_now, now);
...@@ -256,8 +270,6 @@ event_executor_main(void *arg) ...@@ -256,8 +270,6 @@ event_executor_main(void *arg)
VOID(pthread_mutex_unlock(&LOCK_event_arrays)); VOID(pthread_mutex_unlock(&LOCK_event_arrays));
if (t2sleep > 0) if (t2sleep > 0)
{ {
// sql_print_information("Sleeping for %d seconds.", t2sleep);
// printf("\nWHEN=%llu NOW=%llu\n", TIME_to_ulonglong_datetime(&et->execute_at), TIME_to_ulonglong_datetime(&time_now));
/* /*
We sleep t2sleep seconds but we check every second whether this thread We sleep t2sleep seconds but we check every second whether this thread
has been killed, or there is new candidate has been killed, or there is new candidate
...@@ -266,11 +278,9 @@ event_executor_main(void *arg) ...@@ -266,11 +278,9 @@ event_executor_main(void *arg)
evex_queue_num_elements(EVEX_EQ_NAME) && evex_queue_num_elements(EVEX_EQ_NAME) &&
(evex_queue_first_element(&EVEX_EQ_NAME, event_timed*) == et)) (evex_queue_first_element(&EVEX_EQ_NAME, event_timed*) == et))
my_sleep(1000000); my_sleep(1000000);
// sql_print_information("Finished sleeping");
} }
if (!event_executor_running_global_var) if (!event_executor_running_global_var)
continue; continue;
} }
...@@ -316,7 +326,7 @@ event_executor_main(void *arg) ...@@ -316,7 +326,7 @@ event_executor_main(void *arg)
printf("[%10s] next at [%llu]\n\n\n", et->name.str,TIME_to_ulonglong_datetime(&et->execute_at)); printf("[%10s] next at [%llu]\n\n\n", et->name.str,TIME_to_ulonglong_datetime(&et->execute_at));
et->update_fields(thd); et->update_fields(thd);
if ((et->execute_at.year && !et->expression) || if ((et->execute_at.year && !et->expression) ||
TIME_to_ulonglong_datetime(&et->execute_at) == 0L) TIME_to_ulonglong_datetime(&et->execute_at) == 0)
et->flags |= EVENT_EXEC_NO_MORE; et->flags |= EVENT_EXEC_NO_MORE;
} }
if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED) if ((et->flags & EVENT_EXEC_NO_MORE) || et->status == MYSQL_EVENT_DISABLED)
...@@ -551,6 +561,7 @@ evex_load_events_from_db(THD *thd) ...@@ -551,6 +561,7 @@ evex_load_events_from_db(THD *thd)
et->dbname.str, et->name.str); et->dbname.str, et->name.str);
goto end; goto end;
} }
// let's find when to be executed // let's find when to be executed
et->compute_next_execution_time(); et->compute_next_execution_time();
......
...@@ -714,10 +714,34 @@ event_timed::mark_last_executed() ...@@ -714,10 +714,34 @@ event_timed::mark_last_executed()
} }
bool /*
Returns :
0 - OK
-1 - Cannot open mysql.event
-2 - Cannot find the event in mysql.event (already deleted?)
others - return code from SE in case deletion of the event row
failed.
*/
int
event_timed::drop(THD *thd) event_timed::drop(THD *thd)
{ {
return (bool) evex_drop_event(thd, this, false); TABLE *table;
int ret= 0;
DBUG_ENTER("event_timed::drop");
if (evex_open_event_table(thd, TL_WRITE, &table))
DBUG_RETURN(-1);
if (evex_db_find_event_aux(thd, dbname, name, table))
DBUG_RETURN(-2);
if ((ret= table->file->delete_row(table->record[0])))
DBUG_RETURN(ret);
close_thread_tables(thd);
DBUG_RETURN(0);
} }
...@@ -783,11 +807,11 @@ event_timed::get_show_create_event(THD *thd, uint *length) ...@@ -783,11 +807,11 @@ event_timed::get_show_create_event(THD *thd, uint *length)
char *dst, *ret; char *dst, *ret;
uint len, tmp_len; uint len, tmp_len;
len = strlen("CREATE EVENT ") + dbname.length + strlen(".") + name.length + len = strlen("CREATE EVENT `") + dbname.length + strlen(".") + name.length +
strlen(" ON SCHEDULE EVERY 5 MINUTE DO ") + body.length + strlen(";"); strlen("` ON SCHEDULE EVERY 5 MINUTE DO ") + body.length + strlen(";");
ret= dst= (char*) alloc_root(thd->mem_root, len + 1); ret= dst= (char*) alloc_root(thd->mem_root, len + 1);
memcpy(dst, "CREATE EVENT ", tmp_len= strlen("CREATE EVENT ")); memcpy(dst, "CREATE EVENT `", tmp_len= strlen("CREATE EVENT `"));
dst+= tmp_len; dst+= tmp_len;
memcpy(dst, dbname.str, tmp_len=dbname.length); memcpy(dst, dbname.str, tmp_len=dbname.length);
dst+= tmp_len; dst+= tmp_len;
...@@ -795,8 +819,8 @@ event_timed::get_show_create_event(THD *thd, uint *length) ...@@ -795,8 +819,8 @@ event_timed::get_show_create_event(THD *thd, uint *length)
dst+= tmp_len; dst+= tmp_len;
memcpy(dst, name.str, tmp_len= name.length); memcpy(dst, name.str, tmp_len= name.length);
dst+= tmp_len; dst+= tmp_len;
memcpy(dst, " ON SCHEDULE EVERY 5 MINUTE DO ", memcpy(dst, "` ON SCHEDULE EVERY 5 MINUTE DO ",
tmp_len= strlen(" ON SCHEDULE EVERY 5 MINUTE DO ")); tmp_len= strlen("` ON SCHEDULE EVERY 5 MINUTE DO "));
dst+= tmp_len; dst+= tmp_len;
memcpy(dst, body.str, tmp_len= body.length); memcpy(dst, body.str, tmp_len= body.length);
...@@ -834,14 +858,14 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root) ...@@ -834,14 +858,14 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
DBUG_ENTER("event_timed::execute"); DBUG_ENTER("event_timed::execute");
VOID(pthread_mutex_lock(&LOCK_running)); VOID(pthread_mutex_lock(&this->LOCK_running));
if (running) if (running)
{ {
VOID(pthread_mutex_unlock(&LOCK_running)); VOID(pthread_mutex_unlock(&this->LOCK_running));
DBUG_RETURN(-100); DBUG_RETURN(-100);
} }
running= true; running= true;
VOID(pthread_mutex_unlock(&LOCK_running)); VOID(pthread_mutex_unlock(&this->LOCK_running));
// TODO Andrey : make this as member variable and delete in destructor // TODO Andrey : make this as member variable and delete in destructor
empty_item_list.empty(); empty_item_list.empty();
...@@ -851,9 +875,9 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root) ...@@ -851,9 +875,9 @@ event_timed::execute(THD *thd, MEM_ROOT *mem_root)
ret= sphead->execute_procedure(thd, &empty_item_list); ret= sphead->execute_procedure(thd, &empty_item_list);
VOID(pthread_mutex_lock(&LOCK_running)); VOID(pthread_mutex_lock(&this->LOCK_running));
running= false; running= false;
VOID(pthread_mutex_unlock(&LOCK_running)); VOID(pthread_mutex_unlock(&this->LOCK_running));
done: done:
// Don't cache sphead if allocated on another mem_root // Don't cache sphead if allocated on another mem_root
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment