diff options
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_sf.result | 47 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_sf.test | 121 | ||||
-rw-r--r-- | sql/item_func.cc | 7 | ||||
-rw-r--r-- | sql/sp.cc | 3 | ||||
-rw-r--r-- | sql/sp.h | 3 |
5 files changed, 174 insertions, 7 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_sf.result b/mysql-test/suite/rpl/r/rpl_sf.result index 46defc6908a..085ba1ebb8a 100644 --- a/mysql-test/suite/rpl/r/rpl_sf.result +++ b/mysql-test/suite/rpl/r/rpl_sf.result @@ -19,5 +19,50 @@ fn16456() timestamp set binlog_format=STATEMENT; select fn16456(); -ERROR HY000: Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events +ERROR HY000: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable) +drop function fn16456; +set global log_bin_trust_function_creators=0; +create function fn16456() +returns int deterministic +begin +return unix_timestamp(); +end| +set binlog_format=ROW; +select fn16456(); +fn16456() +timestamp +set binlog_format=STATEMENT; +select fn16456(); +fn16456() +timestamp +drop function fn16456; +set global log_bin_trust_function_creators=0; +create function fn16456() +returns int no sql +begin +return unix_timestamp(); +end| +set binlog_format=ROW; +select fn16456(); +fn16456() +timestamp +set binlog_format=STATEMENT; +select fn16456(); +fn16456() +timestamp +drop function fn16456; +set global log_bin_trust_function_creators=0; +create function fn16456() +returns int reads sql data +begin +return unix_timestamp(); +end| +set binlog_format=ROW; +select fn16456(); +fn16456() +timestamp +set binlog_format=STATEMENT; +select fn16456(); +fn16456() +timestamp drop function fn16456; diff --git a/mysql-test/suite/rpl/t/rpl_sf.test b/mysql-test/suite/rpl/t/rpl_sf.test index ecf91a723fa..4d12f3839a2 100644 --- a/mysql-test/suite/rpl/t/rpl_sf.test +++ b/mysql-test/suite/rpl/t/rpl_sf.test @@ -1,6 +1,7 @@ -- source include/have_log_bin.inc # Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR +# BUG#41166 stored function requires "deterministic" if binlog_format is "statement" # save status @@ -55,15 +56,131 @@ select fn16456(); set binlog_format=STATEMENT; ---error ER_BINLOG_ROW_RBR_TO_SBR +--error ER_BINLOG_UNSAFE_ROUTINE select fn16456(); -# restore status +# clean + +drop function fn16456; + + + +# success in definition with deterministic + +set global log_bin_trust_function_creators=0; + +delimiter |; +create function fn16456() + returns int deterministic +begin + return unix_timestamp(); +end| +delimiter ;| + + + +# allow funcall in RBR + +set binlog_format=ROW; + +--replace_column 1 timestamp +select fn16456(); + + + +# allow funcall in SBR + +set binlog_format=STATEMENT; + +--replace_column 1 timestamp +select fn16456(); + + + +# clean + +drop function fn16456; + + +# success in definition with NO SQL + +set global log_bin_trust_function_creators=0; + +delimiter |; +create function fn16456() + returns int no sql +begin + return unix_timestamp(); +end| +delimiter ;| + + + +# allow funcall in RBR + +set binlog_format=ROW; + +--replace_column 1 timestamp +select fn16456(); + + + +# allow funcall in SBR + +set binlog_format=STATEMENT; + +--replace_column 1 timestamp +select fn16456(); + + +# clean drop function fn16456; + + +# success in definition with reads sql data + +set global log_bin_trust_function_creators=0; + +delimiter |; +create function fn16456() + returns int reads sql data +begin + return unix_timestamp(); +end| +delimiter ;| + + + +# allow funcall in RBR + +set binlog_format=ROW; + +--replace_column 1 timestamp +select fn16456(); + + + +# allow funcall in SBR + +set binlog_format=STATEMENT; + +--replace_column 1 timestamp +select fn16456(); + + + +# clean + +drop function fn16456; + + + +# restore status + --disable_query_log eval set binlog_format=$oblf; eval set global log_bin_trust_function_creators=$otfc; diff --git a/sql/item_func.cc b/sql/item_func.cc index 0af3c4954cd..55d4b37ddb0 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5990,6 +5990,9 @@ Item_func_sp::execute_impl(THD *thd) #ifndef NO_EMBEDDED_ACCESS_CHECKS Security_context *save_security_ctx= thd->security_ctx; #endif + enum enum_sp_data_access access= + (m_sp->m_chistics->daccess == SP_DEFAULT_ACCESS) ? + SP_DEFAULT_ACCESS_MAPPING : m_sp->m_chistics->daccess; DBUG_ENTER("Item_func_sp::execute_impl"); @@ -6007,11 +6010,13 @@ Item_func_sp::execute_impl(THD *thd) Throw an error if a non-deterministic function is called while statement-based replication (SBR) is active. */ + if (!m_sp->m_chistics->detistic && !trust_function_creators && + (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) && (mysql_bin_log.is_open() && thd->variables.binlog_format == BINLOG_FORMAT_STMT)) { - my_error(ER_BINLOG_ROW_RBR_TO_SBR, MYF(0)); + my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0)); goto error; } diff --git a/sql/sp.cc b/sql/sp.cc index 29e228f5e45..4d840f53e2f 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -70,9 +70,6 @@ enum MYSQL_PROC_FIELD_COUNT }; -/* Tells what SP_DEFAULT_ACCESS should be mapped to */ -#define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL - /*************************************************************************/ /** @@ -17,6 +17,9 @@ #ifndef _SP_H_ #define _SP_H_ +/* Tells what SP_DEFAULT_ACCESS should be mapped to */ +#define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL + // Return codes from sp_create_*, sp_drop_*, and sp_show_*: #define SP_OK 0 #define SP_KEY_NOT_FOUND -1 |