Commit ff46e549 authored by guilhem@mysql.com's avatar guilhem@mysql.com

WL#2971 "change log-bin-trust-routine-creators=0 to apply only to functions".

Indeed now that stored procedures CALL is not binlogged, but instead the invoked substatements are,
the restrictions applied by log-bin-trust-routine-creators=0 are superfluous for procedures.
They still need to apply to functions where function calls are written to the binlog (for example as "DO myfunc(3)").
We rename the variable to log-bin-trust-function-creators but allow the old name until some future version (and issue a warning if old name is used).
parent 1379dd18
...@@ -2008,7 +2008,7 @@ sub mysqld_arguments ($$$$$) { ...@@ -2008,7 +2008,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir); mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir);
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir); mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
mtr_add_arg($args, "%s--core", $prefix); mtr_add_arg($args, "%s--core", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-routine-creators", $prefix); mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix); mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
...@@ -2131,7 +2131,7 @@ sub mysqld_arguments ($$$$$) { ...@@ -2131,7 +2131,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix); mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix);
mtr_add_arg($args, "%s--sort_buffer=256K", $prefix); mtr_add_arg($args, "%s--sort_buffer=256K", $prefix);
mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix); mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-routine-creators", $prefix); mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
if ( $opt_ssl_supported ) if ( $opt_ssl_supported )
{ {
......
...@@ -1275,7 +1275,7 @@ start_master() ...@@ -1275,7 +1275,7 @@ start_master()
--language=$LANGUAGE \ --language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \ --innodb_data_file_path=ibdata1:128M:autoextend \
--open-files-limit=1024 \ --open-files-limit=1024 \
--log-bin-trust-routine-creators \ --log-bin-trust-function-creators \
$MASTER_40_ARGS \ $MASTER_40_ARGS \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
...@@ -1296,7 +1296,7 @@ start_master() ...@@ -1296,7 +1296,7 @@ start_master()
--tmpdir=$MYSQL_TMP_DIR \ --tmpdir=$MYSQL_TMP_DIR \
--language=$LANGUAGE \ --language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \ --innodb_data_file_path=ibdata1:128M:autoextend \
--log-bin-trust-routine-creators \ --log-bin-trust-function-creators \
$MASTER_40_ARGS \ $MASTER_40_ARGS \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \ $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
...@@ -1429,7 +1429,7 @@ start_slave() ...@@ -1429,7 +1429,7 @@ start_slave()
--report-port=$slave_port \ --report-port=$slave_port \
--master-retry-count=10 \ --master-retry-count=10 \
-O slave_net_timeout=10 \ -O slave_net_timeout=10 \
--log-bin-trust-routine-creators \ --log-bin-trust-function-creators \
$SMALL_SERVER \ $SMALL_SERVER \
$EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT" $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
CUR_MYERR=$slave_err CUR_MYERR=$slave_err
......
...@@ -486,7 +486,7 @@ void start_master() ...@@ -486,7 +486,7 @@ void start_master()
#endif #endif
add_arg(&al, "--local-infile"); add_arg(&al, "--local-infile");
add_arg(&al, "--core"); add_arg(&al, "--core");
add_arg(&al, "--log-bin-trust-routine-creators"); add_arg(&al, "--log-bin-trust-function-creators");
add_arg(&al, "--datadir=%s", master_dir); add_arg(&al, "--datadir=%s", master_dir);
#ifndef __WIN__ #ifndef __WIN__
add_arg(&al, "--pid-file=%s", master_pid); add_arg(&al, "--pid-file=%s", master_pid);
......
This diff is collapsed.
--log_bin_trust_routine_creators=0 --log_bin_trust_routine_creators=0 --slave-skip-errors=1062
# Test of replication of stored procedures (WL#2146 for MySQL 5.0) # Test of replication of stored procedures (WL#2146 for MySQL 5.0)
# Modified by WL#2971.
# Note that in the .opt files we still use the old variable name
# log-bin-trust-routine-creators so that this test checks that it's
# still accepted (this test also checks that the new name is
# accepted). The old name could be removed in 5.1 or 6.0.
source include/master-slave.inc; source include/master-slave.inc;
# First let's test replication of current_user() (that's a related thing)
# we need a db != test, where we don't have automatic grants # we need a db != test, where we don't have automatic grants
create database if not exists mysqltest1; --disable_warnings
drop database if exists mysqltest1;
--enable_warnings
create database mysqltest1;
use mysqltest1; use mysqltest1;
create table t1 (a varchar(100)); create table t1 (a varchar(100));
sync_slave_with_master; sync_slave_with_master;
...@@ -16,30 +24,15 @@ use mysqltest1; ...@@ -16,30 +24,15 @@ use mysqltest1;
# (same definer, same properties...) # (same definer, same properties...)
connection master; connection master;
# cleanup
--disable_warnings
drop procedure if exists foo;
drop procedure if exists foo2;
drop procedure if exists foo3;
drop procedure if exists foo4;
drop procedure if exists bar;
drop function if exists fn1;
--enable_warnings
delimiter |; delimiter |;
--error 1418 # not deterministic
create procedure foo()
begin
declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end|
--replace_column 2 # 5 # # Stored procedures don't have the limitations that functions have
show binlog events from 98| # check that not there # regarding binlogging: it's ok to create a procedure as not
# deterministic and updating data, while it's not ok to create such a
# function. We test this.
create procedure foo() deterministic create procedure foo()
begin begin
declare b int; declare b int;
set b = 8; set b = 8;
...@@ -54,38 +47,29 @@ delimiter ;| ...@@ -54,38 +47,29 @@ delimiter ;|
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
sync_slave_with_master; sync_slave_with_master;
# You will notice in the result that the definer does not match what
# it is on master, it is a known bug on which Alik is working
--replace_result localhost.localdomain localhost 127.0.0.1 localhost --replace_result localhost.localdomain localhost 127.0.0.1 localhost
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
# Now when we call it, does the CALL() get into binlog,
# or the substatements?
connection master; connection master;
# see if timestamp used in SP on slave is same as on master # see if timestamp used in SP on slave is same as on master
set timestamp=1000000000; set timestamp=1000000000;
call foo(); call foo();
--replace_column 2 # 5 #
show binlog events from 308;
select * from t1; select * from t1;
sync_slave_with_master; sync_slave_with_master;
select * from t1; select * from t1;
# Now a SP which is supposed to not update tables (CALL should not be # Now a SP which is not updating tables
# binlogged) as it's "read sql data", so should not give error even if
# non-deterministic.
connection master; connection master;
delete from t1; delete from t1;
create procedure foo2() create procedure foo2()
not deterministic
reads sql data
select * from mysqltest1.t1; select * from mysqltest1.t1;
call foo2(); call foo2();
# verify CALL is not in binlog
--replace_column 2 # 5 #
show binlog events from 518;
--error 1418 # check that this is allowed (it's not for functions):
alter procedure foo2 contains sql; alter procedure foo2 contains sql;
# SP with definer's right # SP with definer's right
...@@ -106,15 +90,7 @@ grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; ...@@ -106,15 +90,7 @@ grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,); connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,);
connection con1; connection con1;
--error 1419 # only full-global-privs user can create a routine # this routine will fail in the second INSERT because of privileges
create procedure foo4()
deterministic
insert into t1 values (10);
connection master;
set global log_bin_trust_routine_creators=1;
connection con1;
delimiter |; delimiter |;
create procedure foo4() create procedure foo4()
deterministic deterministic
...@@ -128,29 +104,22 @@ delimiter ;| ...@@ -128,29 +104,22 @@ delimiter ;|
# I add ,0 so that it does not print the error in the test output, # I add ,0 so that it does not print the error in the test output,
# because this error is hostname-dependent # because this error is hostname-dependent
--error 1142,0 --error 1142,0
call foo4(); # invoker has no INSERT grant on table => failure call foo4(); # invoker has no INSERT grant on table t1 => failure
show warnings;
connection master; connection master;
call foo3(); # success (definer == root) call foo3(); # success (definer == root)
show warnings; show warnings;
--replace_result localhost.localdomain localhost 127.0.0.1 localhost
--error 1142,0 --error 1142,0
call foo4(); # definer's rights => failure call foo4(); # definer's rights => failure
show warnings;
# we test replication of ALTER PROCEDURE # we test replication of ALTER PROCEDURE
alter procedure foo4 sql security invoker; alter procedure foo4 sql security invoker;
call foo4(); # invoker's rights => success call foo4(); # invoker's rights => success
show warnings; show warnings;
# Check that only successful CALLs are in binlog # Note that half-failed procedure calls are ok with binlogging;
--replace_column 2 # 5 # # if we compare t2 on master and slave we see they are identical:
show binlog events from 990;
# Note that half-failed CALLs are not in binlog, which is a known
# bug. If we compare t2 on master and slave we see they differ:
select * from t1; select * from t1;
select * from t2; select * from t2;
...@@ -158,6 +127,30 @@ sync_slave_with_master; ...@@ -158,6 +127,30 @@ sync_slave_with_master;
select * from t1; select * from t1;
select * from t2; select * from t2;
# Let's check another failing-in-the-middle procedure
connection master;
delete from t2;
alter table t2 add unique (a);
drop procedure foo4;
delimiter |;
create procedure foo4()
deterministic
begin
insert into t2 values(20),(20);
end|
delimiter ;|
--error 1062
call foo4();
show warnings;
select * from t2;
sync_slave_with_master;
# check that this failed-in-the-middle replicated right:
select * from t2;
# Test of DROP PROCEDURE # Test of DROP PROCEDURE
--replace_result localhost.localdomain localhost 127.0.0.1 localhost --replace_result localhost.localdomain localhost 127.0.0.1 localhost
...@@ -177,6 +170,14 @@ drop procedure foo2; ...@@ -177,6 +170,14 @@ drop procedure foo2;
drop procedure foo3; drop procedure foo3;
delimiter |; delimiter |;
# check that needs "deterministic"
--error 1418
create function fn1(x int)
returns int
begin
insert into t1 values (x);
return x+2;
end|
create function fn1(x int) create function fn1(x int)
returns int returns int
deterministic deterministic
...@@ -202,15 +203,69 @@ drop function fn1; ...@@ -202,15 +203,69 @@ drop function fn1;
create function fn1() create function fn1()
returns int returns int
deterministic no sql
begin begin
return unix_timestamp(); return unix_timestamp();
end| end|
delimiter ;| delimiter ;|
# check that needs "deterministic"
--error 1418
alter function fn1 contains sql;
delete from t1; delete from t1;
set timestamp=1000000000; set timestamp=1000000000;
insert into t1 values(fn1()); insert into t1 values(fn1());
connection con1;
delimiter |;
--error 1419 # only full-global-privs user can create a function
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
delimiter ;|
connection master;
# test old variable name:
set global log_bin_trust_routine_creators=1;
# now use new name:
set global log_bin_trust_function_creators=0;
set global log_bin_trust_function_creators=1;
# slave needs it too otherwise will not execute what master allowed:
connection slave;
set global log_bin_trust_function_creators=1;
connection con1;
delimiter |;
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
delimiter ;|
connection master;
# Now a function which is supposed to not update tables
# as it's "reads sql data", so should not give error even if
# non-deterministic.
delimiter |;
create function fn3()
returns int
not deterministic
reads sql data
begin
return 0;
end|
delimiter ;|
select fn3();
--replace_result localhost.localdomain localhost 127.0.0.1 localhost --replace_result localhost.localdomain localhost 127.0.0.1 localhost
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
...@@ -223,18 +278,43 @@ select * from t1; ...@@ -223,18 +278,43 @@ select * from t1;
--replace_column 13 # 14 # --replace_column 13 # 14 #
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
# And now triggers # Let's check a failing-in-the-middle function
connection master;
delete from t2;
alter table t2 add unique (a);
drop function fn1;
delimiter |;
create function fn1()
returns int
begin
insert into t2 values(20),(20);
return 10;
end|
delimiter ;|
# Because of BUG#14769 the following statement requires that we start
# slave with --slave-skip-errors=1062. When that bug is fixed, that
# option can be removed.
--error 1062
select fn1();
select * from t2;
sync_slave_with_master;
# check that this failed-in-the-middle replicated right:
select * from t2;
# ********************** PART 3 : TRIGGERS ***************
connection con1; connection con1;
--error 1227 --error 1227
create trigger trg before insert on t1 for each row set new.a= 10; create trigger trg before insert on t1 for each row set new.a= 10;
connection master; connection master;
# fn1() above uses timestamps, so in !ps-protocol, the timezone will be
# binlogged, but in --ps-protocol it will not be (BUG#9359) so
# the binlog offsets get shifted which spoils SHOW BINLOG EVENTS.
# To be immune, we take a new binlog.
flush logs;
delete from t1; delete from t1;
# TODO: when triggers can contain an update, test that this update # TODO: when triggers can contain an update, test that this update
# does not go into binlog. # does not go into binlog.
...@@ -253,7 +333,7 @@ drop trigger trg; ...@@ -253,7 +333,7 @@ drop trigger trg;
insert into t1 values (1); insert into t1 values (1);
select * from t1; select * from t1;
--replace_column 2 # 5 # --replace_column 2 # 5 #
show binlog events in 'master-bin.000002' from 98; show binlog events in 'master-bin.000001' from 98;
sync_slave_with_master; sync_slave_with_master;
select * from t1; select * from t1;
......
...@@ -4775,12 +4775,6 @@ Item_func_sp::execute(Item **itp) ...@@ -4775,12 +4775,6 @@ Item_func_sp::execute(Item **itp)
res= m_sp->execute_function(thd, args, arg_count, itp); res= m_sp->execute_function(thd, args, arg_count, itp);
thd->restore_sub_statement_state(&statement_state); thd->restore_sub_statement_state(&statement_state);
if (res && mysql_bin_log.is_open() &&
(m_sp->m_chistics->daccess == SP_CONTAINS_SQL ||
m_sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_ctx_func); sp_restore_security_context(thd, save_ctx_func);
error: error:
......
...@@ -1180,7 +1180,7 @@ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs; ...@@ -1180,7 +1180,7 @@ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth; extern my_bool opt_secure_auth;
extern my_bool opt_log_slow_admin_statements; extern my_bool opt_log_slow_admin_statements;
extern my_bool sp_automatic_privileges, opt_noacl; extern my_bool sp_automatic_privileges, opt_noacl;
extern my_bool opt_old_style_user_limits, trust_routine_creators; extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb; extern uint opt_crash_binlog_innodb;
extern char *shared_memory_base_name, *mysqld_unix_port; extern char *shared_memory_base_name, *mysqld_unix_port;
extern my_bool opt_enable_shared_memory; extern my_bool opt_enable_shared_memory;
......
...@@ -371,7 +371,7 @@ my_bool opt_log_slow_admin_statements= 0; ...@@ -371,7 +371,7 @@ my_bool opt_log_slow_admin_statements= 0;
my_bool lower_case_file_system= 0; my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0; my_bool opt_large_pages= 0;
uint opt_large_page_size= 0; uint opt_large_page_size= 0;
my_bool opt_old_style_user_limits= 0, trust_routine_creators= 0; my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
/* /*
True if there is at least one per-hour limit for some user, so we should True if there is at least one per-hour limit for some user, so we should
check them before each query (and possibly reset counters when hour is check them before each query (and possibly reset counters when hour is
...@@ -4432,7 +4432,7 @@ enum options_mysqld ...@@ -4432,7 +4432,7 @@ enum options_mysqld
OPT_INNODB_FAST_SHUTDOWN, OPT_INNODB_FAST_SHUTDOWN,
OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB, OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB,
OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
OPT_LOG_BIN_TRUST_ROUTINE_CREATORS, OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG,
OPT_INNODB, OPT_ISAM, OPT_INNODB, OPT_ISAM,
OPT_ENGINE_CONDITION_PUSHDOWN, OPT_ENGINE_CONDITION_PUSHDOWN,
...@@ -4857,16 +4857,27 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, ...@@ -4857,16 +4857,27 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
"File that holds the names for last binary log files.", "File that holds the names for last binary log files.",
(gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
/*
In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
log-bin-trust-function-creators but kept also the old name for
compatibility; the behaviour was also changed to apply only to functions
(and triggers). In a future release this old name could be removed.
*/
{"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"(deprecated) Use log-bin-trust-function-creators.",
(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
/* /*
This option starts with "log-bin" to emphasize that it is specific of This option starts with "log-bin" to emphasize that it is specific of
binary logging. Hopefully in 5.1 nobody will need it anymore, when we have binary logging.
row-level binlog.
*/ */
{"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_ROUTINE_CREATORS, {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"If equal to 0 (the default), then when --log-bin is used, creation of " "If equal to 0 (the default), then when --log-bin is used, creation of "
"a routine is allowed only to users having the SUPER privilege and only" "a function is allowed only to users having the SUPER privilege and only "
"if this routine may not break binary logging", "if this function may not break binary logging.",
(gptr*) &trust_routine_creators, (gptr*) &trust_routine_creators, 0, (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-error", OPT_ERROR_LOG_FILE, "Error log file.", {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
(gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR,
...@@ -5725,7 +5736,7 @@ The minimum value for this variable is 4096.", ...@@ -5725,7 +5736,7 @@ The minimum value for this variable is 4096.",
(gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG, (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0}, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
{"read_only", OPT_READONLY, {"read_only", OPT_READONLY,
"Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege", "Make all non-temporary tables read-only, with the exception for replication (slave) threads and users with the SUPER privilege",
(gptr*) &opt_readonly, (gptr*) &opt_readonly,
(gptr*) &opt_readonly, (gptr*) &opt_readonly,
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
......
...@@ -200,9 +200,12 @@ sys_var_key_cache_long sys_key_cache_age_threshold("key_cache_age_threshold", ...@@ -200,9 +200,12 @@ sys_var_key_cache_long sys_key_cache_age_threshold("key_cache_age_threshold",
param_age_threshold)); param_age_threshold));
sys_var_bool_ptr sys_local_infile("local_infile", sys_var_bool_ptr sys_local_infile("local_infile",
&opt_local_infile); &opt_local_infile);
sys_var_bool_ptr sys_var_trust_routine_creators
sys_trust_routine_creators("log_bin_trust_routine_creators", sys_trust_routine_creators("log_bin_trust_routine_creators",
&trust_routine_creators); &trust_function_creators);
sys_var_bool_ptr
sys_trust_function_creators("log_bin_trust_function_creators",
&trust_function_creators);
sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings); sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings);
sys_var_thd_ulong sys_long_query_time("long_query_time", sys_var_thd_ulong sys_long_query_time("long_query_time",
&SV::long_query_time); &SV::long_query_time);
...@@ -722,6 +725,7 @@ sys_var *sys_variables[]= ...@@ -722,6 +725,7 @@ sys_var *sys_variables[]=
&sys_innodb_commit_concurrency, &sys_innodb_commit_concurrency,
#endif #endif
&sys_trust_routine_creators, &sys_trust_routine_creators,
&sys_trust_function_creators,
&sys_engine_condition_pushdown, &sys_engine_condition_pushdown,
#ifdef HAVE_NDBCLUSTER_DB #ifdef HAVE_NDBCLUSTER_DB
&sys_ndb_autoincrement_prefetch_sz, &sys_ndb_autoincrement_prefetch_sz,
...@@ -865,7 +869,7 @@ struct show_var_st init_vars[]= { ...@@ -865,7 +869,7 @@ struct show_var_st init_vars[]= {
#endif #endif
{"log", (char*) &opt_log, SHOW_BOOL}, {"log", (char*) &opt_log, SHOW_BOOL},
{"log_bin", (char*) &opt_bin_log, SHOW_BOOL}, {"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
{sys_trust_routine_creators.name,(char*) &sys_trust_routine_creators, SHOW_SYS}, {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
{"log_error", (char*) log_error_file, SHOW_CHAR}, {"log_error", (char*) log_error_file, SHOW_CHAR},
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
{"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL}, {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
...@@ -3463,6 +3467,26 @@ bool process_key_caches(int (* func) (const char *name, KEY_CACHE *)) ...@@ -3463,6 +3467,26 @@ bool process_key_caches(int (* func) (const char *name, KEY_CACHE *))
} }
void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DEPRECATED_SYNTAX,
ER(ER_WARN_DEPRECATED_SYNTAX), "log_bin_trust_routine_creators",
"log_bin_trust_function_creators");
}
void sys_var_trust_routine_creators::set_default(THD *thd, enum_var_type type)
{
warn_deprecated(thd);
sys_var_bool_ptr::set_default(thd, type);
}
bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
{
warn_deprecated(thd);
return sys_var_bool_ptr::update(thd, var);
}
/**************************************************************************** /****************************************************************************
Used templates Used templates
****************************************************************************/ ****************************************************************************/
......
...@@ -738,6 +738,17 @@ public: ...@@ -738,6 +738,17 @@ public:
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
}; };
class sys_var_trust_routine_creators :public sys_var_bool_ptr
{
/* We need a derived class only to have a warn_deprecated() */
public:
sys_var_trust_routine_creators(const char *name_arg, my_bool *value_arg) :
sys_var_bool_ptr(name_arg, value_arg) {};
void warn_deprecated(THD *thd);
void set_default(THD *thd, enum_var_type type);
bool update(THD *thd, set_var *var);
};
/**************************************************************************** /****************************************************************************
Classes for parsing of the SET command Classes for parsing of the SET command
****************************************************************************/ ****************************************************************************/
......
...@@ -5349,9 +5349,9 @@ ER_CANT_CREATE_GEOMETRY_OBJECT 22003 ...@@ -5349,9 +5349,9 @@ ER_CANT_CREATE_GEOMETRY_OBJECT 22003
ER_FAILED_ROUTINE_BREAK_BINLOG ER_FAILED_ROUTINE_BREAK_BINLOG
eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes" eng "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes"
ER_BINLOG_UNSAFE_ROUTINE ER_BINLOG_UNSAFE_ROUTINE
eng "This routine 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_routine_creators variable)" eng "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)"
ER_BINLOG_CREATE_ROUTINE_NEED_SUPER ER_BINLOG_CREATE_ROUTINE_NEED_SUPER
eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)" eng "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)"
ER_EXEC_STMT_WITH_OPEN_CURSOR ER_EXEC_STMT_WITH_OPEN_CURSOR
eng "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it." eng "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it."
ER_STMT_HAS_NO_OPEN_CURSOR ER_STMT_HAS_NO_OPEN_CURSOR
......
...@@ -551,12 +551,13 @@ db_create_routine(THD *thd, int type, sp_head *sp) ...@@ -551,12 +551,13 @@ db_create_routine(THD *thd, int type, sp_head *sp)
store(sp->m_chistics->comment.str, sp->m_chistics->comment.length, store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
system_charset_info); system_charset_info);
if (!trust_routine_creators && mysql_bin_log.is_open()) if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
!trust_function_creators && mysql_bin_log.is_open())
{ {
if (!sp->m_chistics->detistic) if (!sp->m_chistics->detistic)
{ {
/* /*
Note that for a _function_ this test is not enough; one could use Note that this test is not perfect; one could use
a non-deterministic read-only function in an update statement. a non-deterministic read-only function in an update statement.
*/ */
enum enum_sp_data_access access= enum enum_sp_data_access access=
......
...@@ -4318,18 +4318,6 @@ end_with_restore_list: ...@@ -4318,18 +4318,6 @@ end_with_restore_list:
So just execute the statement. So just execute the statement.
*/ */
res= sp->execute_procedure(thd, &lex->value_list); res= sp->execute_procedure(thd, &lex->value_list);
if (mysql_bin_log.is_open() &&
(sp->m_chistics->daccess == SP_CONTAINS_SQL ||
sp->m_chistics->daccess == SP_MODIFIES_SQL_DATA))
{
if (res)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
else
thd->clear_error();
}
/* /*
If warnings have been cleared, we have to clear total_warn_count If warnings have been cleared, we have to clear total_warn_count
too, otherwise the clients get confused. too, otherwise the clients get confused.
...@@ -4388,7 +4376,8 @@ end_with_restore_list: ...@@ -4388,7 +4376,8 @@ end_with_restore_list:
if (end_active_trans(thd)) if (end_active_trans(thd))
goto error; goto error;
memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics)); memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
if (!trust_routine_creators && mysql_bin_log.is_open() && if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
!trust_function_creators && mysql_bin_log.is_open() &&
!sp->m_chistics->detistic && !sp->m_chistics->detistic &&
(chistics.daccess == SP_CONTAINS_SQL || (chistics.daccess == SP_CONTAINS_SQL ||
chistics.daccess == SP_MODIFIES_SQL_DATA)) chistics.daccess == SP_MODIFIES_SQL_DATA))
...@@ -4399,6 +4388,12 @@ end_with_restore_list: ...@@ -4399,6 +4388,12 @@ end_with_restore_list:
} }
else else
{ {
/*
Note that if you implement the capability of ALTER FUNCTION to
alter the body of the function, this command should be made to
follow the restrictions that log-bin-trust-function-creators=0
already puts on CREATE FUNCTION.
*/
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
else else
......
...@@ -131,9 +131,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) ...@@ -131,9 +131,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
But a trigger can in theory be used to do nasty things (if it supported But a trigger can in theory be used to do nasty things (if it supported
DROP for example) so we do the check for privileges. For now there is DROP for example) so we do the check for privileges. For now there is
already a stronger test right above; but when this stronger test will already a stronger test right above; but when this stronger test will
be removed, the test below will hold. be removed, the test below will hold. Because triggers have the same
nature as functions regarding binlogging: their body is implicitely
binlogged, so they share the same danger, so trust_function_creators
applies to them too.
*/ */
if (!trust_routine_creators && mysql_bin_log.is_open() && if (!trust_function_creators && mysql_bin_log.is_open() &&
!(thd->security_ctx->master_access & SUPER_ACL)) !(thd->security_ctx->master_access & SUPER_ACL))
{ {
my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0)); my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment