List:Commits« Previous MessageNext Message »
From:Dao-Gang.Qu Date:January 20 2010 8:26am
Subject:bzr commit into mysql-5.1-bugteam branch (Dao-Gang.Qu:3316) Bug#49132
View as plain text  
#At file:///home/daogangqu/mysql/bzrwork/bug49132/mysql-5.1-bugteam/ based on revid:joro@stripped

 3316 Dao-Gang.Qu@stripped	2010-01-20
      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-20 08:26:13 +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	2009-12-06 01:11:32 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result	2010-01-20 08:26:13 +0000
@@ -772,8 +772,11 @@ insert into t2 values (bug27417(2));
 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	#	Intvar	#	#	INSERT_ID=3
-master-bin.000001	#	Query	#	#	use `test`; insert into t2 values (bug27417(2))
+master-bin.000001	#	Query	#	#	BEGIN
+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	#	#	ROLLBACK
 select count(*) from t1 /* must be 3 */;
 count(*)
 3
@@ -787,8 +790,11 @@ count(*)
 2
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Intvar	#	#	INSERT_ID=4
-master-bin.000001	#	Query	#	#	use `test`; delete from t2 where a=bug27417(3)
+master-bin.000001	#	Query	#	#	BEGIN
+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(*)
 5
@@ -810,8 +816,9 @@ ERROR 23000: Duplicate entry '1' 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=1
-master-bin.000001	#	Query	#	#	use `test`; insert into t2 values (bug27417(1))
+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	#	#	ROLLBACK
 select count(*) from t1 /* must be 1 */;
 count(*)
@@ -825,8 +832,10 @@ 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=2
-master-bin.000001	#	Query	#	#	use `test`; insert into t2 select bug27417(1) union select 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: #
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	ROLLBACK
 select count(*) from t1 /* must be 2 */;
 count(*)
@@ -838,8 +847,13 @@ update t3 set b=b+bug27417(1);
 ERROR 23000: Duplicate entry '4' for key 'b'
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Intvar	#	#	INSERT_ID=4
-master-bin.000001	#	Query	#	#	use `test`; update t3 set b=b+bug27417(1)
+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: #
+master-bin.000001	#	Update_rows	#	#	table_id: #
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	ROLLBACK
 select count(*) from t1 /* must be 2 */;
 count(*)
 2
@@ -853,8 +867,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=6
-master-bin.000001	#	Query	#	#	use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t4)
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	ROLLBACK
 select count(*) from t1 /* must be 4 */;
 count(*)
@@ -869,7 +884,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;
@@ -884,8 +899,10 @@ ERROR 23000: Duplicate entry '1' 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=9
-master-bin.000001	#	Query	#	#	use `test`; delete from t2
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+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	#	#	ROLLBACK
 select count(*) from t1 /* must be 1 */;
 count(*)
@@ -904,7 +921,11 @@ ERROR 23000: Duplicate entry '1' 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	#	Query	#	#	use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Delete_rows	#	#	table_id: #
+master-bin.000001	#	Write_rows	#	#	table_id: #
+master-bin.000001	#	Delete_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	ROLLBACK
 select count(*) from t1 /* must be 1 */;
 count(*)
@@ -924,12 +945,11 @@ 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=10
-master-bin.000001	#	User var	#	#	@`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001	#	Begin_load_query	#	#	;file_id=#;block_len=#
-master-bin.000001	#	Intvar	#	#	INSERT_ID=10
-master-bin.000001	#	User var	#	#	@`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
-master-bin.000001	#	Execute_load_query	#	#	use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t4)
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: #
+master-bin.000001	#	Write_rows	#	#	table_id: #
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
 master-bin.000001	#	Query	#	#	ROLLBACK
 drop trigger trg_del_t2;
 drop table t1,t2,t3,t4,t5;

=== 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-20 08:26:13 +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-20 08:26:13 +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-20 08:26:13 +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-20 08:26:13 +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	2009-11-21 11:18:21 +0000
+++ b/sql/event_db_repository.cc	2010-01-20 08:26:13 +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,8 +1053,8 @@ 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->current_stmt_binlog_row_based)
-    thd->clear_current_stmt_binlog_row_based();
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
+  thd->clear_current_stmt_binlog_row_based();
 
   DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL);
 
