Commit ab59263b authored by unknown's avatar unknown

Fix rpl_events test failure in the runtime tree.


mysql-test/r/rpl_events.result:
  Now ON COMPLETION NOT PRESERVE events are also dropped on the
  slave, since DROP EVENT command that is invoked for all such commands
  gets invoked on the slave.
sql/event_data_objects.cc:
  Fix the failing rpl_events test after the patch for Bug#27733.
  At the time Events::drop_event got invoked inside
  Event_job_data::execute() thd->query pointed to CREATE PROCEDURE
  statement. This statement was written to the binary log
  from inside Events::drop_event (under assumption that this is a
  DROP EVENT statement that needs to be replicated), and caused
  creation of this procedure on the slave (and a subsequent failure
  when a procedure with the same name already exist).
  
  The patch ensures that thd->query points at the right query text
  for DROP EVENT executed when dropping ON COMPLETION NOT PRESERVE 
  events.
sql/event_data_objects.h:
  Update a  declaration.
sql/events.cc:
  Change if () to an assert: thd->query now always points at a valid
  query.
parent c1b6e128
...@@ -34,7 +34,6 @@ id c ts ...@@ -34,7 +34,6 @@ id c ts
affected rows: 2 affected rows: 2
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce'; SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator db name status originator
test justonce SLAVESIDE_DISABLED 1
DROP EVENT IF EXISTS test.slave_once; DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once'); INSERT INTO t1(c) VALUES ('from slave_once');
...@@ -111,7 +110,6 @@ id c ts ...@@ -111,7 +110,6 @@ id c ts
affected rows: 2 affected rows: 2
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce'; SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator db name status originator
test justonce SLAVESIDE_DISABLED 1
DROP EVENT IF EXISTS test.slave_once; DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE DO
INSERT INTO t1(c) VALUES ('from slave_once'); INSERT INTO t1(c) VALUES ('from slave_once');
......
...@@ -1792,6 +1792,33 @@ Event_job_data::construct_sp_sql(THD *thd, String *sp_sql) ...@@ -1792,6 +1792,33 @@ Event_job_data::construct_sp_sql(THD *thd, String *sp_sql)
} }
/**
Get DROP EVENT statement to binlog the drop of ON COMPLETION NOT
PRESERVE event.
*/
bool
Event_job_data::construct_drop_event_sql(THD *thd, String *sp_sql)
{
LEX_STRING buffer;
const uint STATIC_SQL_LENGTH= 14;
DBUG_ENTER("Event_job_data::construct_drop_event_sql");
buffer.length= STATIC_SQL_LENGTH + name.length*2 + dbname.length*2;
if (! (buffer.str= (char*) thd->alloc(buffer.length)))
DBUG_RETURN(TRUE);
sp_sql->set(buffer.str, buffer.length, system_charset_info);
sp_sql->length(0);
sp_sql->append(C_STRING_WITH_LEN("DROP EVENT "));
append_identifier(thd, sp_sql, dbname.str, dbname.length);
sp_sql->append('.');
append_identifier(thd, sp_sql, name.str, name.length);
DBUG_RETURN(thd->is_fatal_error);
}
/** /**
Compiles and executes the event (the underlying sp_head object) Compiles and executes the event (the underlying sp_head object)
...@@ -1804,7 +1831,9 @@ bool ...@@ -1804,7 +1831,9 @@ bool
Event_job_data::execute(THD *thd, bool drop) Event_job_data::execute(THD *thd, bool drop)
{ {
String sp_sql; String sp_sql;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Security_context event_sctx, *save_sctx= NULL; Security_context event_sctx, *save_sctx= NULL;
#endif
CHARSET_INFO *charset_connection; CHARSET_INFO *charset_connection;
List<Item> empty_item_list; List<Item> empty_item_list;
bool ret= TRUE; bool ret= TRUE;
...@@ -1916,14 +1945,25 @@ Event_job_data::execute(THD *thd, bool drop) ...@@ -1916,14 +1945,25 @@ Event_job_data::execute(THD *thd, bool drop)
end: end:
if (drop && !thd->is_fatal_error) if (drop && !thd->is_fatal_error)
{ {
sql_print_information("Event Scheduler: Dropping %s.%s",
(const char *) dbname.str, (const char *) name.str);
/* /*
We must do it here since here we're under the right authentication We must do it here since here we're under the right authentication
ID of the event definer. ID of the event definer.
*/ */
if (Events::drop_event(thd, dbname, name, FALSE)) sql_print_information("Event Scheduler: Dropping %s.%s",
(const char *) dbname.str, (const char *) name.str);
/*
Construct a query for the binary log, to ensure the event is dropped
on the slave
*/
if (construct_drop_event_sql(thd, &sp_sql))
ret= 1; ret= 1;
else
{
thd->query= sp_sql.c_ptr_safe();
thd->query_length= sp_sql.length();
if (Events::drop_event(thd, dbname, name, FALSE))
ret= 1;
}
} }
if (thd->lex->sphead) /* NULL only if a parse error */ if (thd->lex->sphead) /* NULL only if a parse error */
{ {
......
...@@ -184,6 +184,8 @@ class Event_job_data : public Event_basic ...@@ -184,6 +184,8 @@ class Event_job_data : public Event_basic
private: private:
bool bool
construct_sp_sql(THD *thd, String *sp_sql); construct_sp_sql(THD *thd, String *sp_sql);
bool
construct_drop_event_sql(THD *thd, String *sp_sql);
Event_job_data(const Event_job_data &); /* Prevent use of these */ Event_job_data(const Event_job_data &); /* Prevent use of these */
void operator=(Event_job_data &); void operator=(Event_job_data &);
......
...@@ -424,7 +424,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -424,7 +424,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
if (event_queue) if (event_queue)
event_queue->create_event(thd, new_element, &created); event_queue->create_event(thd, new_element, &created);
/* Binlog the create event. */ /* Binlog the create event. */
if (mysql_bin_log.is_open() && (thd->query_length > 0)) DBUG_ASSERT(thd->query && thd->query_length);
if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->binlog_query(THD::MYSQL_QUERY_TYPE,
...@@ -549,7 +550,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ...@@ -549,7 +550,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
event_queue->update_event(thd, parse_data->dbname, parse_data->name, event_queue->update_event(thd, parse_data->dbname, parse_data->name,
new_element); new_element);
/* Binlog the alter event. */ /* Binlog the alter event. */
if (mysql_bin_log.is_open() && (thd->query_length > 0)) DBUG_ASSERT(thd->query && thd->query_length);
if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->binlog_query(THD::MYSQL_QUERY_TYPE,
...@@ -628,7 +630,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) ...@@ -628,7 +630,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
if (event_queue) if (event_queue)
event_queue->drop_event(thd, dbname, name); event_queue->drop_event(thd, dbname, name);
/* Binlog the drop event. */ /* Binlog the drop event. */
if (mysql_bin_log.is_open() && (thd->query_length > 0)) DBUG_ASSERT(thd->query && thd->query_length);
if (mysql_bin_log.is_open())
{ {
thd->clear_error(); thd->clear_error();
thd->binlog_query(THD::MYSQL_QUERY_TYPE, thd->binlog_query(THD::MYSQL_QUERY_TYPE,
......
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