diff options
-rw-r--r-- | sql/event.cc | 301 | ||||
-rw-r--r-- | sql/event.h | 4 | ||||
-rw-r--r-- | sql/event_executor.cc | 47 | ||||
-rw-r--r-- | sql/event_priv.h | 7 | ||||
-rw-r--r-- | sql/event_timed.cc | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 1 | ||||
-rw-r--r-- | sql/set_var.cc | 3 | ||||
-rw-r--r-- | sql/set_var.h | 11 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 4 |
9 files changed, 257 insertions, 123 deletions
diff --git a/sql/event.cc b/sql/event.cc index 82dbc2ebd76..756ebbf8c9a 100644 --- a/sql/event.cc +++ b/sql/event.cc @@ -21,6 +21,8 @@ /* TODO list : + - The default value of created/modified should not be 0000-00-00 because of + STRICT mode restricions. - Remove m_ prefixes of member variables. - Use timestamps instead of datetime. @@ -150,6 +152,93 @@ event_timed_compare(event_timed **a, event_timed **b) } + +/* + Open mysql.event table for read + + SYNOPSIS + evex_open_event_table_for_read() + thd Thread context + lock_type How to lock the table + RETURN + 0 Error + # Pointer to TABLE object +*/ + +TABLE *evex_open_event_table(THD *thd, enum thr_lock_type lock_type) +{ + TABLE_LIST tables; + bool not_used; + DBUG_ENTER("open_proc_table"); + + /* + Speed up things if the table doesn't exists. *table_exists + is set when we create or read stored procedure or on flush privileges. + */ + if (!mysql_event_table_exists) + DBUG_RETURN(0); + + bzero((char*) &tables, sizeof(tables)); + tables.db= (char*) "mysql"; + tables.table_name= tables.alias= (char*) "event"; + tables.lock_type= lock_type; + + if (simple_open_n_lock_tables(thd, &tables)) + { + mysql_event_table_exists= 0; + DBUG_RETURN(0); + } + + DBUG_RETURN(tables.table); +} + + +/* + Find row in open mysql.event table representing event + + SYNOPSIS + evex_db_find_routine_aux() + thd Thread context + dbname Name of event's database + rname Name of the event inside the db + table TABLE object for open mysql.event table. + + RETURN VALUE + SP_OK - Routine found + SP_KEY_NOT_FOUND- No routine with given name +*/ + +static int +evex_db_find_routine_aux(THD *thd, const LEX_STRING dbname, + const LEX_STRING rname, TABLE *table) +{ + byte key[MAX_KEY_LENGTH]; // db, name, optional key length type + DBUG_ENTER("evex_db_find_routine_aux"); + DBUG_PRINT("enter", ("name: %.*s", rname.length, rname.str)); + + /* + Create key to find row. We have to use field->store() to be able to + handle VARCHAR and CHAR fields. + Assumption here is that the two first fields in the table are + 'db' and 'name' and the first key is the primary key over the + same fields. + */ + if (rname.length > table->field[1]->field_length) + DBUG_RETURN(SP_KEY_NOT_FOUND); + table->field[0]->store(dbname.str, dbname.length, &my_charset_bin); + table->field[1]->store(rname.str, rname.length, &my_charset_bin); + key_copy(key, table->record[0], table->key_info, table->key_info->key_length); + + if (table->file->index_read_idx(table->record[0], 0, + key, table->key_info->key_length, + HA_READ_KEY_EXACT)) + DBUG_RETURN(SP_KEY_NOT_FOUND); + + DBUG_RETURN(0); +} + + + /* Puts some data common to CREATE and ALTER EVENT into a row. @@ -164,13 +253,13 @@ event_timed_compare(event_timed **a, event_timed **b) */ static int -evex_fill_row(THD *thd, TABLE *table, event_timed *et) +evex_fill_row(THD *thd, TABLE *table, event_timed *et, my_bool is_update) { DBUG_ENTER("evex_fill_row"); int ret=0; if (table->s->fields != EVEX_FIELD_COUNT) - goto get_field_failed; + DBUG_RETURN(EVEX_GET_FIELD_FAILED); DBUG_PRINT("info", ("m_db.len=%d",et->m_db.length)); DBUG_PRINT("info", ("m_name.len=%d",et->m_name.length)); @@ -195,13 +284,13 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et) if (et->m_starts.year) { table->field[EVEX_FIELD_STARTS]->set_notnull();// set NULL flag to OFF - table->field[EVEX_FIELD_STARTS]->store_time(&et->m_starts,MYSQL_TIMESTAMP_DATETIME); + table->field[EVEX_FIELD_STARTS]->store_time(&et->m_starts,MYSQL_TIMESTAMP_DATETIME); } if (et->m_ends.year) { table->field[EVEX_FIELD_ENDS]->set_notnull(); - table->field[EVEX_FIELD_ENDS]->store_time(&et->m_ends, MYSQL_TIMESTAMP_DATETIME); + table->field[EVEX_FIELD_ENDS]->store_time(&et->m_ends, MYSQL_TIMESTAMP_DATETIME); } if (et->m_expr) @@ -220,13 +309,15 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et) { // fix_fields already called in init_execute_at table->field[EVEX_FIELD_EXECUTE_AT]->set_notnull(); - table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->m_execute_at, MYSQL_TIMESTAMP_DATETIME); + table->field[EVEX_FIELD_EXECUTE_AT]->store_time(&et->m_execute_at, + MYSQL_TIMESTAMP_DATETIME); //this will make it NULL because we don't call set_notnull table->field[EVEX_FIELD_TRANSIENT_INTERVAL]->store((longlong) 0); } 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 } @@ -238,8 +329,6 @@ evex_fill_row(THD *thd, TABLE *table, event_timed *et) store((et->m_comment).str, (et->m_comment).length, system_charset_info); DBUG_RETURN(0); -get_field_failed: - DBUG_RETURN(EVEX_GET_FIELD_FAILED); } @@ -259,34 +348,38 @@ get_field_failed: static int db_create_event(THD *thd, event_timed *et) { - int ret; + int ret= EVEX_OK; TABLE *table; - TABLE_LIST tables; char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2]; char olddb[128]; - bool dbchanged; + bool dbchanged= false; DBUG_ENTER("db_create_event"); DBUG_PRINT("enter", ("name: %.*s", et->m_name.length, et->m_name.str)); - dbchanged= false; - if ((ret= sp_use_new_db(thd, et->m_db.str, olddb, sizeof(olddb), - 0, &dbchanged))) + + DBUG_PRINT("info", ("open mysql.event for update")); + if (!(table= evex_open_event_table(thd, TL_WRITE))) { - DBUG_PRINT("info", ("cannot use_new_db. code=%d", ret)); - DBUG_RETURN(EVEX_NO_DB_ERROR); + my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0)); + goto done; } - bzero(&tables, sizeof(tables)); - tables.db= (char*)"mysql"; - tables.table_name= tables.alias= (char*)"event"; - - if (!(table= EVEX_OPEN_TABLE_FOR_UPDATE())) + DBUG_PRINT("info", ("check existance of an event with the same name")); + if (!evex_db_find_routine_aux(thd, et->m_db, et->m_name, table)) { - if (dbchanged) - (void)mysql_change_db(thd, olddb, 1); - DBUG_RETURN(SP_OPEN_TABLE_FAILED); + my_error(ER_EVENT_ALREADY_EXISTS, MYF(0), et->m_name.str); + goto done; } + DBUG_PRINT("info", ("non-existant, go forward")); + if ((ret= sp_use_new_db(thd, et->m_db.str, olddb, sizeof(olddb), + 0, &dbchanged))) + { + DBUG_PRINT("info", ("cannot use_new_db. code=%d", ret)); + my_error(ER_BAD_DB_ERROR, MYF(0)); + DBUG_RETURN(0); + } + restore_record(table, s->default_values); // Get default values for fields strxmov(definer, et->m_definer_user.str, "@", et->m_definer_host.str, NullS); @@ -305,25 +398,25 @@ db_create_event(THD *thd, event_timed *et) */ if (!(et->m_expr) && !(et->m_execute_at.year)) { - DBUG_PRINT("error", ("neither m_expr nor m_execute_as is set!")); - ret= EVEX_WRITE_ROW_FAILED; + DBUG_PRINT("error", ("neither m_expr nor m_execute_as are set!")); + my_error(ER_EVENT_NEITHER_M_EXPR_NOR_M_AT, MYF(0)); goto done; } - ret= table->field[EVEX_FIELD_DEFINER]-> - store(definer, (uint)strlen(definer), system_charset_info); - if (ret) + + if (table->field[EVEX_FIELD_DEFINER]-> + store(definer, (uint)strlen(definer), system_charset_info)) { - ret= EVEX_PARSE_ERROR; + my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str); goto done; } - + ((Field_timestamp *)table->field[EVEX_FIELD_CREATED])->set_time(); - if ((ret= evex_fill_row(thd, table, et))) + if ((ret= evex_fill_row(thd, table, et, false))) goto done; ret= EVEX_OK; if (table->file->write_row(table->record[0])) - ret= EVEX_WRITE_ROW_FAILED; + my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str); else if (mysql_bin_log.is_open()) { thd->clear_error(); @@ -333,9 +426,10 @@ db_create_event(THD *thd, event_timed *et) } done: - close_thread_tables(thd); + // No need to close the table, it will be closed in sql_parse::do_command + if (dbchanged) - (void)mysql_change_db(thd, olddb, 1); + (void) mysql_change_db(thd, olddb, 1); DBUG_RETURN(ret); } @@ -365,34 +459,43 @@ db_update_event(THD *thd, sp_name *name, event_timed *et) DBUG_PRINT("enter", ("rename to: %.*s", name->m_name.length, name->m_name.str)); // Todo: Handle in sql_prepare.cc SP_OPEN_TABLE_FAILED - if (!(table= EVEX_OPEN_TABLE_FOR_UPDATE())) - DBUG_RETURN(SP_OPEN_TABLE_FAILED); + if (!(table= evex_open_event_table(thd, TL_WRITE))) + { + my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0)); + goto done; + } - ret= sp_db_find_routine_aux(thd, 0/*notype*/, et->m_db, et->m_name, table); - if (ret == EVEX_OK) + if (evex_db_find_routine_aux(thd, et->m_db, et->m_name, table) == SP_KEY_NOT_FOUND) { - store_record(table,record[1]); - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; // Don't update create on row update. - ret= evex_fill_row(thd, table, et); - if (ret) - goto done; - - if (name) - { - table->field[EVEX_FIELD_DB]-> - store(name->m_db.str, name->m_db.length, system_charset_info); - table->field[EVEX_FIELD_NAME]-> - store(name->m_name.str, name->m_name.length, system_charset_info); - } + my_error(ER_EVENT_DOES_NOT_EXIST, MYF(0), et->m_name.str); + goto done; + } + + store_record(table,record[1]); + + table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; // Don't update create on row update. + if ((ret= evex_fill_row(thd, table, et, true))) + goto done; + + if (name) + { + table->field[EVEX_FIELD_DB]-> + store(name->m_db.str, name->m_db.length, system_charset_info); + table->field[EVEX_FIELD_NAME]-> + store(name->m_name.str, name->m_name.length, system_charset_info); + } - if ((table->file->update_row(table->record[1],table->record[0]))) - ret= EVEX_WRITE_ROW_FAILED; + if ((ret= table->file->update_row(table->record[1],table->record[0]))) + { + my_error(ER_EVENT_STORE_FAILED, MYF(0), et->m_name.str); + goto done; } done: close_thread_tables(thd); DBUG_RETURN(ret); } + /* Use sp_name for look up, return in **ett if found */ @@ -404,18 +507,18 @@ db_find_event(THD *thd, sp_name *name, event_timed **ett) const char *definer; char *ptr; event_timed *et; - Open_tables_state open_tables_state_backup; DBUG_ENTER("db_find_event"); DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); - if (!(table= open_proc_type_table_for_read(thd, &open_tables_state_backup, - "event", &mysql_event_table_exists))) - DBUG_RETURN(SP_OPEN_TABLE_FAILED); + if (!(table= evex_open_event_table(thd, TL_READ))) + { + my_error(ER_EVENT_OPEN_TABLE_FAILED, MYF(0)); + goto done; + } - if ((ret= sp_db_find_routine_aux(thd, 0/*notype*/, name->m_db, name->m_name, - table)) != SP_OK) + if ((ret= evex_db_find_routine_aux(thd, name->m_db, name->m_name, table))) goto done; et= new event_timed; @@ -434,7 +537,6 @@ done: et= 0; } close_thread_tables(thd); - thd->restore_backup_open_tables_state(&open_tables_state_backup); *ett= et; DBUG_RETURN(ret); } @@ -503,8 +605,6 @@ done: if (thd->mem_root != tmp_mem_root) thd->mem_root= tmp_mem_root; - if (spn) - delete spn; DBUG_RETURN(ret); } @@ -619,19 +719,19 @@ int evex_create_event(THD *thd, event_timed *et, uint create_options) { int ret = 0; - sp_name *spn= 0; DBUG_ENTER("evex_create_event"); DBUG_PRINT("enter", ("name: %*s options:%d", et->m_name.length, et->m_name.str, create_options)); +/* VOID(pthread_mutex_lock(&LOCK_evex_running)); if (!evex_is_running) // TODO: put an warning to the user here. // Is it needed? (Andrey, 051129) {} VOID(pthread_mutex_unlock(&LOCK_evex_running)); - +*/ if ((ret = db_create_event(thd, et)) == EVEX_WRITE_ROW_FAILED && (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) @@ -652,24 +752,16 @@ evex_create_event(THD *thd, event_timed *et, uint create_options) goto done; VOID(pthread_mutex_lock(&LOCK_evex_running)); - if (!evex_is_running) + if (evex_is_running && et->m_status == MYSQL_EVENT_ENABLED) { - VOID(pthread_mutex_unlock(&LOCK_evex_running)); - goto done; - } - VOID(pthread_mutex_unlock(&LOCK_evex_running)); - - //cache only if the event is ENABLED - if (et->m_status == MYSQL_EVENT_ENABLED) - { - spn= new sp_name(et->m_db, et->m_name); - if ((ret= evex_load_and_compile_event(thd, spn, true))) - goto done; + sp_name spn(et->m_db, et->m_name); + ret= evex_load_and_compile_event(thd, &spn, true); } + VOID(pthread_mutex_unlock(&LOCK_evex_running)); done: - if (spn) - delete spn; + // No need to close the table, it will be closed in sql_parse::do_command + DBUG_RETURN(ret); } @@ -685,7 +777,7 @@ done: NOTES et contains data about dbname and event name. - name is the new name of the event. if not null this means + name is the new name of the event, if not null this means that RENAME TO was specified in the query. TODO - Add code for in-memory structures - caching & uncaching. @@ -701,19 +793,24 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et) DBUG_ENTER("evex_update_event"); DBUG_PRINT("enter", ("name: %*s", et->m_name.length, et->m_name.str)); +/* VOID(pthread_mutex_lock(&LOCK_evex_running)); if (!evex_is_running) // put an warning to the user here {} VOID(pthread_mutex_unlock(&LOCK_evex_running)); - +*/ + if ((ret= db_update_event(thd, name, et))) goto done_no_evex; VOID(pthread_mutex_lock(&LOCK_evex_running)); if (!evex_is_running) - // not running - therefore no memory structures + { + // not running - therefore no memory structures + VOID(pthread_mutex_unlock(&LOCK_evex_running)); goto done_no_evex; + } VOID(pthread_mutex_unlock(&LOCK_evex_running)); /* @@ -721,31 +818,23 @@ evex_update_event(THD *thd, sp_name *name, event_timed *et) The reason is that DISABLED events are not cached. */ VOID(pthread_mutex_lock(&LOCK_event_arrays)); - if (name) - { - evex_remove_from_cache(&name->m_db, &name->m_name, false); - if (et->m_status == MYSQL_EVENT_ENABLED && - (ret= evex_load_and_compile_event(thd, name, false)) - ) - goto done; - } - else - { - evex_remove_from_cache(&et->m_db, &et->m_name, false); - spn= new sp_name(et->m_db, et->m_name); - if (et->m_status == MYSQL_EVENT_ENABLED && - (ret= evex_load_and_compile_event(thd, spn, false)) - ) + evex_remove_from_cache(&et->m_db, &et->m_name, false); + if (et->m_status == MYSQL_EVENT_ENABLED) + if (name) + ret= evex_load_and_compile_event(thd, name, false); + else { + spn= new sp_name(et->m_db, et->m_name); + ret= evex_load_and_compile_event(thd, spn, false); delete spn; - goto done; - } - } + } done: VOID(pthread_mutex_unlock(&LOCK_event_arrays)); done_no_evex: + // No need to close the table, it will be closed in sql_parse::do_command + DBUG_RETURN(ret); } @@ -771,13 +860,15 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists) bool opened; DBUG_ENTER("evex_drop_event"); +/* VOID(pthread_mutex_lock(&LOCK_evex_running)); if (!evex_is_running) // put an warning to the user here {} VOID(pthread_mutex_unlock(&LOCK_evex_running)); - - if (!(table= EVEX_OPEN_TABLE_FOR_UPDATE())) +*/ +//// + if (!(table= evex_open_event_table(thd, TL_WRITE))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); ret= sp_db_find_routine_aux(thd, 0/*notype*/, et->m_db, et->m_name, table); @@ -806,14 +897,8 @@ evex_drop_event(THD *thd, event_timed *et, bool drop_if_exists) VOID(pthread_mutex_unlock(&LOCK_evex_running)); done: - /* - "opened" is switched to TRUE when we open mysql.event for checking. - In this case we have to close the table after finishing working with it. - */ - close_thread_tables(thd); + // No need to close the table, it will be closed in sql_parse::do_command DBUG_RETURN(ret); } - - diff --git a/sql/event.h b/sql/event.h index cab5d9bf257..6c7edbcf3fc 100644 --- a/sql/event.h +++ b/sql/event.h @@ -214,8 +214,8 @@ CREATE TABLE `event` ( `execute_at` datetime default NULL, `transient_expression` int(11) default NULL, `interval_type` enum('YEAR','QUARTER','MONTH','DAY','HOUR','MINUTE','WEEK','SECOND','MICROSECOND','YEAR_MONTH','DAY_HOUR','DAY_MINUTE','DAY_SECOND','HOUR_MINUTE','HOUR_SECOND','MINUTE_SECOND','DAY_MICROSECOND','HOUR_MICROSECOND','MINUTE_MICROSECOND','SECOND_MICROSECOND') default NULL, - `created` timestamp NOT NULL default '0000-00-00 00:00:00', - `modified` timestamp NOT NULL default '0000-00-00 00:00:00', + `created` timestamp NOT NULL, + `modified` timestamp NOT NULL, `last_executed` datetime default NULL, `starts` datetime default NULL, `ends` datetime default NULL, diff --git a/sql/event_executor.cc b/sql/event_executor.cc index b3029d66f07..58504a7e559 100644 --- a/sql/event_executor.cc +++ b/sql/event_executor.cc @@ -36,6 +36,7 @@ my_bool event_executor_running_global_var= false; extern ulong thread_created; +static my_bool evex_mutexes_initted= false; static int evex_load_events_from_db(THD *thd); @@ -50,6 +51,19 @@ evex_load_events_from_db(THD *thd); pthread_handler_t event_executor_worker(void *arg); pthread_handler_t event_executor_main(void *arg); +static +void evex_init_mutexes() +{ + if (evex_mutexes_initted) + { + evex_mutexes_initted= true; + return; + } + pthread_mutex_init(&LOCK_event_arrays, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&LOCK_workers_count, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&LOCK_evex_running, MY_MUTEX_INIT_FAST); +} + int init_events() { @@ -59,15 +73,15 @@ init_events() DBUG_PRINT("info",("Starting events main thread")); - pthread_mutex_init(&LOCK_event_arrays, MY_MUTEX_INIT_FAST); - pthread_mutex_init(&LOCK_workers_count, MY_MUTEX_INIT_FAST); - pthread_mutex_init(&LOCK_evex_running, MY_MUTEX_INIT_FAST); - + evex_init_mutexes(); + VOID(pthread_mutex_lock(&LOCK_evex_running)); evex_is_running= false; event_executor_running_global_var= false; VOID(pthread_mutex_unlock(&LOCK_evex_running)); + DBUG_RETURN(0); +/* #ifndef DBUG_FAULTY_THR //TODO Andrey: Change the error code returned! if (pthread_create(&th, NULL, event_executor_main, (void*)NULL)) @@ -77,6 +91,7 @@ init_events() #endif DBUG_RETURN(0); +*/ } @@ -94,6 +109,7 @@ shutdown_events() DBUG_VOID_RETURN; } +#ifdef ANDREY_0 static int init_event_thread(THD* thd) @@ -165,7 +181,7 @@ pthread_handler_t event_executor_main(void *arg) goto err; // make this thread invisible it has no vio -> show processlist won't see - thd->system_thread= 0; + thd->system_thread= 1; VOID(pthread_mutex_lock(&LOCK_thread_count)); threads.append(thd); @@ -350,7 +366,7 @@ err_no_thd: free_root(&evex_mem_root, MYF(0)); sql_print_information("Event executor stopped"); - shutdown_events(); +// shutdown_events(); my_thread_end(); pthread_exit(0); @@ -391,7 +407,7 @@ pthread_handler_t event_executor_worker(void *event_void) thd->init_for_queries(); // make this thread visible it has no vio -> show processlist needs this flag - thd->system_thread= 0; + thd->system_thread= 1; VOID(pthread_mutex_lock(&LOCK_thread_count)); threads.append(thd); @@ -531,3 +547,20 @@ end: ("Events loaded from DB. Status code %d", ret)); DBUG_RETURN(ret); } + +#endif + +bool sys_var_event_executor::update(THD *thd, set_var *var) +{ +#ifdef ANDREY_0 + // here start the thread if not running. + VOID(pthread_mutex_lock(&LOCK_evex_running)); + if ((my_bool) var->save_result.ulong_value && !evex_is_running) { + VOID(pthread_mutex_unlock(&LOCK_evex_running)); + init_events(); + } else + VOID(pthread_mutex_unlock(&LOCK_evex_running)); +#endif + return sys_var_bool_ptr::update(thd, var); +} + diff --git a/sql/event_priv.h b/sql/event_priv.h index 61fd4517bd5..75d39c3c81e 100644 --- a/sql/event_priv.h +++ b/sql/event_priv.h @@ -17,9 +17,6 @@ #ifndef _EVENT_PRIV_H_ #define _EVENT_PRIV_H_ -#define EVEX_OPEN_TABLE_FOR_UPDATE() \ - open_proc_type_table_for_update(thd, "event", &mysql_event_table_exists) - enum { @@ -53,5 +50,7 @@ extern pthread_mutex_t LOCK_event_arrays, int my_time_compare(TIME *a, TIME *b); - + + +TABLE *evex_open_event_table(THD *thd, enum thr_lock_type lock_type); #endif /* _EVENT_PRIV_H_ */ diff --git a/sql/event_timed.cc b/sql/event_timed.cc index 579568cee7d..b8b4876252a 100644 --- a/sql/event_timed.cc +++ b/sql/event_timed.cc @@ -719,7 +719,7 @@ event_timed::update_fields(THD *thd) if (!(m_status_changed || m_last_executed_changed)) goto done; - if (!(table= EVEX_OPEN_TABLE_FOR_UPDATE())) + if (!(table= evex_open_event_table(thd, TL_WRITE))) DBUG_RETURN(SP_OPEN_TABLE_FAILED); if ((ret= sp_db_find_routine_aux(thd, 0/*notype*/, m_db, m_name, table))) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8688b72c48f..4377e1a23d4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3568,6 +3568,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); clean_up(1); wait_for_signal_thread_to_end(); clean_up_mutexes(); + shutdown_events(); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(0); diff --git a/sql/set_var.cc b/sql/set_var.cc index 727ec1f8d98..4414ab61d15 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -207,7 +207,7 @@ sys_var_long_ptr sys_delayed_insert_timeout("delayed_insert_timeout", &delayed_insert_timeout); sys_var_long_ptr sys_delayed_queue_size("delayed_queue_size", &delayed_queue_size); -sys_var_bool_ptr sys_event_executor("event_scheduler", +sys_var_event_executor sys_event_executor("event_scheduler", &event_executor_running_global_var); sys_var_long_ptr sys_expire_logs_days("expire_logs_days", &expire_logs_days); @@ -3364,6 +3364,7 @@ bool sys_var_trust_routine_creators::update(THD *thd, set_var *var) return sys_var_bool_ptr::update(thd, var); } + /**************************************************************************** Used templates ****************************************************************************/ diff --git a/sql/set_var.h b/sql/set_var.h index 14059f7e9b7..7d2a7999ddc 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -782,6 +782,17 @@ public: bool update(THD *thd, set_var *var); }; + +class sys_var_event_executor :public sys_var_bool_ptr +{ + /* We need a derived class only to have a warn_deprecated() */ +public: + sys_var_event_executor(const char *name_arg, my_bool *value_arg) : + sys_var_bool_ptr(name_arg, value_arg) {}; + bool update(THD *thd, set_var *var); +}; + + /**************************************************************************** Classes for parsing of the SET command ****************************************************************************/ diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 0c9990b58ed..5804125ed68 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5737,3 +5737,7 @@ ER_EVENT_ENDS_BEFORE_STARTS eng "ENDS must be after STARTS" ER_EVENT_EXEC_TIME_IN_THE_PAST eng "Activation (AT) time is in the past" +ER_EVENT_OPEN_TABLE_FAILED + eng "Failed to open mysql.event" +ER_EVENT_NEITHER_M_EXPR_NOR_M_AT + eng "No datetime expression provided" |