Commit 3cae7d11 authored by unknown's avatar unknown

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.
parent 132b46e9
#
# 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;
...@@ -772,8 +772,11 @@ insert into t2 values (bug27417(2)); ...@@ -772,8 +772,11 @@ insert into t2 values (bug27417(2));
ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=3 master-bin.000001 # Query # # BEGIN
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 # # ROLLBACK
select count(*) from t1 /* must be 3 */; select count(*) from t1 /* must be 3 */;
count(*) count(*)
3 3
...@@ -787,8 +790,11 @@ count(*) ...@@ -787,8 +790,11 @@ count(*)
2 2
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=4 master-bin.000001 # Query # # BEGIN
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 */; select count(*) from t1 /* must be 5 */;
count(*) count(*)
5 5
...@@ -810,8 +816,9 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ...@@ -810,8 +816,9 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=1 master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1)) 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 master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 1 */; select count(*) from t1 /* must be 1 */;
count(*) count(*)
...@@ -825,8 +832,10 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ...@@ -825,8 +832,10 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=2 master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2) 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 master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 2 */; select count(*) from t1 /* must be 2 */;
count(*) count(*)
...@@ -838,8 +847,13 @@ update t3 set b=b+bug27417(1); ...@@ -838,8 +847,13 @@ update t3 set b=b+bug27417(1);
ERROR 23000: Duplicate entry '4' for key 'b' ERROR 23000: Duplicate entry '4' for key 'b'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Intvar # # INSERT_ID=4 master-bin.000001 # Query # # BEGIN
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 # # ROLLBACK
select count(*) from t1 /* must be 2 */; select count(*) from t1 /* must be 2 */;
count(*) count(*)
2 2
...@@ -853,8 +867,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ...@@ -853,8 +867,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=6 master-bin.000001 # Table_map # # table_id: # (test.t4)
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.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # ROLLBACK master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 4 */; select count(*) from t1 /* must be 4 */;
count(*) count(*)
...@@ -869,7 +884,7 @@ UPDATE t3,t4 SET t3.a=t4.a + bug27417(1); ...@@ -869,7 +884,7 @@ UPDATE t3,t4 SET t3.a=t4.a + bug27417(1);
ERROR 23000: Duplicate entry '2' for key 'PRIMARY' ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
select count(*) from t1 /* must be 1 */; select count(*) from t1 /* must be 1 */;
count(*) count(*)
1 2
drop table t4; drop table t4;
delete from t1; delete from t1;
delete from t2; delete from t2;
...@@ -884,8 +899,10 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ...@@ -884,8 +899,10 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=9 master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Query # # use `test`; delete from 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 master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 1 */; select count(*) from t1 /* must be 1 */;
count(*) count(*)
...@@ -904,7 +921,11 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ...@@ -904,7 +921,11 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN 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 master-bin.000001 # Query # # ROLLBACK
select count(*) from t1 /* must be 1 */; select count(*) from t1 /* must be 1 */;
count(*) count(*)
...@@ -924,12 +945,11 @@ count(*) ...@@ -924,12 +945,11 @@ count(*)
show binlog events from <binlog_start>; show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # BEGIN
master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # Table_map # # table_id: # (test.t4)
master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # Write_rows # # table_id: #
master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
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 # Query # # ROLLBACK master-bin.000001 # Query # # ROLLBACK
drop trigger trg_del_t2; drop trigger trg_del_t2;
drop table t1,t2,t3,t4,t5; drop table t1,t2,t3,t4,t5;
......
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;
#
# 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;
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;
#
# 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;
...@@ -1045,6 +1045,7 @@ update_timing_fields_for_event(THD *thd, ...@@ -1045,6 +1045,7 @@ update_timing_fields_for_event(THD *thd,
TABLE *table= NULL; TABLE *table= NULL;
Field **fields; Field **fields;
int ret= 1; int ret= 1;
bool save_binlog_row_based;
DBUG_ENTER("Event_db_repository::update_timing_fields_for_event"); DBUG_ENTER("Event_db_repository::update_timing_fields_for_event");
...@@ -1052,8 +1053,8 @@ update_timing_fields_for_event(THD *thd, ...@@ -1052,8 +1053,8 @@ update_timing_fields_for_event(THD *thd,
Turn off row binlogging of event timing updates. These are not used Turn off row binlogging of event timing updates. These are not used
for RBR of events replicated to the slave. for RBR of events replicated to the slave.
*/ */
if (thd->current_stmt_binlog_row_based) save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL); DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL);
...@@ -1095,6 +1096,8 @@ update_timing_fields_for_event(THD *thd, ...@@ -1095,6 +1096,8 @@ update_timing_fields_for_event(THD *thd,
end: end:
if (table) if (table)
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(test(ret)); DBUG_RETURN(test(ret));
} }
......
...@@ -389,6 +389,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -389,6 +389,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
bool if_not_exists) bool if_not_exists)
{ {
int ret; int ret;
bool save_binlog_row_based;
DBUG_ENTER("Events::create_event"); DBUG_ENTER("Events::create_event");
/* /*
...@@ -431,8 +432,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -431,8 +432,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
Turn off row binlogging of this statement and use statement-based Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE EVENT command. so that all supporting tables are updated for CREATE EVENT command.
*/ */
if (thd->current_stmt_binlog_row_based) save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata); pthread_mutex_lock(&LOCK_event_metadata);
...@@ -472,6 +473,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -472,6 +473,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
{ {
sql_print_error("Event Error: An error occurred while creating query string, " sql_print_error("Event Error: An error occurred while creating query string, "
"before writing it into binary log."); "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); DBUG_RETURN(TRUE);
} }
/* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
...@@ -480,6 +483,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, ...@@ -480,6 +483,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
} }
} }
pthread_mutex_unlock(&LOCK_event_metadata); 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); DBUG_RETURN(ret);
} }
...@@ -509,6 +514,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ...@@ -509,6 +514,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
LEX_STRING *new_dbname, LEX_STRING *new_name) LEX_STRING *new_dbname, LEX_STRING *new_name)
{ {
int ret; int ret;
bool save_binlog_row_based;
Event_queue_element *new_element; Event_queue_element *new_element;
DBUG_ENTER("Events::update_event"); DBUG_ENTER("Events::update_event");
...@@ -565,8 +571,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ...@@ -565,8 +571,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
Turn off row binlogging of this statement and use statement-based Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for UPDATE EVENT command. so that all supporting tables are updated for UPDATE EVENT command.
*/ */
if (thd->current_stmt_binlog_row_based) save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata); pthread_mutex_lock(&LOCK_event_metadata);
...@@ -602,6 +608,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, ...@@ -602,6 +608,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data,
} }
} }
pthread_mutex_unlock(&LOCK_event_metadata); 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); DBUG_RETURN(ret);
} }
...@@ -635,6 +643,7 @@ bool ...@@ -635,6 +643,7 @@ bool
Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
{ {
int ret; int ret;
bool save_binlog_row_based;
DBUG_ENTER("Events::drop_event"); DBUG_ENTER("Events::drop_event");
/* /*
...@@ -662,8 +671,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) ...@@ -662,8 +671,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
Turn off row binlogging of this statement and use statement-based so Turn off row binlogging of this statement and use statement-based so
that all supporting tables are updated for DROP EVENT command. that all supporting tables are updated for DROP EVENT command.
*/ */
if (thd->current_stmt_binlog_row_based) save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
pthread_mutex_lock(&LOCK_event_metadata); pthread_mutex_lock(&LOCK_event_metadata);
/* On error conditions my_error() is called so no need to handle here */ /* On error conditions my_error() is called so no need to handle here */
...@@ -676,6 +685,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) ...@@ -676,6 +685,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists)
write_bin_log(thd, TRUE, thd->query(), thd->query_length()); write_bin_log(thd, TRUE, thd->query(), thd->query_length());
} }
pthread_mutex_unlock(&LOCK_event_metadata); 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); DBUG_RETURN(ret);
} }
......
...@@ -896,6 +896,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) ...@@ -896,6 +896,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
bool store_failed= FALSE; bool store_failed= FALSE;
bool save_binlog_row_based;
DBUG_ENTER("sp_create_routine"); DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length, DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
sp->m_name.str)); sp->m_name.str));
...@@ -913,6 +915,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) ...@@ -913,6 +915,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
saved_count_cuted_fields= thd->count_cuted_fields; saved_count_cuted_fields= thd->count_cuted_fields;
...@@ -1118,6 +1121,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) ...@@ -1118,6 +1121,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
thd->variables.sql_mode= saved_mode; thd->variables.sql_mode= saved_mode;
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
...@@ -1142,6 +1147,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) ...@@ -1142,6 +1147,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
{ {
TABLE *table; TABLE *table;
int ret; int ret;
bool save_binlog_row_based;
DBUG_ENTER("sp_drop_routine"); DBUG_ENTER("sp_drop_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s", DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str)); type, (int) name->m_name.length, name->m_name.str));
...@@ -1154,6 +1160,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) ...@@ -1154,6 +1160,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
if (!(table= open_proc_table_for_update(thd))) if (!(table= open_proc_table_for_update(thd)))
...@@ -1171,6 +1178,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name) ...@@ -1171,6 +1178,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
} }
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
...@@ -1197,6 +1206,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) ...@@ -1197,6 +1206,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
{ {
TABLE *table; TABLE *table;
int ret; int ret;
bool save_binlog_row_based;
DBUG_ENTER("sp_update_routine"); DBUG_ENTER("sp_update_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s", DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str)); type, (int) name->m_name.length, name->m_name.str));
...@@ -1208,6 +1218,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) ...@@ -1208,6 +1218,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
if (!(table= open_proc_table_for_update(thd))) if (!(table= open_proc_table_for_update(thd)))
...@@ -1241,6 +1252,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) ...@@ -1241,6 +1252,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
} }
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(ret); DBUG_RETURN(ret);
} }
......
...@@ -2978,6 +2978,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -2978,6 +2978,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
TABLE_LIST tables[3]; TABLE_LIST tables[3];
bool create_new_users=0; bool create_new_users=0;
char *db_name, *table_name; char *db_name, *table_name;
bool save_binlog_row_based;
DBUG_ENTER("mysql_table_grant"); DBUG_ENTER("mysql_table_grant");
if (!initialized) if (!initialized)
...@@ -3073,6 +3074,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -3073,6 +3074,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
...@@ -3088,7 +3090,11 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -3088,7 +3090,11 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
*/ */
tables[0].updating= tables[1].updating= tables[2].updating= 1; tables[0].updating= tables[1].updating= tables[2].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) 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); DBUG_RETURN(FALSE);
}
} }
#endif #endif
...@@ -3101,6 +3107,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -3101,6 +3107,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (simple_open_n_lock_tables(thd,tables)) if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen { // Should never happen
close_thread_tables(thd); /* purecov: deadcode */ 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 */ DBUG_RETURN(TRUE); /* purecov: deadcode */
} }
...@@ -3227,6 +3235,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, ...@@ -3227,6 +3235,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
/* Tables are automatically closed */ /* Tables are automatically closed */
thd->lex->restore_backup_query_tables_list(&backup); 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); DBUG_RETURN(result);
} }
...@@ -3255,6 +3265,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -3255,6 +3265,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
TABLE_LIST tables[2]; TABLE_LIST tables[2];
bool create_new_users=0, result=0; bool create_new_users=0, result=0;
char *db_name, *table_name; char *db_name, *table_name;
bool save_binlog_row_based;
DBUG_ENTER("mysql_routine_grant"); DBUG_ENTER("mysql_routine_grant");
if (!initialized) if (!initialized)
...@@ -3290,6 +3301,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -3290,6 +3301,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
...@@ -3305,13 +3317,19 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -3305,13 +3317,19 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
*/ */
tables[0].updating= tables[1].updating= 1; tables[0].updating= tables[1].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) 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); DBUG_RETURN(FALSE);
}
} }
#endif #endif
if (simple_open_n_lock_tables(thd,tables)) if (simple_open_n_lock_tables(thd,tables))
{ // Should never happen { // Should never happen
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
...@@ -3387,6 +3405,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, ...@@ -3387,6 +3405,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
} }
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
/* Tables are automatically closed */ /* Tables are automatically closed */
DBUG_RETURN(result); DBUG_RETURN(result);
...@@ -3401,6 +3421,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, ...@@ -3401,6 +3421,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
char tmp_db[NAME_LEN+1]; char tmp_db[NAME_LEN+1];
bool create_new_users=0; bool create_new_users=0;
TABLE_LIST tables[2]; TABLE_LIST tables[2];
bool save_binlog_row_based;
DBUG_ENTER("mysql_grant"); DBUG_ENTER("mysql_grant");
if (!initialized) if (!initialized)
{ {
...@@ -3429,6 +3450,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, ...@@ -3429,6 +3450,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
...@@ -3444,13 +3466,19 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, ...@@ -3444,13 +3466,19 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
*/ */
tables[0].updating= tables[1].updating= 1; tables[0].updating= tables[1].updating= 1;
if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) 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); DBUG_RETURN(FALSE);
}
} }
#endif #endif
if (simple_open_n_lock_tables(thd,tables)) if (simple_open_n_lock_tables(thd,tables))
{ // This should never happen { // This should never happen
close_thread_tables(thd); /* purecov: deadcode */ 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 */ DBUG_RETURN(TRUE); /* purecov: deadcode */
} }
...@@ -3510,6 +3538,8 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, ...@@ -3510,6 +3538,8 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
if (!result) if (!result)
my_ok(thd); my_ok(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -5666,6 +5696,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) ...@@ -5666,6 +5696,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
List_iterator <LEX_USER> user_list(list); List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
bool some_users_created= FALSE; bool some_users_created= FALSE;
bool save_binlog_row_based;
DBUG_ENTER("mysql_create_user"); DBUG_ENTER("mysql_create_user");
/* /*
...@@ -5673,11 +5704,16 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) ...@@ -5673,11 +5704,16 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
/* CREATE USER may be skipped on replication client. */ /* CREATE USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables))) 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); DBUG_RETURN(result != 1);
}
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
...@@ -5720,6 +5756,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) ...@@ -5720,6 +5756,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -5746,6 +5784,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5746,6 +5784,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
bool some_users_deleted= FALSE; bool some_users_deleted= FALSE;
ulong old_sql_mode= thd->variables.sql_mode; ulong old_sql_mode= thd->variables.sql_mode;
bool save_binlog_row_based;
DBUG_ENTER("mysql_drop_user"); DBUG_ENTER("mysql_drop_user");
/* /*
...@@ -5753,11 +5792,16 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5753,11 +5792,16 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
/* DROP USER may be skipped on replication client. */ /* DROP USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables))) 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); DBUG_RETURN(result != 1);
}
thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH;
...@@ -5794,6 +5838,8 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) ...@@ -5794,6 +5838,8 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
close_thread_tables(thd); close_thread_tables(thd);
thd->variables.sql_mode= old_sql_mode; 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); DBUG_RETURN(result);
} }
...@@ -5820,6 +5866,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) ...@@ -5820,6 +5866,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
List_iterator <LEX_USER> user_list(list); List_iterator <LEX_USER> user_list(list);
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
bool some_users_renamed= FALSE; bool some_users_renamed= FALSE;
bool save_binlog_row_based;
DBUG_ENTER("mysql_rename_user"); DBUG_ENTER("mysql_rename_user");
/* /*
...@@ -5827,11 +5874,16 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) ...@@ -5827,11 +5874,16 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
/* RENAME USER may be skipped on replication client. */ /* RENAME USER may be skipped on replication client. */
if ((result= open_grant_tables(thd, tables))) 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); DBUG_RETURN(result != 1);
}
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
...@@ -5878,6 +5930,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) ...@@ -5878,6 +5930,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list)
rw_unlock(&LOCK_grant); rw_unlock(&LOCK_grant);
close_thread_tables(thd); close_thread_tables(thd);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -5902,6 +5956,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -5902,6 +5956,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
int result; int result;
ACL_DB *acl_db; ACL_DB *acl_db;
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
bool save_binlog_row_based;
DBUG_ENTER("mysql_revoke_all"); DBUG_ENTER("mysql_revoke_all");
/* /*
...@@ -5909,10 +5964,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -5909,10 +5964,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
if ((result= open_grant_tables(thd, tables))) 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); DBUG_RETURN(result != 1);
}
rw_wrlock(&LOCK_grant); rw_wrlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock)); VOID(pthread_mutex_lock(&acl_cache->lock));
...@@ -6063,6 +6123,8 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) ...@@ -6063,6 +6123,8 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
if (result) if (result)
my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); 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); DBUG_RETURN(result);
} }
...@@ -6146,6 +6208,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -6146,6 +6208,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
TABLE_LIST tables[GRANT_TABLES]; TABLE_LIST tables[GRANT_TABLES];
HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash;
Silence_routine_definer_errors error_handler; Silence_routine_definer_errors error_handler;
bool save_binlog_row_based;
DBUG_ENTER("sp_revoke_privileges"); DBUG_ENTER("sp_revoke_privileges");
if ((result= open_grant_tables(thd, tables))) if ((result= open_grant_tables(thd, tables)))
...@@ -6162,6 +6225,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -6162,6 +6225,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
row-based replication. The flag will be reset at the end of the row-based replication. The flag will be reset at the end of the
statement. statement.
*/ */
save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
/* Remove procedure access */ /* Remove procedure access */
...@@ -6198,6 +6262,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, ...@@ -6198,6 +6262,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name,
close_thread_tables(thd); close_thread_tables(thd);
thd->pop_internal_handler(); 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()); DBUG_RETURN(error_handler.has_errors());
} }
......
...@@ -398,6 +398,7 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -398,6 +398,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
TABLE *table; TABLE *table;
TABLE_LIST tables; TABLE_LIST tables;
udf_func *u_d; udf_func *u_d;
bool save_binlog_row_based;
DBUG_ENTER("mysql_create_function"); DBUG_ENTER("mysql_create_function");
if (!initialized) if (!initialized)
...@@ -437,8 +438,8 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -437,8 +438,8 @@ int mysql_create_function(THD *thd,udf_func *udf)
Turn off row binlogging of this statement and use statement-based Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for CREATE FUNCTION command. so that all supporting tables are updated for CREATE FUNCTION command.
*/ */
if (thd->current_stmt_binlog_row_based) save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
rw_wrlock(&THR_LOCK_udf); rw_wrlock(&THR_LOCK_udf);
if ((hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length))) if ((hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length)))
...@@ -508,12 +509,16 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -508,12 +509,16 @@ int mysql_create_function(THD *thd,udf_func *udf)
/* Binlog the create function. */ /* Binlog the create function. */
write_bin_log(thd, TRUE, thd->query(), thd->query_length()); 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); DBUG_RETURN(0);
err: err:
if (new_dl) if (new_dl)
dlclose(dl); dlclose(dl);
rw_unlock(&THR_LOCK_udf); rw_unlock(&THR_LOCK_udf);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -525,6 +530,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) ...@@ -525,6 +530,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
udf_func *udf; udf_func *udf;
char *exact_name_str; char *exact_name_str;
uint exact_name_len; uint exact_name_len;
bool save_binlog_row_based;
DBUG_ENTER("mysql_drop_function"); DBUG_ENTER("mysql_drop_function");
if (!initialized) if (!initialized)
...@@ -540,8 +546,8 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) ...@@ -540,8 +546,8 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
Turn off row binlogging of this statement and use statement-based Turn off row binlogging of this statement and use statement-based
so that all supporting tables are updated for DROP FUNCTION command. so that all supporting tables are updated for DROP FUNCTION command.
*/ */
if (thd->current_stmt_binlog_row_based) save_binlog_row_based= thd->current_stmt_binlog_row_based;
thd->clear_current_stmt_binlog_row_based(); thd->clear_current_stmt_binlog_row_based();
rw_wrlock(&THR_LOCK_udf); rw_wrlock(&THR_LOCK_udf);
if (!(udf=(udf_func*) hash_search(&udf_hash,(uchar*) udf_name->str, if (!(udf=(udf_func*) hash_search(&udf_hash,(uchar*) udf_name->str,
...@@ -583,9 +589,13 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) ...@@ -583,9 +589,13 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
/* Binlog the drop function. */ /* Binlog the drop function. */
write_bin_log(thd, TRUE, thd->query(), thd->query_length()); 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); DBUG_RETURN(0);
err: err:
rw_unlock(&THR_LOCK_udf); rw_unlock(&THR_LOCK_udf);
/* Restore the state of binlog format */
thd->current_stmt_binlog_row_based= save_binlog_row_based;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment