summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/rpl/r/rpl_sf.result47
-rw-r--r--mysql-test/suite/rpl/t/rpl_sf.test121
-rw-r--r--sql/item_func.cc7
-rw-r--r--sql/sp.cc3
-rw-r--r--sql/sp.h3
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
-
/*************************************************************************/
/**
diff --git a/sql/sp.h b/sql/sp.h
index 75c6856f64b..5a190c5480e 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -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