summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2007-02-26 15:25:43 +0400
committerunknown <bar@mysql.com>2007-02-26 15:25:43 +0400
commitf534fc5e2a89246ddb4ea7d85055f941f211034c (patch)
tree840e2c8cd1e24a28481b85b03abdb959e836d7ed
parent6dab9de8ec1eb7a64bd453053a172db74f62cfa5 (diff)
downloadmariadb-git-f534fc5e2a89246ddb4ea7d85055f941f211034c.tar.gz
Bug#24478 DROP TRIGGER is not caught by replicate-*-table filters
Problem: DROP TRIGGER was not properly handled in combination with slave filters, which made replication stop Fix: loading table name before checking slave filters when dropping a trigger. mysql-test/r/rpl_replicate_do.result: Adding test case mysql-test/t/rpl_replicate_do.test: Adding test case sql/sql_parse.cc: Loading table name when dropping a trigger before checking slave filtering rules. sql/sql_trigger.cc: Making add_table_for_trigger() public sql/sql_trigger.h: Making add_table_for_trigger() public
-rw-r--r--mysql-test/r/rpl_replicate_do.result34
-rw-r--r--mysql-test/t/rpl_replicate_do.test32
-rw-r--r--sql/sql_parse.cc25
-rw-r--r--sql/sql_trigger.cc6
-rw-r--r--sql/sql_trigger.h4
5 files changed, 96 insertions, 5 deletions
diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result
index f79f6305342..9bacffb0609 100644
--- a/mysql-test/r/rpl_replicate_do.result
+++ b/mysql-test/r/rpl_replicate_do.result
@@ -41,3 +41,37 @@ select * from t1;
ts
2005-08-12 00:00:00
drop table t1;
+*** master ***
+create table t1 (a int, b int);
+create trigger trg1 before insert on t1 for each row set new.b=2;
+create table t2 (a int, b int);
+create trigger trg2 before insert on t2 for each row set new.b=2;
+show tables;
+Tables_in_test
+t1
+t2
+show triggers;
+Trigger Event Table Statement Timing Created sql_mode Definer
+trg1 INSERT t1 set new.b=2 BEFORE NULL root@localhost
+trg2 INSERT t2 set new.b=2 BEFORE NULL root@localhost
+*** slave ***
+show tables;
+Tables_in_test
+t1
+show triggers;
+Trigger Event Table Statement Timing Created sql_mode Definer
+trg1 INSERT t1 set new.b=2 BEFORE NULL root@localhost
+*** master ***
+drop trigger trg1;
+drop trigger trg2;
+show triggers;
+Trigger Event Table Statement Timing Created sql_mode Definer
+*** slave ***
+show tables;
+Tables_in_test
+t1
+show triggers;
+Trigger Event Table Statement Timing Created sql_mode Definer
+*** master ***
+drop table t1;
+drop table t2;
diff --git a/mysql-test/t/rpl_replicate_do.test b/mysql-test/t/rpl_replicate_do.test
index 9dec8c06c79..0e95d71514b 100644
--- a/mysql-test/t/rpl_replicate_do.test
+++ b/mysql-test/t/rpl_replicate_do.test
@@ -59,3 +59,35 @@ drop table t1;
sync_slave_with_master;
# End of 4.1 tests
+
+#
+# Bug#24478 DROP TRIGGER is not caught by replicate-*-table filters
+#
+--echo *** master ***
+connection master;
+create table t1 (a int, b int);
+create trigger trg1 before insert on t1 for each row set new.b=2;
+create table t2 (a int, b int);
+create trigger trg2 before insert on t2 for each row set new.b=2;
+show tables;
+show triggers;
+sync_slave_with_master;
+--echo *** slave ***
+connection slave;
+show tables;
+show triggers;
+--echo *** master ***
+connection master;
+drop trigger trg1;
+drop trigger trg2;
+show triggers;
+sync_slave_with_master;
+--echo *** slave ***
+connection slave;
+show tables;
+show triggers;
+--echo *** master ***
+connection master;
+drop table t1;
+drop table t2;
+sync_slave_with_master;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b0b7afc6528..7226a8e3c86 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -33,6 +33,7 @@
#include "sp_head.h"
#include "sp.h"
#include "sp_cache.h"
+#include "sql_trigger.h"
#ifdef HAVE_OPENSSL
/*
@@ -2485,6 +2486,30 @@ mysql_execute_command(THD *thd)
#ifdef HAVE_REPLICATION
if (unlikely(thd->slave_thread))
{
+ if (lex->sql_command == SQLCOM_DROP_TRIGGER)
+ {
+ /*
+ When dropping a trigger, we need to load its table name
+ before checking slave filter rules.
+ */
+ add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
+
+ if (!all_tables)
+ {
+ /*
+ If table name cannot be loaded,
+ it means the trigger does not exists possibly because
+ CREATE TRIGGER was previously skipped for this trigger
+ according to slave filtering rules.
+ Returning success without producing any errors in this case.
+ */
+ DBUG_RETURN(0);
+ }
+
+ // force searching in slave.cc:tables_ok()
+ all_tables->updating= 1;
+ }
+
/*
Check if statment should be skipped because of slave filtering
rules
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 3569733d064..0b648570b86 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -107,10 +107,6 @@ const LEX_STRING trg_event_type_names[]=
};
-static int
-add_table_for_trigger(THD *thd, sp_name *trig, bool if_exists,
- TABLE_LIST ** table);
-
class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook
{
private:
@@ -1183,7 +1179,7 @@ bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event,
1 Error
*/
-static int
+int
add_table_for_trigger(THD *thd, sp_name *trig, bool if_exists,
TABLE_LIST **table)
{
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 7e0fadfa677..8970986b931 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -139,3 +139,7 @@ private:
extern const LEX_STRING trg_action_time_type_names[];
extern const LEX_STRING trg_event_type_names[];
+
+int
+add_table_for_trigger(THD *thd, sp_name *trig, bool if_exists,
+ TABLE_LIST **table);