#At file:///home/daogangqu/mysql/bzrwork/bug49132/mysql-pe/ based on revid:magne.mahre@stripped
3843 Dao-Gang.Qu@stripped 2010-01-25 [merge]
Bug #49132 Replication failure on temporary table + DDL
In RBR, DDL statement will change binlog format to non row-based
format before it is binlogged, but the binlog format was not be
restored, and then manipulating a temporary table can not reset binlog
format to row-based format rightly. So that the manipulated statement
is binlogged with statement-based format.
To fix the problem, restore the state of binlog format after the DDL
statement is binlogged.
@ mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
Added the test file to verify if executing DDL statement before
trying to manipulate a temporary table causes row-based replication
to break with error 'table does not exist'.
@ mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
Correct the test result, all the above binlog event
should be row-based after the bug49132 is fixed in RBR.
@ mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result
Test result for bug#49132 base on ndb engine.
@ mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test
Added the test file to verify if executing DDL statement before
trying to manipulate a temporary table causes row-based replication
to break with error 'table does not exist' base on ndb engine.
@ mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
Test result for bug#49132 base on myisam engine.
@ mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test
Added the test file to verify if executing DDL statement before
trying to manipulate a temporary table causes row-based replication
to break with error 'table does not exist' base on myisam engine.
@ sql/event_db_repository.cc
Added code to restore the state of binlog format after the DDL
statement is binlogged.
@ sql/events.cc
Added code to restore the state of binlog format after the DDL
statement is binlogged.
@ sql/sp.cc
Added code to restore the state of binlog format after the DDL
statement is binlogged.
@ sql/sql_acl.cc
Added code to restore the state of binlog format after the DDL
statement is binlogged.
@ sql/sql_udf.cc
Added code to restore the state of binlog format after the DDL
statement is binlogged.
added:
mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test
mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result
mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test
mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result
mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test
modified:
mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result
sql/event_db_repository.cc
sql/events.cc
sql/sp.cc
sql/sql_acl.cc
sql/sql_udf.cc
=== added file 'mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
@@ -0,0 +1,159 @@
+#
+# This test verify if executing DDL statement before trying to manipulate
+# a temporary table causes row-based replication to break with error 'table
+# does not exist'.
+#
+
+# CREATE TABLE when a temporary table is open.
+CREATE TEMPORARY TABLE t1 (a INT);
+EVAL CREATE TABLE t2 (a INT, b INT) ENGINE= $ENGINE_TYPE;
+INSERT INTO t1 VALUES (1);
+
+# CREATE EVENT when a temporary table is open.
+CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+
+# ALTER EVENT when a temporary table is open.
+ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+
+# DROP EVENT when a temporary table is open.
+DROP EVENT IF EXISTS e1;
+INSERT INTO t1 VALUES (1);
+
+# CREATE PROCEDURE when a temporary table is open.
+CREATE PROCEDURE p1() SELECT 1;
+INSERT INTO t1 VALUES (1);
+
+# Alter PROCEDURE when a temporary table is open.
+ALTER PROCEDURE p1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+
+# CREATE FUNCTION when a temporary table is open.
+CREATE FUNCTION f1() RETURNS INT RETURN 123;
+INSERT INTO t1 VALUES (1);
+
+# ALTER FUNCTION when a temporary table is open.
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+
+# CREATE DATABASE when a temporary table is open.
+CREATE DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+
+# DROP DATABASE when a temporary table is open.
+DROP DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+
+# CREATE USER when a temporary table is open.
+CREATE USER test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT select on table to user when a temporary table is open.
+GRANT SELECT ON t2 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT all on function to user when a temporary table is open.
+GRANT ALL ON f1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT all on procedure to user when a temporary table is open.
+GRANT ALL ON p1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# GRANT usage on *.* to user when a temporary table is open.
+GRANT USAGE ON *.* TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# REVOKE usage on *.* from user when a temporary table is open.
+REVOKE USAGE ON *.* FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+
+# RENAME USER when a temporary table is open.
+RENAME USER test_1@localhost TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+
+# DROP USER when a temporary table is open.
+DROP USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+
+# Test ACL statement in sub statement
+DELIMITER |;
+CREATE PROCEDURE p2()
+BEGIN
+ # CREATE USER when a temporary table is open.
+ CREATE TEMPORARY TABLE t3 (a INT);
+ CREATE USER test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT select on table to user when a temporary table is open.
+ GRANT SELECT ON t2 TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT all on function to user when a temporary table is open.
+ GRANT ALL ON f1 TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT all on procedure to user when a temporary table is open.
+ GRANT ALL ON p1 TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # GRANT usage on *.* to user when a temporary table is open.
+ GRANT USAGE ON *.* TO test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+ REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+ REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+ REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # REVOKE usage on *.* from user when a temporary table is open.
+ REVOKE USAGE ON *.* FROM test_2@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # RENAME USER when a temporary table is open.
+ RENAME USER test_2@localhost TO test_3@localhost;
+ INSERT INTO t1 VALUES (1);
+
+ # DROP USER when a temporary table is open.
+ DROP USER test_3@localhost;
+ INSERT INTO t1 VALUES (1);
+ DROP TEMPORARY TABLE t3;
+END |
+DELIMITER ;|
+
+# DROP PROCEDURE when a temporary table is open.
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (1);
+DROP PROCEDURE p2;
+INSERT INTO t1 VALUES (1);
+
+# DROP FUNCTION when a temporary table is open.
+DROP FUNCTION f1;
+INSERT INTO t1 VALUES (1);
+
+# DROP TABLE when a temporary table is open.
+DROP TABLE t2;
+INSERT INTO t1 VALUES (1);
+
+DROP TEMPORARY TABLE t1;
+
=== modified file 'mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result'
--- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2010-01-21 08:47:09 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result 2010-01-25 02:10:08 +0000
@@ -746,8 +746,9 @@ ERROR 23000: Duplicate entry '2' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=3
-master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(2))
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 3 */;
count(*)
@@ -763,8 +764,9 @@ count(*)
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=4
-master-bin.000001 # Query # # use `test`; delete from t2 where a=bug27417(3)
+master-bin.000001 # Table_map # # table_id: # (test.t2)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 5 */;
count(*)
@@ -786,6 +788,10 @@ insert into t2 values (bug27417(1));
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 1 */;
count(*)
1
@@ -797,6 +803,10 @@ insert into t2 select bug27417(1) union
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 2 */;
count(*)
2
@@ -808,8 +818,11 @@ ERROR 23000: Duplicate entry '4' for key
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN
-master-bin.000001 # Intvar # # INSERT_ID=4
-master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1)
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: #
+master-bin.000001 # Update_rows # # table_id: #
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 2 */;
count(*)
@@ -823,6 +836,10 @@ UPDATE t4,t3 SET t4.a=t3.a + bug27417(1)
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 4 */;
count(*)
4
@@ -836,7 +853,7 @@ UPDATE t3,t4 SET t3.a=t4.a + bug27417(1)
ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */;
count(*)
-1
+2
drop table t4;
delete from t1;
delete from t2;
@@ -850,6 +867,11 @@ delete from t2;
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t3)
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 1 */;
count(*)
1
@@ -866,6 +888,10 @@ delete t2.* from t2,t5 where t2.a=t5.a +
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
select count(*) from t1 /* must be 1 */;
count(*)
1
@@ -883,6 +909,10 @@ count(*)
2
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # BEGIN
+master-bin.000001 # Table_map # # table_id: # (test.t1)
+master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
+master-bin.000001 # Query # # COMMIT
drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5;
drop function bug27417;
=== added file 'mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result'
--- a/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result 2010-01-22 09:38:21 +0000
@@ -0,0 +1,90 @@
+CREATE TEMPORARY TABLE t1 (a INT);
+CREATE TABLE t2 (a INT, b INT) ENGINE= NDB;
+INSERT INTO t1 VALUES (1);
+CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+DROP EVENT IF EXISTS e1;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1() SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER PROCEDURE p1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN 123;
+INSERT INTO t1 VALUES (1);
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+DROP DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+CREATE USER test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT SELECT ON t2 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON f1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON p1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT USAGE ON *.* TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE USAGE ON *.* FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+RENAME USER test_1@localhost TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+DROP USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p2()
+BEGIN
+# CREATE USER when a temporary table is open.
+CREATE TEMPORARY TABLE t3 (a INT);
+CREATE USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT select on table to user when a temporary table is open.
+GRANT SELECT ON t2 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on function to user when a temporary table is open.
+GRANT ALL ON f1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on procedure to user when a temporary table is open.
+GRANT ALL ON p1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT usage on *.* to user when a temporary table is open.
+GRANT USAGE ON *.* TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE usage on *.* from user when a temporary table is open.
+REVOKE USAGE ON *.* FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# RENAME USER when a temporary table is open.
+RENAME USER test_2@localhost TO test_3@localhost;
+INSERT INTO t1 VALUES (1);
+# DROP USER when a temporary table is open.
+DROP USER test_3@localhost;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t3;
+END |
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (1);
+DROP PROCEDURE p2;
+INSERT INTO t1 VALUES (1);
+DROP FUNCTION f1;
+INSERT INTO t1 VALUES (1);
+DROP TABLE t2;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t1;
=== added file 'mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test'
--- a/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
@@ -0,0 +1,11 @@
+#
+# Bug#49132
+# This test verifies if executing DDL statement before trying to manipulate
+# a temporary table causes row-based replication to break with error 'table
+# does not exist' base on ndb engine.
+#
+
+source include/have_ndb.inc;
+
+LET $ENGINE_TYPE= NDB;
+source extra/rpl_tests/rpl_tmp_table_and_DDL.test;
=== added file 'mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result'
--- a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result 2010-01-22 09:38:21 +0000
@@ -0,0 +1,96 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TEMPORARY TABLE t1 (a INT);
+CREATE TABLE t2 (a INT, b INT) ENGINE= MyISAM;
+INSERT INTO t1 VALUES (1);
+CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1;
+INSERT INTO t1 VALUES (1);
+DROP EVENT IF EXISTS e1;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p1() SELECT 1;
+INSERT INTO t1 VALUES (1);
+ALTER PROCEDURE p1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE FUNCTION f1() RETURNS INT RETURN 123;
+INSERT INTO t1 VALUES (1);
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+INSERT INTO t1 VALUES (1);
+CREATE DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+DROP DATABASE mysqltest1;
+INSERT INTO t1 VALUES (1);
+CREATE USER test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT SELECT ON t2 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON f1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT ALL ON p1 TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+GRANT USAGE ON *.* TO test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+REVOKE USAGE ON *.* FROM test_1@localhost;
+INSERT INTO t1 VALUES (1);
+RENAME USER test_1@localhost TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+DROP USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+CREATE PROCEDURE p2()
+BEGIN
+# CREATE USER when a temporary table is open.
+CREATE TEMPORARY TABLE t3 (a INT);
+CREATE USER test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT select on table to user when a temporary table is open.
+GRANT SELECT ON t2 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on function to user when a temporary table is open.
+GRANT ALL ON f1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT all on procedure to user when a temporary table is open.
+GRANT ALL ON p1 TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# GRANT usage on *.* to user when a temporary table is open.
+GRANT USAGE ON *.* TO test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on function to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE ALL PRIVILEGES on table to user when a temporary table is open.
+REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# REVOKE usage on *.* from user when a temporary table is open.
+REVOKE USAGE ON *.* FROM test_2@localhost;
+INSERT INTO t1 VALUES (1);
+# RENAME USER when a temporary table is open.
+RENAME USER test_2@localhost TO test_3@localhost;
+INSERT INTO t1 VALUES (1);
+# DROP USER when a temporary table is open.
+DROP USER test_3@localhost;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t3;
+END |
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (1);
+DROP PROCEDURE p2;
+INSERT INTO t1 VALUES (1);
+DROP FUNCTION f1;
+INSERT INTO t1 VALUES (1);
+DROP TABLE t2;
+INSERT INTO t1 VALUES (1);
+DROP TEMPORARY TABLE t1;
=== added file 'mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test'
--- a/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test 2010-01-22 09:38:21 +0000
@@ -0,0 +1,13 @@
+#
+# Bug#49132
+# This test verifies if executing DDL statement before trying to manipulate
+# a temporary table causes row-based replication to break with error 'table
+# does not exist' base on myisam engine.
+#
+
+source include/master-slave.inc;
+source include/have_binlog_format_row.inc;
+
+LET $ENGINE_TYPE= MyISAM;
+source extra/rpl_tests/rpl_tmp_table_and_DDL.test;
+
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2010-01-13 06:34:01 +0000
+++ b/sql/event_db_repository.cc 2010-01-25 02:10:08 +0000
@@ -1045,6 +1045,7 @@ update_timing_fields_for_event(THD *thd,
TABLE *table= NULL;
Field **fields;
int ret= 1;
+ bool save_binlog_row_based;
DBUG_ENTER("Event_db_repository::update_timing_fields_for_event");
@@ -1052,7 +1053,7 @@ update_timing_fields_for_event(THD *thd,
Turn off row binlogging of event timing updates. These are not used
for RBR of events replicated to the slave.
*/
- if (thd->is_current_stmt_binlog_format_row())
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
thd->clear_current_stmt_binlog_format_row();
DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL);
@@ -1095,6 +1096,9 @@ update_timing_fields_for_event(THD *thd,
end:
if (table)
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(test(ret));
}
=== modified file 'sql/events.cc'
--- a/sql/events.cc 2010-01-21 08:47:09 +0000
+++ b/sql/events.cc 2010-01-25 02:10:08 +0000
@@ -293,6 +293,7 @@ Events::create_event(THD *thd, Event_par
bool if_not_exists)
{
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("Events::create_event");
if (check_if_system_tables_error())
@@ -324,7 +325,7 @@ Events::create_event(THD *thd, Event_par
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE EVENT command.
*/
- if (thd->is_current_stmt_binlog_format_row())
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
thd->clear_current_stmt_binlog_format_row();
mysql_mutex_lock(&LOCK_event_metadata);
@@ -365,6 +366,9 @@ Events::create_event(THD *thd, Event_par
{
sql_print_error("Event Error: An error occurred while creating query string, "
"before writing it into binary log.");
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(TRUE);
}
/* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
@@ -373,6 +377,9 @@ Events::create_event(THD *thd, Event_par
}
}
mysql_mutex_unlock(&LOCK_event_metadata);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(ret);
}
@@ -402,6 +409,7 @@ Events::update_event(THD *thd, Event_par
LEX_STRING *new_dbname, LEX_STRING *new_name)
{
int ret;
+ bool save_binlog_row_based;
Event_queue_element *new_element;
DBUG_ENTER("Events::update_event");
@@ -448,7 +456,7 @@ Events::update_event(THD *thd, Event_par
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for UPDATE EVENT command.
*/
- if (thd->is_current_stmt_binlog_format_row())
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
thd->clear_current_stmt_binlog_format_row();
mysql_mutex_lock(&LOCK_event_metadata);
@@ -485,6 +493,9 @@ Events::update_event(THD *thd, Event_par
}
}
mysql_mutex_unlock(&LOCK_event_metadata);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(ret);
}
@@ -518,6 +529,7 @@ bool
Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
{
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("Events::drop_event");
if (check_if_system_tables_error())
@@ -530,7 +542,7 @@ Events::drop_event(THD *thd, LEX_STRING
Turn off row binlogging of this statement and use statement-based so
that all supporting tables are updated for DROP EVENT command.
*/
- if (thd->is_current_stmt_binlog_format_row())
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
thd->clear_current_stmt_binlog_format_row();
mysql_mutex_lock(&LOCK_event_metadata);
@@ -544,6 +556,9 @@ Events::drop_event(THD *thd, LEX_STRING
ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
}
mysql_mutex_unlock(&LOCK_event_metadata);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(ret);
}
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2010-01-13 06:34:01 +0000
+++ b/sql/sp.cc 2010-01-25 02:10:08 +0000
@@ -914,6 +914,8 @@ sp_create_routine(THD *thd, int type, sp
bool store_failed= FALSE;
+ bool save_binlog_row_based;
+
DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
sp->m_name.str));
@@ -931,7 +933,8 @@ sp_create_routine(THD *thd, int type, sp
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
saved_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields= CHECK_FIELD_WARN;
@@ -1138,6 +1141,9 @@ done:
thd->variables.sql_mode= saved_mode;
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(ret);
}
@@ -1162,6 +1168,7 @@ sp_drop_routine(THD *thd, int type, sp_n
{
TABLE *table;
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("sp_drop_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str));
@@ -1174,7 +1181,8 @@ sp_drop_routine(THD *thd, int type, sp_n
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
if (!(table= open_proc_table_for_update(thd)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
@@ -1192,6 +1200,9 @@ sp_drop_routine(THD *thd, int type, sp_n
}
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(ret);
}
@@ -1218,6 +1229,7 @@ sp_update_routine(THD *thd, int type, sp
{
TABLE *table;
int ret;
+ bool save_binlog_row_based;
DBUG_ENTER("sp_update_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str));
@@ -1229,7 +1241,8 @@ sp_update_routine(THD *thd, int type, sp
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
if (!(table= open_proc_table_for_update(thd)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
@@ -1263,6 +1276,9 @@ sp_update_routine(THD *thd, int type, sp
}
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(ret);
}
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2010-01-21 08:47:09 +0000
+++ b/sql/sql_acl.cc 2010-01-25 02:10:08 +0000
@@ -3029,6 +3029,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
TABLE_LIST tables[3];
bool create_new_users=0;
char *db_name, *table_name;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_table_grant");
if (!initialized)
@@ -3135,7 +3136,8 @@ int mysql_table_grant(THD *thd, TABLE_LI
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
#ifdef HAVE_REPLICATION
/*
@@ -3150,7 +3152,12 @@ int mysql_table_grant(THD *thd, TABLE_LI
*/
tables[0].updating= tables[1].updating= tables[2].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(FALSE);
+ }
}
#endif
@@ -3163,6 +3170,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd); /* purecov: deadcode */
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(TRUE); /* purecov: deadcode */
}
@@ -3289,6 +3299,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
/* Tables are automatically closed */
thd->lex->restore_backup_query_tables_list(&backup);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result);
}
@@ -3317,6 +3330,7 @@ bool mysql_routine_grant(THD *thd, TABLE
TABLE_LIST tables[2];
bool create_new_users=0, result=0;
char *db_name, *table_name;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_routine_grant");
if (!initialized)
@@ -3353,7 +3367,8 @@ bool mysql_routine_grant(THD *thd, TABLE
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
#ifdef HAVE_REPLICATION
/*
@@ -3368,13 +3383,21 @@ bool mysql_routine_grant(THD *thd, TABLE
*/
tables[0].updating= tables[1].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(FALSE);
+ }
}
#endif
if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(TRUE);
}
@@ -3451,6 +3474,9 @@ bool mysql_routine_grant(THD *thd, TABLE
}
mysql_rwlock_unlock(&LOCK_grant);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
/* Tables are automatically closed */
DBUG_RETURN(result);
@@ -3465,6 +3491,7 @@ bool mysql_grant(THD *thd, const char *d
char tmp_db[NAME_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_grant");
if (!initialized)
{
@@ -3494,7 +3521,8 @@ bool mysql_grant(THD *thd, const char *d
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
#ifdef HAVE_REPLICATION
/*
@@ -3509,13 +3537,21 @@ bool mysql_grant(THD *thd, const char *d
*/
tables[0].updating= tables[1].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(FALSE);
+ }
}
#endif
if (simple_open_n_lock_tables(thd,tables))
{ // This should never happen
close_thread_tables(thd); /* purecov: deadcode */
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(TRUE); /* purecov: deadcode */
}
@@ -3575,6 +3611,9 @@ bool mysql_grant(THD *thd, const char *d
if (!result)
my_ok(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result);
}
@@ -5781,6 +5820,7 @@ bool mysql_create_user(THD *thd, List <L
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
bool some_users_created= FALSE;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_create_user");
/*
@@ -5788,11 +5828,17 @@ bool mysql_create_user(THD *thd, List <L
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
/* CREATE USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result != 1);
+ }
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
@@ -5834,6 +5880,9 @@ bool mysql_create_user(THD *thd, List <L
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result);
}
@@ -5860,6 +5909,7 @@ bool mysql_drop_user(THD *thd, List <LEX
TABLE_LIST tables[GRANT_TABLES];
bool some_users_deleted= FALSE;
ulong old_sql_mode= thd->variables.sql_mode;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_drop_user");
/*
@@ -5867,11 +5917,17 @@ bool mysql_drop_user(THD *thd, List <LEX
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
/* DROP USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result != 1);
+ }
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
@@ -5908,6 +5964,9 @@ bool mysql_drop_user(THD *thd, List <LEX
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
thd->variables.sql_mode= old_sql_mode;
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result);
}
@@ -5934,6 +5993,7 @@ bool mysql_rename_user(THD *thd, List <L
List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES];
bool some_users_renamed= FALSE;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_rename_user");
/*
@@ -5941,11 +6001,17 @@ bool mysql_rename_user(THD *thd, List <L
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
/* RENAME USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result != 1);
+ }
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
@@ -5992,6 +6058,9 @@ bool mysql_rename_user(THD *thd, List <L
mysql_rwlock_unlock(&LOCK_grant);
close_thread_tables(thd);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result);
}
@@ -6016,6 +6085,7 @@ bool mysql_revoke_all(THD *thd, List <L
int result;
ACL_DB *acl_db;
TABLE_LIST tables[GRANT_TABLES];
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_revoke_all");
/*
@@ -6023,10 +6093,16 @@ bool mysql_revoke_all(THD *thd, List <L
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
if ((result= open_grant_tables(thd, tables)))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result != 1);
+ }
mysql_rwlock_wrlock(&LOCK_grant);
mysql_mutex_lock(&acl_cache->lock);
@@ -6179,6 +6255,9 @@ bool mysql_revoke_all(THD *thd, List <L
/* error for writing binary log has already been reported */
if (result && !binlog_error)
my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(result || binlog_error);
}
@@ -6270,6 +6349,7 @@ bool sp_revoke_privileges(THD *thd, cons
TABLE_LIST tables[GRANT_TABLES];
HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
Silence_routine_definer_errors error_handler;
+ bool save_binlog_row_based;
DBUG_ENTER("sp_revoke_privileges");
if ((result= open_grant_tables(thd, tables)))
@@ -6286,7 +6366,8 @@ bool sp_revoke_privileges(THD *thd, cons
row-based replication. The flag will be reset at the end of the
statement.
*/
- thd->clear_current_stmt_binlog_format_row();
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->clear_current_stmt_binlog_format_row();
/* Remove procedure access */
do
@@ -6322,6 +6403,9 @@ bool sp_revoke_privileges(THD *thd, cons
close_thread_tables(thd);
thd->pop_internal_handler();
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(error_handler.has_errors());
}
=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc 2010-01-13 14:34:46 +0000
+++ b/sql/sql_udf.cc 2010-01-25 02:10:08 +0000
@@ -417,6 +417,7 @@ int mysql_create_function(THD *thd,udf_f
TABLE *table;
TABLE_LIST tables;
udf_func *u_d;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_create_function");
if (!initialized)
@@ -452,7 +453,7 @@ int mysql_create_function(THD *thd,udf_f
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE FUNCTION command.
*/
- if (thd->is_current_stmt_binlog_format_row())
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
thd->clear_current_stmt_binlog_format_row();
mysql_rwlock_wrlock(&THR_LOCK_udf);
@@ -520,13 +521,25 @@ int mysql_create_function(THD *thd,udf_f
/* Binlog the create function. */
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(1);
+ }
+
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(0);
err:
if (new_dl)
dlclose(dl);
mysql_rwlock_unlock(&THR_LOCK_udf);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(1);
}
@@ -538,6 +551,7 @@ int mysql_drop_function(THD *thd,const L
udf_func *udf;
char *exact_name_str;
uint exact_name_len;
+ bool save_binlog_row_based;
DBUG_ENTER("mysql_drop_function");
if (!initialized)
@@ -553,7 +567,7 @@ int mysql_drop_function(THD *thd,const L
Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for DROP FUNCTION command.
*/
- if (thd->is_current_stmt_binlog_format_row())
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
thd->clear_current_stmt_binlog_format_row();
mysql_rwlock_wrlock(&THR_LOCK_udf);
@@ -595,10 +609,21 @@ int mysql_drop_function(THD *thd,const L
while binlogging, to avoid binlog inconsistency.
*/
if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
+ {
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(1);
+ }
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(0);
err:
mysql_rwlock_unlock(&THR_LOCK_udf);
+ /* Restore the state of binlog format */
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
DBUG_RETURN(1);
}
Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20100125021008-l1ixhrfagmlem6ag.bundle
| Thread |
|---|
| • bzr commit into mysql-pe branch (Dao-Gang.Qu:3843) Bug#49132 | Dao-Gang.Qu | 25 Jan |