List:Commits« Previous MessageNext Message »
From:Dao-Gang.Qu Date:January 25 2010 2:12am
Subject:bzr commit into mysql-pe branch (Dao-Gang.Qu:3843) Bug#49132
View as plain text  
#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#49132Dao-Gang.Qu25 Jan