diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/events.cc | 51 | ||||
-rw-r--r-- | sql/events.h | 13 | ||||
-rw-r--r-- | sql/mysqld.cc | 35 | ||||
-rw-r--r-- | sql/set_var.cc | 42 | ||||
-rw-r--r-- | sql/set_var.h | 6 |
5 files changed, 103 insertions, 44 deletions
diff --git a/sql/events.cc b/sql/events.cc index f4b9b05179d..931ba17341f 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -59,17 +59,39 @@ eligible for execution. */ -const char *event_scheduler_state_names[]= - { "OFF", "0", "ON", "1", "SUSPEND", "2", NullS }; +/* + Keep the order of the first to as in var_typelib + sys_var_event_scheduler::value_ptr() references this array. Keep in + mind! +*/ +static const char *opt_event_scheduler_state_names[]= + { "OFF", "ON", "0", "1", "DISABLED", NullS }; TYPELIB Events::opt_typelib= { - array_elements(event_scheduler_state_names)-1, + array_elements(opt_event_scheduler_state_names)-1, "", - event_scheduler_state_names, + opt_event_scheduler_state_names, NULL }; + +/* + The order should not be changed. We consider OFF to be equivalent of INT 0 + And ON of 1. If OFF & ON are interchanged the logic in + sys_var_event_scheduler::update() will be broken! +*/ +static const char *var_event_scheduler_state_names[]= { "OFF", "ON", NullS }; + +TYPELIB Events::var_typelib= +{ + array_elements(var_event_scheduler_state_names)-1, + "", + var_event_scheduler_state_names, + NULL +}; + + static Event_queue events_event_queue; @@ -81,7 +103,8 @@ Event_db_repository events_event_db_repository; Events Events::singleton; -ulong Events::opt_event_scheduler= 2; +enum Events::enum_opt_event_scheduler Events::opt_event_scheduler= + Events::EVENTS_OFF; /* @@ -607,6 +630,9 @@ Events::init() bool res= FALSE; DBUG_ENTER("Events::init"); + if (opt_event_scheduler == Events::EVENTS_DISABLED) + DBUG_RETURN(FALSE); + /* We need a temporary THD during boot */ if (!(thd= new THD())) { @@ -637,12 +663,10 @@ Events::init() } scheduler->init_scheduler(event_queue); - if (opt_event_scheduler) - { - DBUG_ASSERT(opt_event_scheduler == 1 || opt_event_scheduler == 2); - if (opt_event_scheduler == 1) - res= scheduler->start(); - } + DBUG_ASSERT(opt_event_scheduler == Events::EVENTS_ON || + opt_event_scheduler == Events::EVENTS_OFF); + if (opt_event_scheduler == Events::EVENTS_ON) + res= scheduler->start(); end: delete thd; @@ -667,10 +691,11 @@ void Events::deinit() { DBUG_ENTER("Events::deinit"); - - if (likely(!check_system_tables_error)) + if (likely(!check_system_tables_error) && + scheduler->get_state() > Event_scheduler::UNINITIALIZED) { scheduler->stop(); + DBUG_ASSERT(scheduler->get_state() == Event_scheduler::INITIALIZED); scheduler->deinit_scheduler(); event_queue->deinit_queue(); diff --git a/sql/events.h b/sql/events.h index 737044ad298..9a820b8521e 100644 --- a/sql/events.h +++ b/sql/events.h @@ -48,9 +48,18 @@ public: or other scheme will be found. */ friend class Event_queue_element; - - static ulong opt_event_scheduler; + + /* The order should match the order in opt_typelib */ + enum enum_opt_event_scheduler + { + EVENTS_OFF= 0, + EVENTS_ON= 1, + EVENTS_DISABLED= 5, + }; + + static enum_opt_event_scheduler opt_event_scheduler; static TYPELIB opt_typelib; + static TYPELIB var_typelib; bool init(); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 58697202461..b8626623b59 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5072,9 +5072,9 @@ Disable with --skip-bdb (will save memory).", (gptr*) &global_system_variables.engine_condition_pushdown, (gptr*) &global_system_variables.engine_condition_pushdown, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + /* See how it's handled in get_one_option() */ {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.", - (gptr*) &Events::opt_event_scheduler, (gptr*) &Events::opt_event_scheduler, 0, GET_ULONG, - REQUIRED_ARG, 2/*default*/, 0/*min-value*/, 2/*max-value*/, 0, 0, 0}, + NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"external-locking", OPT_USE_LOCKING, "Use system (external) locking (disabled by default). With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running. Disable with --skip-external-locking.", @@ -7423,20 +7423,33 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #endif case OPT_EVENT_SCHEDULER: if (!argument) - Events::opt_event_scheduler= 2; + Events::opt_event_scheduler= Events::EVENTS_DISABLED; else { int type; - if ((type=find_type(argument, &Events::opt_typelib, 1)) <= 0) - { - fprintf(stderr,"Unknown option to event-scheduler: %s\n",argument); - exit(1); - } /* - type= 1 2 3 4 5 6 - (OFF | 0) - (ON | 1) - (2 | SUSPEND) + type= 5 1 2 3 4 + (DISABLE ) - (OFF | ON) - (0 | 1) */ - Events::opt_event_scheduler= (type-1) / 2; + switch ((type=find_type(argument, &Events::opt_typelib, 1))) { + case 0: + fprintf(stderr, "Unknown option to event-scheduler: %s\n",argument); + exit(1); + case 5: /* OPT_DISABLED */ + Events::opt_event_scheduler= Events::EVENTS_DISABLED; + break; + case 2: /* OPT_ON */ + case 4: /* 1 */ + Events::opt_event_scheduler= Events::EVENTS_ON; + break; + case 1: /* OPT_OFF */ + case 3: /* 0 */ + Events::opt_event_scheduler= Events::EVENTS_OFF; + break; + default: + DBUG_ASSERT(0); + unireg_abort(1); + } } break; case (int) OPT_SKIP_NEW: diff --git a/sql/set_var.cc b/sql/set_var.cc index f10df7fa6f8..d2764e13ae3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3914,6 +3914,7 @@ bool sys_var_thd_dbug::update(THD *thd, set_var *var) return 0; } + byte *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b) { char buf[256]; @@ -3925,6 +3926,12 @@ byte *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b) } +bool sys_var_event_scheduler::check(THD *thd, set_var *var) +{ + return check_enum(thd, var, &Events::var_typelib); +} + + /* The update method of the global variable event_scheduler. If event_scheduler is switched from 0 to 1 then the scheduler main @@ -3946,29 +3953,27 @@ sys_var_event_scheduler::update(THD *thd, set_var *var) int res; /* here start the thread if not running. */ DBUG_ENTER("sys_var_event_scheduler::update"); - if (Events::opt_event_scheduler == 0) + if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) { - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=0"); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--event-scheduler=DISABLED"); DBUG_RETURN(TRUE); } DBUG_PRINT("new_value", ("%lu", (bool)var->save_result.ulong_value)); - if (var->save_result.ulonglong_value < 1 || - var->save_result.ulonglong_value > 2) - { - char buf[64]; - my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "event_scheduler", - llstr(var->save_result.ulonglong_value, buf)); - DBUG_RETURN(TRUE); - } - if (var->save_result.ulonglong_value == 1) + Item_result var_type= var->value->result_type(); + + if (var->save_result.ulong_value == Events::EVENTS_ON) res= Events::get_instance()->start_execution_of_events(); - else + else if (var->save_result.ulong_value == Events::EVENTS_OFF) res= Events::get_instance()->stop_execution_of_events(); - + else + { + DBUG_ASSERT(0); + } if (res) my_error(ER_EVENT_SET_VAR_ERROR, MYF(0)); + DBUG_RETURN((bool) res); } @@ -3976,14 +3981,15 @@ sys_var_event_scheduler::update(THD *thd, set_var *var) byte *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) { - if (Events::opt_event_scheduler == 0) - thd->sys_var_tmp.long_value= 0; + int state; + if (Events::opt_event_scheduler == Events::EVENTS_DISABLED) + state= Events::EVENTS_DISABLED; // This should be DISABLED else if (Events::get_instance()->is_execution_of_events_started()) - thd->sys_var_tmp.long_value= 1; + state= Events::EVENTS_ON; // This should be ON else - thd->sys_var_tmp.long_value= 2; + state= Events::EVENTS_OFF; // This should be OFF - return (byte*) &thd->sys_var_tmp; + return (byte*) Events::opt_typelib.type_names[state]; } diff --git a/sql/set_var.h b/sql/set_var.h index a63bcc4a55d..01669b378e1 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -932,6 +932,12 @@ public: sys_var_long_ptr(name_arg, NULL, NULL) {}; bool update(THD *thd, set_var *var); byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); + SHOW_TYPE type() { return SHOW_CHAR; } + bool check(THD *thd, set_var *var); + bool check_update_type(Item_result type) + { + return type != STRING_RESULT && type != INT_RESULT; + } }; #ifdef HAVE_ROW_BASED_REPLICATION |