mariadb/mysql-test/suite/roles/definer.test
Monty 8be53a389c MDEV-6112 multiple triggers per table
This is similar to MysQL Worklog 3253, but with
a different implementation. The disk format and
SQL syntax is identical with MySQL 5.7.

Fetures supported:
- "Any" ammount of any trigger
- Supports FOLLOWS and PRECEDES to be
  able to put triggers in a certain execution order.

Implementation details:
- Class Trigger added to hold information about a trigger.
  Before this trigger information was stored in a set of lists in
  Table_triggers_list and in Table_triggers_list::bodies
- Each Trigger has a next field that poinst to the next Trigger with the
  same action and time.
- When accessing a trigger, we now always access all linked triggers
- The list are now only used to load and save trigger files.
- MySQL trigger test case (trigger_wl3253) added and we execute these
  identically.
- Even more gracefully handling of wrong trigger files than before. This
  is useful if a trigger file uses functions or syntax not provided by
  the server.
- Each trigger now has a "Created" field that shows when the trigger was
  created, with 2 decimals.

Other comments:
- Many of the changes in test files was done because of the new "Created"
  field in the trigger file. This shows up in SHOW ... TRIGGER and when
  using information_schema.trigger.
- Don't check if all memory is released if on uses --gdb;  This is needed
  to be able to get a list from safemalloc of not freed memory while
  debugging.
- Added option to trim_whitespace() to know how many prefix characters
  was skipped.
- Changed a few ulonglong sql_mode to sql_mode_t, to find some wrong usage
  of sql_mode.
2016-10-05 01:11:07 +03:00

338 lines
8.7 KiB
Text