@@ -1095,6 +1096,8 @@ update_timing_fields_for_event(THD *thd,
 end:
   if (table)
     close_thread_tables(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   DBUG_RETURN(test(ret));
 }

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2009-10-16 10:29:42 +0000
+++ b/sql/events.cc	2010-01-20 08:26:13 +0000
@@ -389,6 +389,7 @@ Events::create_event(THD *thd, Event_par
                      bool if_not_exists)
 {
   int ret;
+  bool save_binlog_row_based;
   DBUG_ENTER("Events::create_event");
 
   /*
@@ -430,8 +431,8 @@ 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->current_stmt_binlog_row_based)
-    thd->clear_current_stmt_binlog_row_based();
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
+  thd->clear_current_stmt_binlog_row_based();
 
   pthread_mutex_lock(&LOCK_event_metadata);
 
@@ -471,6 +472,8 @@ 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 */
+        thd->current_stmt_binlog_row_based= save_binlog_row_based;
         DBUG_RETURN(TRUE);
       }
       /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER 
@@ -479,6 +482,8 @@ Events::create_event(THD *thd, Event_par
     }
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   DBUG_RETURN(ret);
 }
@@ -508,6 +513,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");
@@ -563,8 +569,8 @@ 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->current_stmt_binlog_row_based)
-    thd->clear_current_stmt_binlog_row_based();
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
+  thd->clear_current_stmt_binlog_row_based();
 
   pthread_mutex_lock(&LOCK_event_metadata);
 
@@ -600,6 +606,8 @@ Events::update_event(THD *thd, Event_par
     }
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   DBUG_RETURN(ret);
 }
@@ -633,6 +641,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");
 
   /*
@@ -660,8 +669,8 @@ 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->current_stmt_binlog_row_based)
-    thd->clear_current_stmt_binlog_row_based();
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
+  thd->clear_current_stmt_binlog_row_based();
 
   pthread_mutex_lock(&LOCK_event_metadata);
   /* On error conditions my_error() is called so no need to handle here */
@@ -674,6 +683,8 @@ Events::drop_event(THD *thd, LEX_STRING 
     write_bin_log(thd, TRUE, thd->query(), thd->query_length());
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(ret);
 }
 

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2009-12-02 11:17:08 +0000
+++ b/sql/sp.cc	2010-01-20 08:26:13 +0000
@@ -896,6 +896,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));
@@ -913,6 +915,7 @@ sp_create_routine(THD *thd, int type, sp
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   saved_count_cuted_fields= thd->count_cuted_fields;
@@ -1118,6 +1121,8 @@ done:
   thd->variables.sql_mode= saved_mode;
 
   close_thread_tables(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(ret);
 }
 
@@ -1142,6 +1147,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));
@@ -1154,6 +1160,7 @@ sp_drop_routine(THD *thd, int type, sp_n
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   if (!(table= open_proc_table_for_update(thd)))
@@ -1171,6 +1178,8 @@ sp_drop_routine(THD *thd, int type, sp_n
   }
 
   close_thread_tables(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(ret);
 }
 
@@ -1197,6 +1206,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));
@@ -1208,6 +1218,7 @@ sp_update_routine(THD *thd, int type, sp
     row-based replication. The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   if (!(table= open_proc_table_for_update(thd)))
@@ -1241,6 +1252,8 @@ sp_update_routine(THD *thd, int type, sp
   }
 
   close_thread_tables(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(ret);
 }
 

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-01-13 11:39:00 +0000
+++ b/sql/sql_acl.cc	2010-01-20 08:26:13 +0000
@@ -2978,6 +2978,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)
@@ -3073,6 +3074,7 @@ int mysql_table_grant(THD *thd, TABLE_LI
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
 #ifdef HAVE_REPLICATION
@@ -3088,7 +3090,11 @@ 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 */
+      thd->current_stmt_binlog_row_based= save_binlog_row_based;
       DBUG_RETURN(FALSE);
+    }
   }
 #endif
 
@@ -3101,6 +3107,8 @@ 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 */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(TRUE);				/* purecov: deadcode */
   }
 
@@ -3227,6 +3235,8 @@ 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 */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(result);
 }
 
@@ -3255,6 +3265,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)
@@ -3290,6 +3301,7 @@ bool mysql_routine_grant(THD *thd, TABLE
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
 #ifdef HAVE_REPLICATION
@@ -3305,13 +3317,19 @@ 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 */
+      thd->current_stmt_binlog_row_based= save_binlog_row_based;
       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 */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(TRUE);
   }
 
@@ -3387,6 +3405,8 @@ bool mysql_routine_grant(THD *thd, TABLE
   }
 
   rw_unlock(&LOCK_grant);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   /* Tables are automatically closed */
   DBUG_RETURN(result);
