#At file:///home/acorreia/workspace.sun/repository.mysql/bzrwork/bug-41166/mysql-5.1-bugteam/ based on revid:ramil@stripped
3028 Alfranio Correia 2009-07-28
BUG#41166 stored function requires "deterministic" if binlog_format is "statement"
If the log_bin_trust_function_creators option is not defined, creating a stored
function requires either one of the modifiers DETERMINISTIC, NO SQL, or READS
SQL DATA. Executing a stored function should also follows the same rules if in
STATEMENT mode. However, this was not happening and a wrong error was being
printed out: ER_BINLOG_ROW_RBR_TO_SBR.
The patch makes the creation and execution compatible and prints out the correct
error ER_BINLOG_UNSAFE_ROUTINE when a stored function without one of the modifiers
above is executed in STATEMENT mode.
modified:
mysql-test/suite/rpl/r/rpl_sf.result
mysql-test/suite/rpl/t/rpl_sf.test
sql/item_func.cc
sql/sp.cc
sql/sp.h
=== modified file 'mysql-test/suite/rpl/r/rpl_sf.result'
--- a/mysql-test/suite/rpl/r/rpl_sf.result 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_sf.result 2009-07-28 17:44:38 +0000
@@ -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;
=== modified file 'mysql-test/suite/rpl/t/rpl_sf.test'
--- a/mysql-test/suite/rpl/t/rpl_sf.test 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_sf.test 2009-07-28 17:44:38 +0000
@@ -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;
=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc 2009-07-03 10:36:04 +0000
+++ b/sql/item_func.cc 2009-07-28 17:44:38 +0000
@@ -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;
}
=== modified file 'sql/sp.cc'
--- a/sql/sp.cc 2009-05-30 13:32:28 +0000
+++ b/sql/sp.cc 2009-07-28 17:44:38 +0000
@@ -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
-
/*************************************************************************/
/**
=== modified file 'sql/sp.h'
--- a/sql/sp.h 2009-05-29 13:37:54 +0000
+++ b/sql/sp.h 2009-07-28 17:44:38 +0000
@@ -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
Attachment: [text/bzr-bundle]
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (alfranio.correia:3028)Bug#41166 | Alfranio Correia | 28 Jul |