summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <kostja@vajra.(none)>2007-04-05 20:47:22 +0400
committerunknown <kostja@vajra.(none)>2007-04-05 20:47:22 +0400
commitff452d050a78083b878260f8d2393016503ae0cb (patch)
tree8ca3fb500b914b5ecd4542a6d38a8a4c49bd22c1 /sql
parenta36054f4201568fac1717b451040ffa7925900a2 (diff)
downloadmariadb-git-ff452d050a78083b878260f8d2393016503ae0cb.tar.gz
Post-merge and post-review fixes for the patch for
Bug#23631 "Events: SHOW VARIABLES doesn't work when mysql.event is damaged: mysql-test/r/events.result: Update results (a post-merge fix) mysql-test/r/events_bugs.result: Update results (a post-merge fix) mysql-test/r/events_scheduling.result: Update results (a post-merge fix) mysql-test/t/events_scheduling.test: Make sure this test has no races. sql/event_data_objects.cc: Manual post-merge fix for the events replication patch. sql/event_data_objects.h: A post-merge fix. sql/event_db_repository.cc: A post-merge fix. sql/event_scheduler.cc: We should drop the event inside ::execute since there we have the right credentials to do so (otherwise Events::drop_event returns "access denied" error). sql/events.cc: A post-review fix for: rename start_or_stop_event_scheduler to switch_event_scheduler_state. sql/events.h: A post-review fix for: rename start_or_stop_event_scheduler to switch_event_scheduler_state. sql/set_var.cc: A post-review fix for: rename start_or_stop_event_scheduler to switch_event_scheduler_state. sql/sql_yacc.yy: Remove unused declaratoins.
Diffstat (limited to 'sql')
-rw-r--r--sql/event_data_objects.cc72
-rw-r--r--sql/event_data_objects.h2
-rw-r--r--sql/event_db_repository.cc7
-rw-r--r--sql/event_scheduler.cc23
-rw-r--r--sql/events.cc12
-rw-r--r--sql/events.h2
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/sql_yacc.yy2
8 files changed, 81 insertions, 41 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 95bfba548de..1881a3540e4 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -99,7 +99,9 @@ Event_parse_data::new_instance(THD *thd)
*/
Event_parse_data::Event_parse_data()
- :on_completion(ON_COMPLETION_DROP), status(ENABLED), do_not_create(FALSE),
+ :on_completion(Event_basic::ON_COMPLETION_DROP),
+ status(Event_basic::ENABLED),
+ do_not_create(FALSE),
item_starts(NULL), item_ends(NULL), item_execute_at(NULL),
starts_null(TRUE), ends_null(TRUE), execute_at_null(TRUE),
item_expression(NULL), expression(0)
@@ -241,7 +243,7 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
if (ltime_utc >= (my_time_t) thd->query_start())
return;
- if (on_completion == ON_COMPLETION_DROP)
+ if (on_completion == Event_basic::ON_COMPLETION_DROP)
{
switch (thd->lex->sql_command) {
case SQLCOM_CREATE_EVENT:
@@ -258,9 +260,9 @@ Event_parse_data::check_if_in_the_past(THD *thd, my_time_t ltime_utc)
do_not_create= TRUE;
}
- else if (status == ENABLED)
+ else if (status == Event_basic::ENABLED)
{
- status= DISABLED;
+ status= Event_basic::DISABLED;
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_EVENT_EXEC_TIME_IN_THE_PAST,
ER(ER_EVENT_EXEC_TIME_IN_THE_PAST));
@@ -589,6 +591,7 @@ Event_parse_data::check_parse_data(THD *thd)
ret= init_execute_at(thd) || init_interval(thd) || init_starts(thd) ||
init_ends(thd);
+ check_originator_id(thd);
DBUG_RETURN(ret);
}
@@ -635,6 +638,31 @@ Event_parse_data::init_definer(THD *thd)
}
+/**
+ Set the originator id of the event to the server_id if executing on
+ the master or set to the server_id of the master if executing on
+ the slave. If executing on slave, also set status to SLAVESIDE_DISABLED.
+
+ SYNOPSIS
+ Event_parse_data::check_originator_id()
+*/
+void Event_parse_data::check_originator_id(THD *thd)
+{
+ /* Disable replicated events on slave. */
+ if ((thd->system_thread == SYSTEM_THREAD_SLAVE_SQL) ||
+ (thd->system_thread == SYSTEM_THREAD_SLAVE_IO))
+ {
+ DBUG_PRINT("info", ("Invoked object status set to SLAVESIDE_DISABLED."));
+ if ((status == Event_basic::ENABLED) ||
+ (status == Event_basic::DISABLED))
+ status = Event_basic::SLAVESIDE_DISABLED;
+ originator = thd->server_id;
+ }
+ else
+ originator = server_id;
+}
+
+
/*
Constructor
@@ -1004,8 +1032,23 @@ Event_queue_element::load_from_row(THD *thd, TABLE *table)
goto error;
DBUG_PRINT("load_from_row", ("Event [%s] is [%s]", name.str, ptr));
- status= (ptr[0]=='E'? Event_queue_element::ENABLED:
- Event_queue_element::DISABLED);
+
+ /* Set event status (ENABLED | SLAVESIDE_DISABLED | DISABLED) */
+ switch (ptr[0])
+ {
+ case 'E' :
+ status = Event_queue_element::ENABLED;
+ break;
+ case 'S' :
+ status = Event_queue_element::SLAVESIDE_DISABLED;
+ break;
+ case 'D' :
+ status = Event_queue_element::DISABLED;
+ break;
+ }
+ if ((ptr= get_field(&mem_root, table->field[ET_FIELD_ORIGINATOR])) == NullS)
+ goto error;
+ originator = table->field[ET_FIELD_ORIGINATOR]->val_int();
/* ToDo : Andrey . Find a way not to allocate ptr on event_mem_root */
if ((ptr= get_field(&mem_root,
@@ -1356,7 +1399,7 @@ Event_queue_element::compute_next_execution_time()
(long) starts, (long) ends, (long) last_executed,
(long) this));
- if (status == Event_queue_element::DISABLED)
+ if (status != Event_queue_element::ENABLED)
{
DBUG_PRINT("compute_next_execution_time",
("Event %s is DISABLED", name.str));
@@ -1708,6 +1751,8 @@ Event_timed::get_create_event(THD *thd, String *buf)
if (status == Event_timed::ENABLED)
buf->append(STRING_WITH_LEN("ENABLE"));
+ else if (status == Event_timed::SLAVESIDE_DISABLED)
+ buf->append(STRING_WITH_LEN("DISABLE ON SLAVE"));
else
buf->append(STRING_WITH_LEN("DISABLE"));
@@ -1765,7 +1810,7 @@ Event_job_data::get_fake_create_event(String *buf)
*/
int
-Event_job_data::execute(THD *thd)
+Event_job_data::execute(THD *thd, bool drop)
{
Security_context save_ctx;
/* this one is local and not needed after exec */
@@ -1805,6 +1850,17 @@ Event_job_data::execute(THD *thd)
definer_host.str, dbname.str));
ret= -99;
}
+ if (drop)
+ {
+ sql_print_information("Event Scheduler: Dropping %s.%s",
+ dbname.str, name.str);
+ /*
+ We must do it here since here we're under the right authentication
+ ID of the event definer
+ */
+ if (Events::drop_event(thd, dbname, name, FALSE))
+ ret= 1;
+ }
event_restore_security_context(thd, &save_ctx);
done:
diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h
index 4d58484e5c2..eb851c98065 100644
--- a/sql/event_data_objects.h
+++ b/sql/event_data_objects.h
@@ -184,7 +184,7 @@ public:
load_from_row(THD *thd, TABLE *table);
int
- execute(THD *thd);
+ execute(THD *thd, bool drop);
int
compile(THD *thd, MEM_ROOT *mem_root);
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index cc981c9cb69..fcd48757957 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -905,6 +905,13 @@ update_timing_fields_for_event(THD *thd,
DBUG_ENTER("Event_db_repository::update_timing_fields_for_event");
+ /*
+ Turn off row binlogging of event timing updates. These are not used
+ for RBR of events replicated to the slave.
+ */
+ if (thd->current_stmt_binlog_row_based)
+ thd->clear_current_stmt_binlog_row_based();
+
if (open_event_table(thd, TL_WRITE, &table))
goto end;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index a9a93cbc74b..fa5cde9a43a 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -309,7 +309,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
thd->enable_slow_log= TRUE;
- ret= job_data->execute(thd);
+ ret= job_data->execute(thd, event->dropped);
print_warnings(thd, job_data);
@@ -338,27 +338,6 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
end:
delete job_data;
- if (event->dropped)
- {
- sql_print_information("Event Scheduler: Dropping %s.%s",
- event->dbname.str, event->name.str);
- /*
- Using db_repository can lead to a race condition because we access
- the table without holding LOCK_metadata.
- Scenario:
- 1. CREATE EVENT xyz AT ... (conn thread)
- 2. execute xyz (worker)
- 3. CREATE EVENT XYZ EVERY ... (conn thread)
- 4. drop xyz (worker)
- 5. XYZ was just created on disk but `drop xyz` of the worker dropped it.
- A consequent load to create Event_queue_element will fail.
-
- If all operations are performed under LOCK_metadata there is no such
- problem. However, this comes at the price of introduction bi-directional
- association between class Events and class Event_worker_thread.
- */
- Events::drop_event(thd, event->dbname, event->name, FALSE);
- }
DBUG_PRINT("info", ("Done with Event %s.%s", event->dbname.str,
event->name.str));
diff --git a/sql/events.cc b/sql/events.cc
index 7c44116af55..10a002121a0 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1041,14 +1041,14 @@ Events::dump_internal_status()
*/
bool
-Events::start_or_stop_event_scheduler(enum_opt_event_scheduler start_or_stop)
+Events::switch_event_scheduler_state(enum_opt_event_scheduler new_state)
{
bool ret= FALSE;
- DBUG_ENTER("Events::start_or_stop_event_scheduler");
+ DBUG_ENTER("Events::switch_event_scheduler_state");
- DBUG_ASSERT(start_or_stop == Events::EVENTS_ON ||
- start_or_stop == Events::EVENTS_OFF);
+ DBUG_ASSERT(new_state == Events::EVENTS_ON ||
+ new_state == Events::EVENTS_OFF);
/*
If the scheduler was disabled because there are no/bad
@@ -1068,7 +1068,7 @@ Events::start_or_stop_event_scheduler(enum_opt_event_scheduler start_or_stop)
goto end;
}
- if (start_or_stop == EVENTS_ON)
+ if (new_state == EVENTS_ON)
ret= scheduler->start();
else
ret= scheduler->stop();
@@ -1079,7 +1079,7 @@ Events::start_or_stop_event_scheduler(enum_opt_event_scheduler start_or_stop)
goto end;
}
- opt_event_scheduler= start_or_stop;
+ opt_event_scheduler= new_state;
end:
pthread_mutex_unlock(&LOCK_event_metadata);
diff --git a/sql/events.h b/sql/events.h
index db0e947ab6c..1b99b072fd7 100644
--- a/sql/events.h
+++ b/sql/events.h
@@ -99,7 +99,7 @@ public:
destroy_mutexes();
static bool
- start_or_stop_event_scheduler(enum enum_opt_event_scheduler start_or_stop);
+ switch_event_scheduler_state(enum enum_opt_event_scheduler new_state);
static bool
create_event(THD *thd, Event_parse_data *parse_data, bool if_exists);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 898d47e766e..741969214bd 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -4020,7 +4020,7 @@ sys_var_event_scheduler::update(THD *thd, set_var *var)
new_state=
(enum Events::enum_opt_event_scheduler) var->save_result.ulong_value;
- res= Events::start_or_stop_event_scheduler(new_state);
+ res= Events::switch_event_scheduler_state(new_state);
DBUG_RETURN((bool) res);
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 0c6ce1d7eeb..50bc81cc13d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -948,7 +948,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SIGNED_SYM
%token SIMPLE_SYM /* SQL-2003-N */
%token SLAVE
-%token SLAVESIDE_DISABLE_SYM
%token SMALLINT /* SQL-2003-R */
%token SNAPSHOT_SYM
%token SOCKET_SYM
@@ -10004,7 +10003,6 @@ keyword_sp:
| SIMPLE_SYM {}
| SHARE_SYM {}
| SHUTDOWN {}
- | SLAVESIDE_DISABLE_SYM {}
| SNAPSHOT_SYM {}
| SOUNDS_SYM {}
| SQL_CACHE_SYM {}