@@ -3401,6 +3421,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)
   {
@@ -3429,6 +3450,7 @@ bool mysql_grant(THD *thd, const char *d
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
 #ifdef HAVE_REPLICATION
@@ -3444,13 +3466,19 @@ 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 */
+      thd->current_stmt_binlog_row_based= save_binlog_row_based;
       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 */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(TRUE);				/* purecov: deadcode */
   }
 
@@ -3510,6 +3538,8 @@ bool mysql_grant(THD *thd, const char *d
 
   if (!result)
     my_ok(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   DBUG_RETURN(result);
 }
@@ -5666,6 +5696,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");
 
   /*
@@ -5673,11 +5704,16 @@ bool mysql_create_user(THD *thd, List <L
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   /* CREATE USER may be skipped on replication client. */
   if ((result= open_grant_tables(thd, tables)))
+  {
+    /* Restore the state of binlog format */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(result != 1);
+  }
 
   rw_wrlock(&LOCK_grant);
   VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -5720,6 +5756,8 @@ bool mysql_create_user(THD *thd, List <L
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(result);
 }
 
@@ -5746,6 +5784,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");
 
   /*
@@ -5753,11 +5792,16 @@ bool mysql_drop_user(THD *thd, List <LEX
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   /* DROP USER may be skipped on replication client. */
   if ((result= open_grant_tables(thd, tables)))
+  {
+    /* Restore the state of binlog format */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(result != 1);
+  }
 
   thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
 
@@ -5794,6 +5838,8 @@ bool mysql_drop_user(THD *thd, List <LEX
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   thd->variables.sql_mode= old_sql_mode;
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(result);
 }
 
@@ -5820,6 +5866,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");
 
   /*
@@ -5827,11 +5874,16 @@ bool mysql_rename_user(THD *thd, List <L
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   /* RENAME USER may be skipped on replication client. */
   if ((result= open_grant_tables(thd, tables)))
+  {
+    /* Restore the state of binlog format */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(result != 1);
+  }
 
   rw_wrlock(&LOCK_grant);
   VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -5878,6 +5930,8 @@ bool mysql_rename_user(THD *thd, List <L
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(result);
 }
 
@@ -5902,6 +5956,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");
 
   /*
@@ -5909,10 +5964,15 @@ bool mysql_revoke_all(THD *thd,  List <L
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   if ((result= open_grant_tables(thd, tables)))
+  {
+    /* Restore the state of binlog format */
+    thd->current_stmt_binlog_row_based= save_binlog_row_based;
     DBUG_RETURN(result != 1);
+  }
 
   rw_wrlock(&LOCK_grant);
   VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -6063,6 +6123,8 @@ bool mysql_revoke_all(THD *thd,  List <L
 
   if (result)
     my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0));
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   DBUG_RETURN(result);
 }
@@ -6146,6 +6208,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)))
@@ -6162,6 +6225,7 @@ bool sp_revoke_privileges(THD *thd, cons
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
   thd->clear_current_stmt_binlog_row_based();
 
   /* Remove procedure access */
@@ -6198,6 +6262,8 @@ bool sp_revoke_privileges(THD *thd, cons
   close_thread_tables(thd);
 
   thd->pop_internal_handler();
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
 
   DBUG_RETURN(error_handler.has_errors());
 }

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2009-10-16 10:29:42 +0000
+++ b/sql/sql_udf.cc	2010-01-20 08:26:13 +0000
@@ -398,6 +398,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)
@@ -437,8 +438,8 @@ 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->current_stmt_binlog_row_based)
-    thd->clear_current_stmt_binlog_row_based();
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
+  thd->clear_current_stmt_binlog_row_based();
 
   rw_wrlock(&THR_LOCK_udf);
   if ((hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length)))
@@ -508,12 +509,16 @@ int mysql_create_function(THD *thd,udf_f
   /* Binlog the create function. */
   write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(0);
 
  err:
   if (new_dl)
     dlclose(dl);
   rw_unlock(&THR_LOCK_udf);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(1);
 }
 
@@ -525,6 +530,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)
@@ -540,8 +546,8 @@ 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->current_stmt_binlog_row_based)
-    thd->clear_current_stmt_binlog_row_based();
+  save_binlog_row_based= thd->current_stmt_binlog_row_based;
+  thd->clear_current_stmt_binlog_row_based();
 
   rw_wrlock(&THR_LOCK_udf);  
   if (!(udf=(udf_func*) hash_search(&udf_hash,(uchar*) udf_name->str,
@@ -583,9 +589,13 @@ int mysql_drop_function(THD *thd,const L
   /* Binlog the drop function. */
   write_bin_log(thd, TRUE, thd->query(), thd->query_length());
 
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(0);
  err:
   rw_unlock(&THR_LOCK_udf);
+  /* Restore the state of binlog format */
+  thd->current_stmt_binlog_row_based= save_binlog_row_based;
   DBUG_RETURN(1);
 }
 


Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20100120082613-vy4uqqw4ymfawp72.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Dao-Gang.Qu:3316) Bug#49132Dao-Gang.Qu20 Jan
  • Re: bzr commit into mysql-5.1-bugteam branch (Dao-Gang.Qu:3316)Bug#49132Libing Song21 Jan