Commit 5d9c8e95 authored by unknown's avatar unknown

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).


mysql-test/mysql-test-run.pl:
  update to new option name
mysql-test/mysql-test-run.sh:
  update to new option name
mysql-test/mysql_test_run_new.c:
  update to new option name
mysql-test/r/rpl_sp.result:
  result update
mysql-test/t/rpl_sp-slave.opt:
  we need to skip this error to not hit BUG#14769
mysql-test/t/rpl_sp.test:
  Test update:
  1) as log-bin-trust-routine-creators now affects only functions, the testing of this option, which was
  mainly done on procedures, is moved to functions
  2) cleanup is simplified; and instead of many SHOW BINLOG EVENTS we do a big one in the end, which is more
  maintainable.
  3) we test a few more function and procedures cases to see how they replicate.
  4) removing out-of-date comments
sql/item_func.cc:
  This warning is wrong since binlogging of functions was changed in August. If a function fails
  in the middle, it will be binlogged with its error code (i.e. properly).
sql/mysql_priv.h:
  variable name changed
sql/mysqld.cc:
  option name changes. A precision about --read-only.
sql/set_var.cc:
  a new class sys_var_trust_routine_creators to be able to issue a "this is a deprecated variable" warning if used.
sql/set_var.h:
  new class to be able to issue a "this is a deprecated variable" warning if used.
sql/share/errmsg.txt:
  routine -> function
sql/sp.cc:
  log-bin-trust-routine-creators now applies only to functions.
sql/sql_parse.cc:
  1) sending ER_FAILED_ROUTINE_BREAK_BINLOG is wrong since August as we don't binlog CALL anymore but instead binlog the substatements;
  the clear_error() goes away too as it was necessary only when we created a binlog event from the "CALL" statement.
  2) log-bin-trust-routine-creators now applies only to functions.
sql/sql_trigger.cc:
  comments.
