diff options
author | Alexander Nozdrin <alik@sun.com> | 2010-01-30 23:09:31 +0300 |
---|---|---|
committer | Alexander Nozdrin <alik@sun.com> | 2010-01-30 23:09:31 +0300 |
commit | f5386dd087c0c2c9e5032263405bff2403b1b191 (patch) | |
tree | 81e219c792bb0ac78dac1e4685f956c765599271 | |
parent | 706b2c2c8f195485a5fc0e8c5ddfb8876ad92360 (diff) | |
parent | f4517dc68a936fff8d646d67b904f83b2dcc119d (diff) | |
download | mariadb-git-f5386dd087c0c2c9e5032263405bff2403b1b191.tar.gz |
Manual merge from mysql-trunk-merge.
Conflicts:
- sql/event_db_repository.cc
- sql/events.cc
- sql/sp.cc
- sql/sql_acl.cc
- sql/sql_udf.cc
-rw-r--r-- | mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test | 159 | ||||
-rw-r--r-- | mysql-test/r/variables.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result | 90 | ||||
-rw-r--r-- | mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test | 11 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result | 96 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test | 13 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 7 | ||||
-rw-r--r-- | sql/events.cc | 23 | ||||
-rw-r--r-- | sql/sp.cc | 13 | ||||
-rw-r--r-- | sql/sql_acl.cc | 66 | ||||
-rw-r--r-- | sql/sql_udf.cc | 20 |
11 files changed, 487 insertions, 13 deletions
diff --git a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test new file mode 100644 index 00000000000..9cf287281a0 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test @@ -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; + diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index a8737419aa1..a8437961117 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -571,7 +571,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1315 The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored +Note 1315 The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored. This option will be removed in MySQL 5.6. set sql_low_priority_updates=1; set sql_quote_show_create=1; set sql_safe_updates=1; diff --git a/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result b/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result new file mode 100644 index 00000000000..1b0f718ad65 --- /dev/null +++ b/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result @@ -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; diff --git a/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test b/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test new file mode 100644 index 00000000000..748c0ac28e4 --- /dev/null +++ b/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test @@ -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; diff --git a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result new file mode 100644 index 00000000000..5729faa9659 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result @@ -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; diff --git a/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test new file mode 100644 index 00000000000..56924a2efe9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test @@ -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; + diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index a6f249d286f..fd2c5a556a8 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -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->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + thd->clear_current_stmt_binlog_format_row(); DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL); @@ -1095,6 +1096,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)); } diff --git a/sql/events.cc b/sql/events.cc index cc9734d4d20..73f3427607d 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -294,6 +294,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) { int ret; + bool save_binlog_row_based; DBUG_ENTER("Events::create_event"); /* @@ -334,8 +335,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for CREATE EVENT command. */ - if (thd->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + thd->clear_current_stmt_binlog_format_row(); mysql_mutex_lock(&LOCK_event_metadata); @@ -375,6 +376,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, { 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 @@ -383,6 +386,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } } mysql_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -412,6 +417,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, 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"); @@ -465,8 +471,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for UPDATE EVENT command. */ - if (thd->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + thd->clear_current_stmt_binlog_format_row(); mysql_mutex_lock(&LOCK_event_metadata); @@ -502,6 +508,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, } } mysql_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -535,6 +543,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"); /* @@ -561,8 +570,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 that all supporting tables are updated for DROP EVENT command. */ - if (thd->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + thd->clear_current_stmt_binlog_format_row(); mysql_mutex_lock(&LOCK_event_metadata); /* On error conditions my_error() is called so no need to handle here */ @@ -575,6 +584,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } mysql_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } diff --git a/sql/sp.cc b/sql/sp.cc index 9d3527dc4e6..cbc0d003c9f 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -908,6 +908,8 @@ sp_create_routine(THD *thd, int type, sp_head *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)); @@ -925,6 +927,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); saved_count_cuted_fields= thd->count_cuted_fields; @@ -1132,6 +1135,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); } @@ -1156,6 +1161,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) { 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)); @@ -1168,6 +1174,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); if (!(table= open_proc_table_for_update(thd))) @@ -1186,6 +1193,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name) } close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -1212,6 +1221,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) { 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)); @@ -1223,6 +1233,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 statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); if (!(table= open_proc_table_for_update(thd))) @@ -1257,6 +1268,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) } close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8a6413f0e5d..012542a9467 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3023,6 +3023,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, 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) @@ -3118,6 +3119,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); #ifdef HAVE_REPLICATION @@ -3133,7 +3135,11 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, */ 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 @@ -3146,6 +3152,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, 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 */ } @@ -3272,6 +3280,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* 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); } @@ -3300,6 +3310,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, 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) @@ -3335,6 +3346,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 statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); #ifdef HAVE_REPLICATION @@ -3350,13 +3362,19 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, */ 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); } @@ -3433,6 +3451,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, } mysql_rwlock_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); @@ -3447,6 +3467,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, 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) { @@ -3475,6 +3496,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 statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); #ifdef HAVE_REPLICATION @@ -3490,13 +3512,19 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, */ 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 */ } @@ -3556,6 +3584,8 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, if (!result) my_ok(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -5759,6 +5789,7 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) 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"); /* @@ -5766,11 +5797,16 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); /* CREATE USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); @@ -5813,6 +5849,8 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list) mysql_rwlock_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); } @@ -5839,6 +5877,7 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) 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"); /* @@ -5846,11 +5885,16 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); /* DROP USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; @@ -5887,6 +5931,8 @@ bool mysql_drop_user(THD *thd, List <LEX_USER> &list) mysql_rwlock_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); } @@ -5913,6 +5959,7 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) 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"); /* @@ -5920,11 +5967,16 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); /* RENAME USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); @@ -5971,6 +6023,8 @@ bool mysql_rename_user(THD *thd, List <LEX_USER> &list) mysql_rwlock_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); } @@ -5995,6 +6049,7 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) int result; ACL_DB *acl_db; TABLE_LIST tables[GRANT_TABLES]; + bool save_binlog_row_based; DBUG_ENTER("mysql_revoke_all"); /* @@ -6002,10 +6057,15 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } mysql_rwlock_wrlock(&LOCK_grant); mysql_mutex_lock(&acl_cache->lock); @@ -6158,6 +6218,8 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list) /* error for writing binary log has already been reported */ if (result && !binlog_error) my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result || binlog_error); } @@ -6249,6 +6311,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, 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))) @@ -6265,6 +6328,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 statement. */ + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); thd->clear_current_stmt_binlog_format_row(); /* Remove procedure access */ @@ -6301,6 +6365,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, 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()); } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index ff7573b4cfd..57c9110405a 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -421,6 +421,7 @@ int mysql_create_function(THD *thd,udf_func *udf) TABLE *table; TABLE_LIST tables; udf_func *u_d; + bool save_binlog_row_based; DBUG_ENTER("mysql_create_function"); if (!initialized) @@ -460,8 +461,8 @@ int mysql_create_function(THD *thd,udf_func *udf) Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for CREATE FUNCTION command. */ - if (thd->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + thd->clear_current_stmt_binlog_format_row(); mysql_rwlock_wrlock(&THR_LOCK_udf); if ((my_hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length))) @@ -531,12 +532,17 @@ int mysql_create_function(THD *thd,udf_func *udf) /* Binlog the create function. */ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) DBUG_RETURN(1); + + /* 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); mysql_rwlock_unlock(&THR_LOCK_udf); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(1); } @@ -548,6 +554,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) udf_func *udf; char *exact_name_str; uint exact_name_len; + bool save_binlog_row_based; DBUG_ENTER("mysql_drop_function"); if (!initialized) @@ -563,8 +570,8 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for DROP FUNCTION command. */ - if (thd->is_current_stmt_binlog_format_row()) - thd->clear_current_stmt_binlog_format_row(); + save_binlog_row_based= thd->is_current_stmt_binlog_format_row(); + thd->clear_current_stmt_binlog_format_row(); mysql_rwlock_wrlock(&THR_LOCK_udf); if (!(udf=(udf_func*) my_hash_search(&udf_hash,(uchar*) udf_name->str, @@ -606,9 +613,14 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) /* Binlog the drop function. */ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) DBUG_RETURN(1); + + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(0); err: mysql_rwlock_unlock(&THR_LOCK_udf); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(1); } |