mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 18:41:56 +01:00
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.
This commit is contained in:
parent
93607e351a
commit
5d9c8e9543
15 changed files with 433 additions and 214 deletions
|
@ -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 ($$$$$) {
|
||||||
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()
|
||||||
--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()
|
||||||
--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()
|
||||||
--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()
|
||||||
#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;
|
||||||
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;
|
||||||
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());
|
||||||
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());
|
||||||
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
|
||||||
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,80 +59,62 @@ 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;
|
select * from t1;
|
||||||
Log_name Pos Event_type Server_id End_log_pos Info
|
a
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
|
15
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
|
5
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1
|
select * from t2;
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3()
|
a
|
||||||
deterministic
|
3
|
||||||
insert into t1 values (15)
|
3
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
|
3
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
|
select * from t1;
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
|
a
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
|
15
|
||||||
|
5
|
||||||
|
select * from t2;
|
||||||
|
a
|
||||||
|
3
|
||||||
|
3
|
||||||
|
3
|
||||||
|
delete from t2;
|
||||||
|
alter table t2 add unique (a);
|
||||||
|
drop procedure foo4;
|
||||||
|
create procedure foo4()
|
||||||
deterministic
|
deterministic
|
||||||
begin
|
begin
|
||||||
insert into t2 values(3);
|
insert into t2 values(20),(20);
|
||||||
insert into t1 values (5);
|
end|
|
||||||
end
|
call foo4();
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
|
ERROR 23000: Duplicate entry '20' for key 1
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15)
|
show warnings;
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
|
Level Code Message
|
||||||
master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker
|
Error 1062 Duplicate entry '20' for key 1
|
||||||
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;
|
|
||||||
a
|
|
||||||
15
|
|
||||||
5
|
|
||||||
select * from t2;
|
select * from t2;
|
||||||
a
|
a
|
||||||
3
|
20
|
||||||
3
|
|
||||||
3
|
|
||||||
select * from t1;
|
|
||||||
a
|
|
||||||
15
|
|
||||||
5
|
|
||||||
select * from t2;
|
select * from t2;
|
||||||
a
|
a
|
||||||
3
|
20
|
||||||
3
|
|
||||||
3
|
|
||||||
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;
|
||||||
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,18 +160,55 @@ 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();
|
return unix_timestamp();
|
||||||
end root@localhost # #
|
end root@localhost # #
|
||||||
|
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
|
||||||
|
return unix_timestamp();
|
||||||
|
end zedjzlcsjhd@localhost # #
|
||||||
|
mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
|
||||||
|
return 0;
|
||||||
|
end root@localhost # #
|
||||||
select * from t1;
|
select * from t1;
|
||||||
a
|
a
|
||||||
1000000000
|
1000000000
|
||||||
|
@ -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();
|
return unix_timestamp();
|
||||||
end @ # #
|
end @ # #
|
||||||
|
mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
|
||||||
|
return unix_timestamp();
|
||||||
|
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);
|
||||||
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
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
--log_bin_trust_routine_creators=0
|
--log_bin_trust_routine_creators=0 --slave-skip-errors=1062
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
# 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,18 +24,14 @@ 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
|
|
||||||
|
# Stored procedures don't have the limitations that functions have
|
||||||
|
# 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()
|
create procedure foo()
|
||||||
begin
|
begin
|
||||||
declare b int;
|
declare b int;
|
||||||
|
@ -35,17 +39,6 @@ begin
|
||||||
insert into t1 values (b);
|
insert into t1 values (b);
|
||||||
insert into t1 values (unix_timestamp());
|
insert into t1 values (unix_timestamp());
|
||||||
end|
|
end|
|
||||||
|
|
||||||
--replace_column 2 # 5 #
|
|
||||||
show binlog events from 98| # check that not there
|
|
||||||
|
|
||||||
create procedure foo() deterministic
|
|
||||||
begin
|
|
||||||
declare b int;
|
|
||||||
set b = 8;
|
|
||||||
insert into t1 values (b);
|
|
||||||
insert into t1 values (unix_timestamp());
|
|
||||||
end|
|
|
||||||
delimiter ;|
|
delimiter ;|
|
||||||
|
|
||||||
# we replace columns having times
|
# we replace columns having times
|
||||||
|
@ -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;
|
||||||
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 ;|
|
||||||
# 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;
|
||||||
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;
|
||||||
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;
|
||||||
|
|
||||||
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;
|
||||||
--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;
|
||||||
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)
|
||||||
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;
|
||||||
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;
|
||||||
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
|
||||||
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,
|
||||||
"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.",
|
||||||
(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",
|
||||||
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[]=
|
||||||
&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[]= {
|
||||||
#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 *))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
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
|
||||||
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)
|
||||||
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:
|
||||||
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:
|
||||||
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:
|
||||||
}
|
}
|
||||||
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)
|
||||||
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));
|
||||||
|
|
Loading…
Add table
Reference in a new issue