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.
This commit is contained in:
parent
422696d673
commit
043e09b543
@ -19,5 +19,50 @@ fn16456()
|
|||||||
timestamp
|
timestamp
|
||||||
set binlog_format=STATEMENT;
|
set binlog_format=STATEMENT;
|
||||||
select fn16456();
|
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;
|
drop function fn16456;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
-- source include/have_log_bin.inc
|
-- source include/have_log_bin.inc
|
||||||
|
|
||||||
# Bug#16456 RBR: rpl_sp.test expects query to fail, but passes in RBR
|
# 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
|
# save status
|
||||||
|
|
||||||
@ -55,15 +56,131 @@ select fn16456();
|
|||||||
|
|
||||||
set binlog_format=STATEMENT;
|
set binlog_format=STATEMENT;
|
||||||
|
|
||||||
--error ER_BINLOG_ROW_RBR_TO_SBR
|
--error ER_BINLOG_UNSAFE_ROUTINE
|
||||||
select fn16456();
|
select fn16456();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 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
|
# restore status
|
||||||
|
|
||||||
drop function fn16456;
|
|
||||||
|
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
eval set binlog_format=$oblf;
|
eval set binlog_format=$oblf;
|
||||||
eval set global log_bin_trust_function_creators=$otfc;
|
eval set global log_bin_trust_function_creators=$otfc;
|
||||||
|
@ -5990,6 +5990,9 @@ Item_func_sp::execute_impl(THD *thd)
|
|||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
Security_context *save_security_ctx= thd->security_ctx;
|
Security_context *save_security_ctx= thd->security_ctx;
|
||||||
#endif
|
#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");
|
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
|
Throw an error if a non-deterministic function is called while
|
||||||
statement-based replication (SBR) is active.
|
statement-based replication (SBR) is active.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!m_sp->m_chistics->detistic && !trust_function_creators &&
|
if (!m_sp->m_chistics->detistic && !trust_function_creators &&
|
||||||
|
(access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) &&
|
||||||
(mysql_bin_log.is_open() &&
|
(mysql_bin_log.is_open() &&
|
||||||
thd->variables.binlog_format == BINLOG_FORMAT_STMT))
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,9 +70,6 @@ enum
|
|||||||
MYSQL_PROC_FIELD_COUNT
|
MYSQL_PROC_FIELD_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Tells what SP_DEFAULT_ACCESS should be mapped to */
|
|
||||||
#define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
3
sql/sp.h
3
sql/sp.h
@ -17,6 +17,9 @@
|
|||||||
#ifndef _SP_H_
|
#ifndef _SP_H_
|
||||||
#define _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_*:
|
// Return codes from sp_create_*, sp_drop_*, and sp_show_*:
|
||||||
#define SP_OK 0
|
#define SP_OK 0
|
||||||
#define SP_KEY_NOT_FOUND -1
|
#define SP_KEY_NOT_FOUND -1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user