parent 93607e35
...@@ -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);
......
...@@ -4,16 +4,11 @@ reset master; ...@@ -4,16 +4,11 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
create database if not exists mysqltest1; drop database if exists mysqltest1;
create database mysqltest1;
use mysqltest1; use mysqltest1;
create table t1 (a varchar(100)); create table t1 (a varchar(100));
use mysqltest1; use mysqltest1;
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;
create procedure foo() create procedure foo()
begin begin
declare b int; declare b int;
...@@ -21,21 +16,9 @@ set b = 8; ...@@ -21,21 +16,9 @@ set b = 8;
insert into t1 values (b); insert into t1 values (b);
insert into t1 values (unix_timestamp()); insert into t1 values (unix_timestamp());
end| end|
ERROR HY000: 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)
show binlog events from 98|
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # create database if not exists mysqltest1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
create procedure foo() deterministic
begin
declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end|
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL YES DEFINER begin mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
declare b int; declare b int;
set b = 8; set b = 8;
insert into t1 values (b); insert into t1 values (b);
...@@ -43,7 +26,7 @@ insert into t1 values (unix_timestamp()); ...@@ -43,7 +26,7 @@ insert into t1 values (unix_timestamp());
end root@localhost # # end root@localhost # #
select * from mysql.proc where name='foo' and db='mysqltest1'; select * from mysql.proc where name='foo' and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL YES DEFINER begin mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
declare b int; declare b int;
set b = 8; set b = 8;
insert into t1 values (b); insert into t1 values (b);
...@@ -51,17 +34,6 @@ insert into t1 values (unix_timestamp()); ...@@ -51,17 +34,6 @@ insert into t1 values (unix_timestamp());
end @ # # end @ # #
set timestamp=1000000000; set timestamp=1000000000;
call foo(); call foo();
show binlog events from 308;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo() deterministic
begin
declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
select * from t1; select * from t1;
a a
8 8
...@@ -72,22 +44,10 @@ a ...@@ -72,22 +44,10 @@ a
1000000000 1000000000
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();
a a
show binlog events from 518;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo2()
not deterministic
reads sql data
select * from mysqltest1.t1
alter procedure foo2 contains sql; alter procedure foo2 contains sql;
ERROR HY000: 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)
drop table t1; drop table t1;
create table t1 (a int); create table t1 (a int);
create table t2 like t1; create table t2 like t1;
...@@ -99,57 +59,21 @@ grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1; ...@@ -99,57 +59,21 @@ grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1;
grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
create procedure foo4() create procedure foo4()
deterministic deterministic
insert into t1 values (10);
ERROR HY000: 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)
set global log_bin_trust_routine_creators=1;
create procedure foo4()
deterministic
begin begin
insert into t2 values(3); insert into t2 values(3);
insert into t1 values (5); insert into t1 values (5);
end| end|
call foo4(); call foo4();
Got one of the listed errors Got one of the listed errors
show warnings;
Level Code Message
Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
Warning 1417 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
call foo3(); call foo3();
show warnings; show warnings;
Level Code Message Level Code Message
call foo4(); call foo4();
Got one of the listed errors Got one of the listed errors
show warnings;
Level Code Message
Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'127.0.0.1' for table 't1'
Warning 1417 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
alter procedure foo4 sql security invoker; alter procedure foo4 sql security invoker;
call foo4(); call foo4();
show warnings; show warnings;
Level Code Message Level Code Message
show binlog events from 990;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3()
deterministic
insert into t1 values (15)
master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
deterministic
begin
insert into t2 values(3);
insert into t1 values (5);
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5)
select * from t1; select * from t1;
a a
15 15
...@@ -168,11 +92,29 @@ a ...@@ -168,11 +92,29 @@ a
3 3
3 3
3 3
delete from t2;
alter table t2 add unique (a);
drop procedure foo4;
create procedure foo4()
deterministic
begin
insert into t2 values(20),(20);
end|
call foo4();
ERROR 23000: Duplicate entry '20' for key 1
show warnings;
Level Code Message
Error 1062 Duplicate entry '20' for key 1
select * from t2;
a
20
select * from t2;
a
20
select * from mysql.proc where name="foo4" and db='mysqltest1'; select * from mysql.proc where name="foo4" and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES INVOKER begin mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES DEFINER begin
insert into t2 values(3); insert into t2 values(20),(20);
insert into t1 values (5);
end @ # # end @ # #
drop procedure foo4; drop procedure foo4;
select * from mysql.proc where name="foo4" and db='mysqltest1'; select * from mysql.proc where name="foo4" and db='mysqltest1';
...@@ -184,6 +126,13 @@ drop procedure foo2; ...@@ -184,6 +126,13 @@ drop procedure foo2;
drop procedure foo3; drop procedure foo3;
create function fn1(x int) create function fn1(x int)
returns int returns int
begin
insert into t1 values (x);
return x+2;
end|
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)
create function fn1(x int)
returns int
deterministic deterministic
begin begin
insert into t1 values (x); insert into t1 values (x);
...@@ -211,17 +160,54 @@ a ...@@ -211,17 +160,54 @@ a
drop function fn1; 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|
alter function fn1 contains sql;
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)
delete from t1; delete from t1;
set timestamp=1000000000; set timestamp=1000000000;
insert into t1 values(fn1()); insert into t1 values(fn1());
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
ERROR HY000: 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)
set global log_bin_trust_routine_creators=1;
Warnings:
Warning 1287 'log_bin_trust_routine_creators' is deprecated; use 'log_bin_trust_function_creators' instead
set global log_bin_trust_function_creators=0;
set global log_bin_trust_function_creators=1;
set global log_bin_trust_function_creators=1;
create function fn2()
returns int
no sql
begin
return unix_timestamp();
end|
create function fn3()
returns int
not deterministic
reads sql data
begin
return 0;
end|
select fn3();
fn3()
0
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 fn1 FUNCTION fn1 SQL CONTAINS_SQL YES DEFINER int(11) begin mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end root@localhost # #
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp(); return unix_timestamp();
end zedjzlcsjhd@localhost # #
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
return 0;
end root@localhost # # end root@localhost # #
select * from t1; select * from t1;
a a
...@@ -232,12 +218,34 @@ a ...@@ -232,12 +218,34 @@ a
1000000000 1000000000
select * from mysql.proc where db='mysqltest1'; select * from mysql.proc where db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
mysqltest1 fn1 FUNCTION fn1 SQL CONTAINS_SQL YES DEFINER int(11) begin mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp();
end @ # #
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
return unix_timestamp(); return unix_timestamp();
end @ # # end @ # #
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
return 0;
end @ # #
delete from t2;
alter table t2 add unique (a);
drop function fn1;
create function fn1()
returns int
begin
insert into t2 values(20),(20);
return 10;
end|
select fn1();
ERROR 23000: Duplicate entry '20' for key 1
select * from t2;
a
20
select * from t2;
a
20
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;
ERROR 42000: Access denied; you need the SUPER privilege for this operation ERROR 42000: Access denied; you need the SUPER privilege for this operation
flush logs;
delete from t1; delete from t1;
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;
insert into t1 values (1); insert into t1 values (1);
...@@ -253,14 +261,106 @@ insert into t1 values (1); ...@@ -253,14 +261,106 @@ insert into t1 values (1);
select * from t1; select * from t1;
a a
1 1
show binlog events in 'master-bin.000002' from 98; show binlog events in 'master-bin.000001' from 98;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # drop database if exists mysqltest1
master-bin.000002 # Query 1 # use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10 master-bin.000001 # Query 1 # create database mysqltest1
master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1) master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo()
master-bin.000002 # Query 1 # use `mysqltest1`; drop trigger trg begin
master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1) declare b int;
set b = 8;
insert into t1 values (b);
insert into t1 values (unix_timestamp());
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo2()
select * from mysqltest1.t1
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo2 contains sql
master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3()
deterministic
insert into t1 values (15)
master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
deterministic
begin
insert into t2 values(3);
insert into t1 values (5);
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5)
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
deterministic
begin
insert into t2 values(20),(20);
end
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(20),(20)
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo2
master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo3
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1(x int)
returns int
deterministic
begin
insert into t1 values (x);
return x+2;
end
master-bin.000001 # Query 1 # use `mysqltest1`; delete t1,t2 from t1,t2
master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`(20)
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(fn1(21))
master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1()
returns int
no sql
begin
return unix_timestamp();
end
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(fn1())
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn2()
returns int
no sql
begin
return unix_timestamp();
end
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn3()
returns int
not deterministic
reads sql data
begin
return 0;
end
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1()
returns int
begin
insert into t2 values(20),(20);
return 10;
end
master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`()
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1)
master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000001 # Query 1 # use `mysqltest1`; drop trigger trg
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1)
select * from t1; select * from t1;
a a
1 1
......
--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