# create view
# create trigger
# create procedure
# create event
# mysqldump dumping the definer
source include/not_embedded.inc;
let MYSQLD_DATADIR=`select @@datadir`;
create database mysqltest1;
use mysqltest1;
create table t1 (a int, b int, c int);
insert t1 values (1,10,100),(2,20,200);
# non-priv role granted
create role role1;
grant select (a) on mysqltest1.t1 to role1;
grant event,execute,trigger on mysqltest1.* to role1;
grant role1 to current_user;
# priv role
create role role2;
grant insert,select on mysqltest1.t1 to role2;
grant event,execute,trigger on mysqltest1.* to role2;
# create a non-priv user and a priv role granted to him
create user foo@localhost;
grant create view on mysqltest1.* to foo@localhost;
create role role4;
grant select on mysqltest1.t1 to role4;
grant role4 to foo@localhost;
##################################################
# views
##################################################
# no curent role = error
--error ER_MALFORMED_DEFINER
create definer=current_role view test.v1 as select a+b,c from t1;
# definer=current_role, but it has doesn't have enough privileges
set role role1;
create definer=current_role view test.v1 as select a+b,c from t1;
show create view test.v1;
set role none;
# definer=role_name, privileges ok
create definer=role2 view test.v2 as select a+b,c,current_role() from t1;
show create view test.v2;
# definer=non_existent_role
create definer=role3 view test.v3 as select a+b,c from t1;
show create view test.v3;
connect (c1, localhost, foo,,mysqltest1);
connection c1;
show grants;
# role1 doesn't have enough privileges for v1 to work
--error ER_VIEW_INVALID
select * from test.v1;
# role2 is ok, v2 is ok
select * from test.v2;
# role3 is treated as a user name role3@%, doesn't exist, v3 fails
--error ER_ACCESS_DENIED_ERROR
select * from test.v3;
# fails, no SUPER - cannot specify a definer arbitrarily
--error ER_TABLEACCESS_DENIED_ERROR
create definer=role4 view test.v4 as select a+b,c from t1;
--error ER_TABLEACCESS_DENIED_ERROR
select * from t1;
set role role4;
select * from t1;
# can select from t1, but the view won't work, by default definer=current_user
create view test.v4 as select a+b,c from t1;
# now role4 is the current_role, can be specified as a definer
create definer=role4 view test.v5 as select a+b,c from t1;
--error ER_VIEW_INVALID
select * from test.v4;
select * from test.v5;
set role none;
--error ER_VIEW_INVALID
select * from test.v4;
select * from test.v5;
connection default;
drop role role4;
show create view test.v5;
--error ER_NO_SUCH_USER
select * from test.v5;
create user role4;
grant select on mysqltest1.t1 to role4;
show create view test.v5;
--error ER_NO_SUCH_USER
select * from test.v5;
# pretend it's an old view from before 10.0.5
perl;
local $/;
my $f= "$ENV{MYSQLD_DATADIR}/test/v5.frm";
open(F, '<', $f) or die "open(<$f): $!";
$_=<F>;
s/create-version=2/create-version=1/;
open(F, '>', $f) or die "open(>$f): $!";
syswrite F, $_ or die "syswrite($f): $!"
EOF
flush tables;
show create view test.v5;
select * from test.v5;
drop user role4;
##################################################
# trigger
##################################################
create table t2 select * from t1;
# no curent role = error
--error ER_MALFORMED_DEFINER
create definer=current_role trigger tr1 before insert on t2 for each row
insert t1 values (111, 222, 333);
# definer=current_role, but it has doesn't have enough privileges
set role role1;
create definer=current_role trigger tr1 before insert on t2 for each row
insert t1 values (111, 222, 333);
--replace_column 7 #
show create trigger tr1;
set role none;
--error ER_TABLEACCESS_DENIED_ERROR
insert t2 values (11,22,33);
select * from t1;
select * from t2;
# definer=role_name, privileges ok
create definer=role2 trigger tr2 before delete on t2 for each row
insert t1 values (111, 222, 333);
--replace_column 7 #
show create trigger tr2;
delete from t2 where a=1;
select * from t1;
select * from t2;
delete from t1 where a=111;
# definer=non_existent_role
create definer=role3 trigger tr3 before update on t2 for each row
insert t1 values (111, 222, 333);
--replace_column 7 #
show create trigger tr3;
--error ER_NO_SUCH_USER
update t2 set b=2 where a=2;
select * from t1;
select * from t2;
flush tables;
# change triggers to use pre-10.0.5 definer with an empty hostname
perl;
local $/;
my $f= "$ENV{MYSQLD_DATADIR}/mysqltest1/t2.TRG";
open(F, '<', $f) or die "open(<$f): $!";
$_=<F>;
s/'role2'/'role2\@'/;
s/`role2`/$&\@``/;
open(F, '>', $f) or die "open(>$f): $!";
syswrite F, $_ or die "syswrite($f): $!"
EOF
--replace_column 7 #
show create trigger tr2;
--error ER_NO_SUCH_USER
delete from t2 where a=2;
select * from t1;
select * from t2;
##################################################
# stored procedures
##################################################
# no curent role = error
--error ER_MALFORMED_DEFINER
create definer=current_role procedure pr1() insert t1 values (111, 222, 333);
# definer=current_role, but it has doesn't have enough privileges
set role role1;
create definer=current_role procedure pr1() insert t1 values (111, 222, 333);
show create procedure pr1;
set role none;
--error ER_TABLEACCESS_DENIED_ERROR
call pr1();
select * from t1;
# definer=role_name, privileges ok
create definer=role2 procedure pr2() insert t1 values (111, 222, 333);
show create procedure pr2;
call pr2();
select * from t1;
delete from t1 where a=111;
# definer=non_existent_role
create definer=role3 procedure pr3() insert t1 values (111, 222, 333);
show create procedure pr3;
--error ER_NO_SUCH_USER
call pr3();
select * from t1;
# change a procedure to use pre-10.0.5 definer with an empty hostname
update mysql.proc set definer='role2@' where definer='role2';
--error ER_NO_SUCH_USER
call pr2();
##################################################
# stored functions
##################################################
# no curent role = error
--error ER_MALFORMED_DEFINER
create definer=current_role function fn1() returns int return (select sum(a+b) from t1);
# definer=current_role, but it has doesn't have enough privileges
set role role1;
create definer=current_role function fn1() returns int return (select sum(a+b) from t1);
show create function fn1;
set role none;
--error ER_COLUMNACCESS_DENIED_ERROR
select fn1();
select * from t1;
# definer=role_name, privileges ok
create definer=role2 function fn2() returns int return (select sum(a+b) from t1);
show create function fn2;
select fn2();
# definer=non_existent_role
create definer=role3 function fn3() returns int return (select sum(a+b) from t1);
show create function fn3;
--error ER_NO_SUCH_USER
select fn3();
##################################################
# events
##################################################
set global event_scheduler=on;
# no curent role = error
--error ER_MALFORMED_DEFINER
create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do
insert t1 values (111, 1, 0);
# definer=current_role, but it has doesn't have enough privileges
set role role1;
create definer=current_role event e1 on schedule every 1 second starts '2000-01-01' do
insert t1 values (111, 2, 0);
show create event e1;
set role none;
# definer=non_existent_role
create definer=role3 event e3 on schedule every 1 second starts '2000-01-01' do
insert t1 values (111, 3, 0);
show create event e3;
# definer=role_name, privileges ok
create definer=role2 event e2 on schedule every 1 second starts '2000-01-01' do
insert t1 values (111, 4, 0);
show create event e2;
let $wait_condition=select count(*) >= 4 from t1;
--source include/wait_condition.inc
set global event_scheduler=off;
--sorted_result
select distinct * from t1;
delete from t1 where a=111;
##################################################
# mysqldump
##################################################
# note that LOCK TABLES won't work because v3 has invalid definer
--exec $MYSQL_DUMP --compact --events --routines --skip-lock-tables --databases test mysqltest1
##################################################
# cleanup
##################################################
drop trigger tr1;
drop trigger tr2;
drop trigger tr3;
drop procedure pr1;
drop procedure pr2;
drop procedure pr3;
drop function fn1;
drop function fn2;
drop function fn3;
drop event e1;
drop event e2;
drop event e3;
drop view test.v1, test.v2, test.v3, test.v4, test.v5;
drop table t1, t2;
drop role role1, role2;
drop user foo@localhost;
drop database mysqltest1;
use test;
##################################################
# reexecution
##################################################
create user utest;
prepare stmt1 from 'grant select on *.* to utest';
execute stmt1;
show grants for utest;
drop user utest;
create role utest;
execute stmt1;
show grants for utest;
drop role utest;