Commit 3543f9d3 authored by anozdrin@mysql.com's avatar anozdrin@mysql.com

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into  mysql.com:/home/alik/MySQL/devel/5.0-wl2818
parents 32dc644e f23f49ed
...@@ -722,6 +722,7 @@ information_schema ROUTINES SQL_MODE ...@@ -722,6 +722,7 @@ information_schema ROUTINES SQL_MODE
information_schema TRIGGERS ACTION_CONDITION information_schema TRIGGERS ACTION_CONDITION
information_schema TRIGGERS ACTION_STATEMENT information_schema TRIGGERS ACTION_STATEMENT
information_schema TRIGGERS SQL_MODE information_schema TRIGGERS SQL_MODE
information_schema TRIGGERS DEFINER
information_schema VIEWS VIEW_DEFINITION information_schema VIEWS VIEW_DEFINITION
select table_name, column_name, data_type from information_schema.columns select table_name, column_name, data_type from information_schema.columns
where data_type = 'datetime'; where data_type = 'datetime';
...@@ -800,45 +801,45 @@ set @fired:= "Yes"; ...@@ -800,45 +801,45 @@ set @fired:= "Yes";
end if; end if;
end| end|
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 trg1 INSERT t1
begin begin
if new.j > 10 then if new.j > 10 then
set new.j := 10; set new.j := 10;
end if; end if;
end BEFORE NULL end BEFORE NULL root@localhost
trg2 UPDATE t1 trg2 UPDATE t1
begin begin
if old.i % 2 = 0 then if old.i % 2 = 0 then
set new.j := -1; set new.j := -1;
end if; end if;
end BEFORE NULL end BEFORE NULL root@localhost
trg3 UPDATE t1 trg3 UPDATE t1
begin begin
if new.j = -1 then if new.j = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end AFTER NULL end AFTER NULL root@localhost
select * from information_schema.triggers; select * from information_schema.triggers;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER
NULL test trg1 INSERT NULL test t1 0 NULL NULL test trg1 INSERT NULL test t1 0 NULL
begin begin
if new.j > 10 then if new.j > 10 then
set new.j := 10; set new.j := 10;
end if; end if;
end ROW BEFORE NULL NULL OLD NEW NULL end ROW BEFORE NULL NULL OLD NEW NULL root@localhost
NULL test trg2 UPDATE NULL test t1 0 NULL NULL test trg2 UPDATE NULL test t1 0 NULL
begin begin
if old.i % 2 = 0 then if old.i % 2 = 0 then
set new.j := -1; set new.j := -1;
end if; end if;
end ROW BEFORE NULL NULL OLD NEW NULL end ROW BEFORE NULL NULL OLD NEW NULL root@localhost
NULL test trg3 UPDATE NULL test t1 0 NULL NULL test trg3 UPDATE NULL test t1 0 NULL
begin begin
if new.j = -1 then if new.j = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end ROW AFTER NULL NULL OLD NEW NULL end ROW AFTER NULL NULL OLD NEW NULL root@localhost
drop trigger trg1; drop trigger trg1;
drop trigger trg2; drop trigger trg2;
drop trigger trg3; drop trigger trg3;
......
...@@ -1936,23 +1936,23 @@ end if; ...@@ -1936,23 +1936,23 @@ end if;
end| end|
set sql_mode=default| set sql_mode=default|
show triggers like "t1"; show triggers like "t1";
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 trg1 INSERT t1
begin begin
if new.a > 10 then if new.a > 10 then
set new.a := 10; set new.a := 10;
set new.a := 11; set new.a := 11;
end if; end if;
end BEFORE 0000-00-00 00:00:00 end BEFORE 0000-00-00 00:00:00 root@localhost
trg2 UPDATE t1 begin trg2 UPDATE t1 begin
if old.a % 2 = 0 then set new.b := 12; end if; if old.a % 2 = 0 then set new.b := 12; end if;
end BEFORE 0000-00-00 00:00:00 end BEFORE 0000-00-00 00:00:00 root@localhost
trg3 UPDATE t1 trg3 UPDATE t1
begin begin
if new.a = -1 then if new.a = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER end AFTER 0000-00-00 00:00:00 STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost
INSERT INTO t1 (a) VALUES (1),(2),(3),(22); INSERT INTO t1 (a) VALUES (1),(2),(3),(22);
update t1 set a = 4 where a=3; update t1 set a = 4 where a=3;
...@@ -2095,29 +2095,29 @@ Tables_in_test ...@@ -2095,29 +2095,29 @@ Tables_in_test
t1 t1
t2 t2
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 trg1 INSERT t1
begin begin
if new.a > 10 then if new.a > 10 then
set new.a := 10; set new.a := 10;
set new.a := 11; set new.a := 11;
end if; end if;
end BEFORE # end BEFORE # root@localhost
trg2 UPDATE t1 begin trg2 UPDATE t1 begin
if old.a % 2 = 0 then set new.b := 12; end if; if old.a % 2 = 0 then set new.b := 12; end if;
end BEFORE # end BEFORE # root@localhost
trg3 UPDATE t1 trg3 UPDATE t1
begin begin
if new.a = -1 then if new.a = -1 then
set @fired:= "Yes"; set @fired:= "Yes";
end if; end if;
end AFTER # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER end AFTER # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost
trg4 INSERT t2 trg4 INSERT t2
begin begin
if new.a > 10 then if new.a > 10 then
set @fired:= "No"; set @fired:= "No";
end if; end if;
end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost
DROP TABLE t1, t2; DROP TABLE t1, t2;
--port=1234 --port=1234
--port=1234 --port=1234
...@@ -2140,9 +2140,9 @@ SELECT * FROM `test2`; ...@@ -2140,9 +2140,9 @@ SELECT * FROM `test2`;
a2 a2
1 1
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
testref INSERT test1 BEGIN testref INSERT test1 BEGIN
INSERT INTO test2 SET a2 = NEW.a1; END BEFORE NULL INSERT INTO test2 SET a2 = NEW.a1; END BEFORE NULL root@localhost
SELECT * FROM `test1`; SELECT * FROM `test1`;
a1 a1
1 1
...@@ -2157,6 +2157,7 @@ DROP FUNCTION IF EXISTS bug9056_func1; ...@@ -2157,6 +2157,7 @@ DROP FUNCTION IF EXISTS bug9056_func1;
DROP FUNCTION IF EXISTS bug9056_func2; DROP FUNCTION IF EXISTS bug9056_func2;
DROP PROCEDURE IF EXISTS bug9056_proc1; DROP PROCEDURE IF EXISTS bug9056_proc1;
DROP PROCEDURE IF EXISTS bug9056_proc2; DROP PROCEDURE IF EXISTS bug9056_proc2;
DROP PROCEDURE IF EXISTS `a'b`;
CREATE TABLE t1 (id int); CREATE TABLE t1 (id int);
INSERT INTO t1 VALUES(1), (2), (3), (4), (5); INSERT INTO t1 VALUES(1), (2), (3), (4), (5);
CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b // CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) RETURN a+b //
......
...@@ -1465,13 +1465,13 @@ flush logs; ...@@ -1465,13 +1465,13 @@ flush logs;
-------- switch to master ------- -------- switch to master -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 SET @a:=1 BEFORE NULL trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
-------- switch to slave ------- -------- switch to slave -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1 SET @a:=1 BEFORE NULL trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
######## DROP TRIGGER trg1 ######## ######## DROP TRIGGER trg1 ########
...@@ -1520,11 +1520,11 @@ flush logs; ...@@ -1520,11 +1520,11 @@ flush logs;
-------- switch to master ------- -------- switch to master -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
-------- switch to slave ------- -------- switch to slave -------
SHOW TRIGGERS; SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
######## CREATE USER user1@localhost ######## ######## CREATE USER user1@localhost ########
......
...@@ -263,104 +263,7 @@ a ...@@ -263,104 +263,7 @@ a
1 1
show binlog events in 'master-bin.000001' 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.000001 # Query 1 # drop database if exists mysqltest1 master-bin.000002 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10
master-bin.000001 # Query 1 # create database mysqltest1
master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo()
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())
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
......
...@@ -89,8 +89,24 @@ insert into t1 set a = now(); ...@@ -89,8 +89,24 @@ insert into t1 set a = now();
select a=b && a=c from t1; select a=b && a=c from t1;
a=b && a=c a=b && a=c
1 1
SELECT routine_name, definer
FROM information_schema.routines;
routine_name definer
bug12480 root@localhost
SELECT trigger_name, definer
FROM information_schema.triggers;
trigger_name definer
t1_first root@localhost
--- On slave -- --- On slave --
SELECT routine_name, definer
FROM information_schema.routines;
routine_name definer
bug12480 @
SELECT trigger_name, definer
FROM information_schema.triggers;
trigger_name definer
t1_first root@localhost
select a=b && a=c from t1; select a=b && a=c from t1;
a=b && a=c a=b && a=c
1 1
......
...@@ -4,7 +4,7 @@ drop procedure if exists f1; ...@@ -4,7 +4,7 @@ drop procedure if exists f1;
use test; use test;
create table t1 (field1 INT); create table t1 (field1 INT);
CREATE VIEW v1 AS SELECT field1 FROM t1; CREATE VIEW v1 AS SELECT field1 FROM t1;
ERROR HY000: View definer is not fully qualified ERROR HY000: Definer is not fully qualified
drop table t1; drop table t1;
create procedure f1() select 1; create procedure f1() select 1;
drop procedure f1; drop procedure f1;
......
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
DROP DATABASE IF EXISTS mysqltest_db1;
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
---> patching t1.TRG...
CREATE TRIGGER wl2818_trg2 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
trigger_name definer
wl2818_trg1
wl2818_trg2 mysqltest_dfn@localhost
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER
NULL mysqltest_db1 wl2818_trg1 INSERT NULL mysqltest_db1 t1 0 NULL
INSERT INTO t2 VALUES(CURRENT_USER()) ROW BEFORE NULL NULL OLD NEW NULL
NULL mysqltest_db1 wl2818_trg2 INSERT NULL mysqltest_db1 t1 0 NULL
INSERT INTO t2 VALUES(CURRENT_USER()) ROW AFTER NULL NULL OLD NEW NULL mysqltest_dfn@localhost
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
DROP DATABASE IF EXISTS mysqltest_db1;
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
---> connection: default
GRANT ALL PRIVILEGES ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
GRANT ALL PRIVILEGES ON mysqltest_db1.t2 TO mysqltest_dfn@localhost;
GRANT ALL PRIVILEGES ON mysqltest_db1.t1
TO 'mysqltest_inv'@localhost;
GRANT SELECT ON mysqltest_db1.t2
TO 'mysqltest_inv'@localhost;
---> connection: wl2818_definer_con
use mysqltest_db1;
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
num_value
1
SELECT * FROM t2;
user_str
mysqltest_dfn@localhost
---> connection: wl2818_invoker_con
use mysqltest_db1;
INSERT INTO t1 VALUES(2);
SELECT * FROM t1;
num_value
1
2
SELECT * FROM t2;
user_str
mysqltest_dfn@localhost
mysqltest_dfn@localhost
---> connection: default
use mysqltest_db1;
REVOKE INSERT ON mysqltest_db1.t2 FROM mysqltest_dfn@localhost;
---> connection: wl2818_invoker_con
use mysqltest_db1;
INSERT INTO t1 VALUES(3);
ERROR 42000: INSERT command denied to user 'mysqltest_dfn'@'localhost' for table 't2'
SELECT * FROM t1;
num_value
1
2
3
SELECT * FROM t2;
user_str
mysqltest_dfn@localhost
mysqltest_dfn@localhost
---> connection: default
use mysqltest_db1;
REVOKE SELECT ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
SET @new_sum = 0;
SET @old_sum = 0;
---> INSERT INTO statement; BEFORE timing
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(4);
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> INSERT INTO statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(5);
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
UPDATE t1 SET num_value = 10;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER UPDATE ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
UPDATE t1 SET num_value = 20;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> connection: default
use mysqltest_db1;
GRANT SELECT ON mysqltest_db1.t1 TO mysqltest_dfn@localhost;
REVOKE UPDATE ON mysqltest_db1.t1 FROM mysqltest_dfn@localhost;
---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
SET @new_sum = 0;
SET @old_sum = 0;
---> INSERT INTO statement; BEFORE timing
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(4);
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> INSERT INTO statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
INSERT INTO t1 VALUES(5);
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE UPDATE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
UPDATE t1 SET num_value = 10;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> UPDATE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER UPDATE ON t1
FOR EACH ROW
SET @new_sum = @new_sum + NEW.num_value;
UPDATE t1 SET num_value = 20;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; BEFORE timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 BEFORE DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> DELETE statement; AFTER timing
DROP TRIGGER trg1;
CREATE TRIGGER trg1 AFTER DELETE ON t1
FOR EACH ROW
SET @old_sum = @old_sum + OLD.num_value;
DELETE FROM t1;
ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for table 't1'
---> connection: wl2818_definer_con
use mysqltest_db1;
DROP TRIGGER trg1;
CREATE DEFINER='mysqltest_inv'@'localhost'
TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @new_sum = 0;
CREATE DEFINER='mysqltest_nonexs'@'localhost'
TRIGGER trg2 AFTER INSERT ON t1
FOR EACH ROW
SET @new_sum = 0;
Warnings:
Note 1449 There is no 'mysqltest_nonexs'@'localhost' registered
INSERT INTO t1 VALUES(6);
ERROR 42000: Access denied; you need the SUPER privilege for this operation
SHOW TRIGGERS;
Trigger Event Table Statement Timing Created sql_mode Definer
trg1 INSERT t1
SET @new_sum = 0 BEFORE NULL mysqltest_inv@localhost
trg2 INSERT t1
SET @new_sum = 0 AFTER NULL mysqltest_nonexs@localhost
DROP TRIGGER trg1;
DROP TRIGGER trg2;
CREATE TRIGGER trg1 BEFORE INSERT ON t1
FOR EACH ROW
SET @a = 1;
CREATE TRIGGER trg2 AFTER INSERT ON t1
FOR EACH ROW
SET @a = 2;
CREATE TRIGGER trg3 BEFORE UPDATE ON t1
FOR EACH ROW
SET @a = 3;
CREATE TRIGGER trg4 AFTER UPDATE ON t1
FOR EACH ROW
SET @a = 4;
CREATE TRIGGER trg5 BEFORE DELETE ON t1
FOR EACH ROW
SET @a = 5;
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
trigger_name definer
trg1
trg2 @
trg3 @abc@def@@
trg4 @hostname
trg5 @abcdef@@@hostname
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED SQL_MODE DEFINER
NULL mysqltest_db1 trg1 INSERT NULL mysqltest_db1 t1 0 NULL
SET @a = 1 ROW BEFORE NULL NULL OLD NEW NULL
NULL mysqltest_db1 trg2 INSERT NULL mysqltest_db1 t1 0 NULL
SET @a = 2 ROW AFTER NULL NULL OLD NEW NULL @
NULL mysqltest_db1 trg3 UPDATE NULL mysqltest_db1 t1 0 NULL
SET @a = 3 ROW BEFORE NULL NULL OLD NEW NULL @abc@def@@
NULL mysqltest_db1 trg4 UPDATE NULL mysqltest_db1 t1 0 NULL
SET @a = 4 ROW AFTER NULL NULL OLD NEW NULL @hostname
NULL mysqltest_db1 trg5 DELETE NULL mysqltest_db1 t1 0 NULL
SET @a = 5 ROW BEFORE NULL NULL OLD NEW NULL @abcdef@@@hostname
---> connection: default
DROP USER mysqltest_dfn@localhost;
DROP USER mysqltest_inv@localhost;
DROP DATABASE mysqltest_db1;
Warnings:
Warning 1454 No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
...@@ -611,9 +611,9 @@ select @a; ...@@ -611,9 +611,9 @@ select @a;
@a @a
10 10
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
t1_bi INSERT t1 set new."t1 column" = 5 BEFORE # REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI t1_bi INSERT t1 set new."t1 column" = 5 BEFORE # REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI root@localhost
t1_af INSERT t1 set @a=10 AFTER # t1_af INSERT t1 set @a=10 AFTER # root@localhost
drop table t1; drop table t1;
set sql_mode="traditional"; set sql_mode="traditional";
create table t1 (a date); create table t1 (a date);
...@@ -633,8 +633,8 @@ t1 CREATE TABLE `t1` ( ...@@ -633,8 +633,8 @@ t1 CREATE TABLE `t1` (
`a` date default NULL `a` date default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
show triggers; show triggers;
Trigger Event Table Statement Timing Created sql_mode Trigger Event Table Statement Timing Created sql_mode Definer
t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # root@localhost
drop table t1; drop table t1;
create table t1 (id int); create table t1 (id int);
create trigger t1_ai after insert on t1 for each row flush tables; create trigger t1_ai after insert on t1 for each row flush tables;
......
...@@ -2199,10 +2199,10 @@ r_object_id users_names ...@@ -2199,10 +2199,10 @@ r_object_id users_names
drop view v1, v2; drop view v1, v2;
drop table t1, t2; drop table t1, t2;
create definer=some_user@`` sql security invoker view v1 as select 1; create definer=some_user@`` sql security invoker view v1 as select 1;
ERROR HY000: View definer is not fully qualified ERROR HY000: Definer is not fully qualified
create definer=some_user@localhost sql security invoker view v1 as select 1; create definer=some_user@localhost sql security invoker view v1 as select 1;
Warnings: Warnings:
Note 1449 There is not some_user@localhost registered Note 1449 There is no 'some_user'@'localhost' registered
show create view v1; show create view v1;
View Create View View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1` v1 CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
......
...@@ -13,7 +13,7 @@ create table mysqltest.t2 (a int, b int); ...@@ -13,7 +13,7 @@ create table mysqltest.t2 (a int, b int);
grant select on mysqltest.t1 to mysqltest_1@localhost; grant select on mysqltest.t1 to mysqltest_1@localhost;
grant create view,select on test.* to mysqltest_1@localhost; grant create view,select on test.* to mysqltest_1@localhost;
create definer=root@localhost view v1 as select * from mysqltest.t1; create definer=root@localhost view v1 as select * from mysqltest.t1;
ERROR HY000: You need the SUPER privilege for creation view with root@localhost definer ERROR 42000: Access denied; you need the SUPER privilege for this operation
create view v1 as select * from mysqltest.t1; create view v1 as select * from mysqltest.t1;
alter view v1 as select * from mysqltest.t1; alter view v1 as select * from mysqltest.t1;
ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1' ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 'v1'
......
...@@ -882,6 +882,7 @@ DROP FUNCTION IF EXISTS bug9056_func1; ...@@ -882,6 +882,7 @@ DROP FUNCTION IF EXISTS bug9056_func1;
DROP FUNCTION IF EXISTS bug9056_func2; DROP FUNCTION IF EXISTS bug9056_func2;
DROP PROCEDURE IF EXISTS bug9056_proc1; DROP PROCEDURE IF EXISTS bug9056_proc1;
DROP PROCEDURE IF EXISTS bug9056_proc2; DROP PROCEDURE IF EXISTS bug9056_proc2;
DROP PROCEDURE IF EXISTS `a'b`;
--enable_warnings --enable_warnings
CREATE TABLE t1 (id int); CREATE TABLE t1 (id int);
......
...@@ -87,12 +87,35 @@ insert into t1 set a = now(); ...@@ -87,12 +87,35 @@ insert into t1 set a = now();
select a=b && a=c from t1; select a=b && a=c from t1;
let $time=`select a from t1`; let $time=`select a from t1`;
# Check that definer attribute is replicated properly:
# - dump definers on the master;
# - wait for the slave to synchronize with the master;
# - dump definers on the slave;
SELECT routine_name, definer
FROM information_schema.routines;
SELECT trigger_name, definer
FROM information_schema.triggers;
save_master_pos; save_master_pos;
connection slave; connection slave;
sync_with_master; sync_with_master;
--disable_query_log --disable_query_log
select "--- On slave --" as ""; select "--- On slave --" as "";
--enable_query_log --enable_query_log
# XXX: Definers of stored procedures and functions are not replicated. WL#2897
# (Complete definer support in the stored routines) addresses this issue. So,
# the result file is expected to be changed after implementation of this WL
# item.
SELECT routine_name, definer
FROM information_schema.routines;
SELECT trigger_name, definer
FROM information_schema.triggers;
select a=b && a=c from t1; select a=b && a=c from t1;
--disable_query_log --disable_query_log
eval select a='$time' as 'test' from t1; eval select a='$time' as 'test' from t1;
......
...@@ -9,7 +9,7 @@ use test; ...@@ -9,7 +9,7 @@ use test;
# test that we can create VIEW if privileges check switched off # test that we can create VIEW if privileges check switched off
# #
create table t1 (field1 INT); create table t1 (field1 INT);
-- error ER_NO_VIEW_USER -- error ER_MALFORMED_DEFINER
CREATE VIEW v1 AS SELECT field1 FROM t1; CREATE VIEW v1 AS SELECT field1 FROM t1;
drop table t1; drop table t1;
......
# Test case(s) in this file contain(s) GRANT/REVOKE statements, which are not
# supported in embedded server. So, this test should not be run on embedded
# server.
-- source include/not_embedded.inc
###########################################################################
#
# Tests for WL#2818:
# - Check that triggers created w/o DEFINER information work well:
# - create the first trigger;
# - manually remove definer information from corresponding TRG file;
# - create the second trigger (the first trigger will be reloaded; check
# that we receive a warning);
# - check that the triggers loaded correctly;
#
###########################################################################
#
# Prepare environment.
#
DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
FLUSH PRIVILEGES;
--disable_warnings
DROP DATABASE IF EXISTS mysqltest_db1;
--enable_warnings
CREATE DATABASE mysqltest_db1;
CREATE USER mysqltest_dfn@localhost;
CREATE USER mysqltest_inv@localhost;
GRANT SUPER ON *.* TO mysqltest_dfn@localhost;
GRANT CREATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
#
# Create a table and the first trigger.
#
--connect (wl2818_definer_con,localhost,mysqltest_dfn,,mysqltest_db1)
--connection wl2818_definer_con
--echo
--echo ---> connection: wl2818_definer_con
CREATE TABLE t1(num_value INT);
CREATE TABLE t2(user_str TEXT);
CREATE TRIGGER wl2818_trg1 BEFORE INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
#
# Remove definers from TRG file.
#
--echo
--echo ---> patching t1.TRG...
--exec grep --text -v 'definers=' $MYSQL_TEST_DIR/var/master-data/mysqltest_db1/t1.TRG > $MYSQL_TEST_DIR/var/tmp/t1.TRG
--exec mv $MYSQL_TEST_DIR/var/tmp/t1.TRG $MYSQL_TEST_DIR/var/master-data/mysqltest_db1/t1.TRG
#
# Create a new trigger.
#
--echo
CREATE TRIGGER wl2818_trg2 AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2 VALUES(CURRENT_USER());
--echo
SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
--echo
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
This diff is collapsed.
...@@ -2081,7 +2081,7 @@ drop table t1, t2; ...@@ -2081,7 +2081,7 @@ drop table t1, t2;
# #
# DEFINER information check # DEFINER information check
# #
-- error ER_NO_VIEW_USER -- error ER_MALFORMED_DEFINER
create definer=some_user@`` sql security invoker view v1 as select 1; create definer=some_user@`` sql security invoker view v1 as select 1;
create definer=some_user@localhost sql security invoker view v1 as select 1; create definer=some_user@localhost sql security invoker view v1 as select 1;
show create view v1; show create view v1;
......
...@@ -24,7 +24,7 @@ grant create view,select on test.* to mysqltest_1@localhost; ...@@ -24,7 +24,7 @@ grant create view,select on test.* to mysqltest_1@localhost;
connect (user1,localhost,mysqltest_1,,test); connect (user1,localhost,mysqltest_1,,test);
connection user1; connection user1;
-- error ER_VIEW_OTHER_USER -- error ER_SPECIFIC_ACCESS_DENIED
create definer=root@localhost view v1 as select * from mysqltest.t1; create definer=root@localhost view v1 as select * from mysqltest.t1;
create view v1 as select * from mysqltest.t1; create view v1 as select * from mysqltest.t1;
# try to modify view without DROP privilege on it # try to modify view without DROP privilege on it
......
...@@ -4888,7 +4888,7 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) ...@@ -4888,7 +4888,7 @@ Item_func_sp::tmp_table_field(TABLE *t_arg)
/* /*
Find the function and chack access rigths to the function Find the function and check access rights to the function
SYNOPSIS SYNOPSIS
find_and_check_access() find_and_check_access()
......
...@@ -522,8 +522,9 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables); ...@@ -522,8 +522,9 @@ bool delete_precheck(THD *thd, TABLE_LIST *tables);
bool insert_precheck(THD *thd, TABLE_LIST *tables); bool insert_precheck(THD *thd, TABLE_LIST *tables);
bool create_table_precheck(THD *thd, TABLE_LIST *tables, bool create_table_precheck(THD *thd, TABLE_LIST *tables,
TABLE_LIST *create_table); TABLE_LIST *create_table);
bool default_view_definer(Security_context *sctx, st_lex_user *definer);
bool get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
enum enum_mysql_completiontype { enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7, ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
...@@ -847,6 +848,10 @@ bool mysqld_show_column_types(THD *thd); ...@@ -847,6 +848,10 @@ bool mysqld_show_column_types(THD *thd);
bool mysqld_help (THD *thd, const char *text); bool mysqld_help (THD *thd, const char *text);
void calc_sum_of_all_status(STATUS_VAR *to); void calc_sum_of_all_status(STATUS_VAR *to);
void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
const LEX_STRING *definer_host);
/* information schema */ /* information schema */
extern LEX_STRING information_schema_name; extern LEX_STRING information_schema_name;
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str, LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
......
...@@ -5405,14 +5405,14 @@ ER_PS_NO_RECURSION ...@@ -5405,14 +5405,14 @@ ER_PS_NO_RECURSION
eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner" eng "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner"
ER_SP_CANT_SET_AUTOCOMMIT ER_SP_CANT_SET_AUTOCOMMIT
eng "Not allowed to set autocommit from a stored function or trigger" eng "Not allowed to set autocommit from a stored function or trigger"
ER_NO_VIEW_USER ER_MALFORMED_DEFINER
eng "View definer is not fully qualified" eng "Definer is not fully qualified"
ER_VIEW_FRM_NO_USER ER_VIEW_FRM_NO_USER
eng "View %-.64s.%-.64s has not definer information (old table format). Current user is used as definer. Please recreate view!" eng "View %-.64s.%-.64s has not definer information (old table format). Current user is used as definer. Please recreate view!"
ER_VIEW_OTHER_USER ER_VIEW_OTHER_USER
eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer" eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
ER_NO_SUCH_USER ER_NO_SUCH_USER
eng "There is not %-.64s@%-.64s registered" eng "There is no '%-.64s'@'%-.64s' registered"
ER_FORBID_SCHEMA_CHANGE ER_FORBID_SCHEMA_CHANGE
eng "Changing schema from '%-.64s' to '%-.64s' is not allowed." eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
ER_ROW_IS_REFERENCED_2 23000 ER_ROW_IS_REFERENCED_2 23000
...@@ -5421,3 +5421,5 @@ ER_NO_REFERENCED_ROW_2 23000 ...@@ -5421,3 +5421,5 @@ ER_NO_REFERENCED_ROW_2 23000
eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
ER_SP_BAD_VAR_SHADOW 42000 ER_SP_BAD_VAR_SHADOW 42000
eng "Variable '%-.64s' must be quoted with `...`, or renamed" eng "Variable '%-.64s' must be quoted with `...`, or renamed"
ER_TRG_NO_DEFINER
eng "No definer attribute for trigger '%-.64s'.'%-.64s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger."
...@@ -441,8 +441,8 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) ...@@ -441,8 +441,8 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1))) if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto done; goto done;
*sphp= thd->lex->sphead; *sphp= thd->lex->sphead;
(*sphp)->set_info((char *)definer, (uint)strlen(definer), (*sphp)->set_definer((char*) definer, (uint) strlen(definer));
created, modified, &chistics, sql_mode); (*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->optimize(); (*sphp)->optimize();
} }
thd->lex->sql_command= oldcmd; thd->lex->sql_command= oldcmd;
......
...@@ -1569,21 +1569,9 @@ sp_head::check_backpatch(THD *thd) ...@@ -1569,21 +1569,9 @@ sp_head::check_backpatch(THD *thd)
} }
void void
sp_head::set_info(char *definer, uint definerlen, sp_head::set_info(longlong created, longlong modified,
longlong created, longlong modified,
st_sp_chistics *chistics, ulong sql_mode) st_sp_chistics *chistics, ulong sql_mode)
{ {
char *p= strchr(definer, '@');
uint len;
if (! p)
p= definer; // Weird...
len= p-definer;
m_definer_user.str= strmake_root(mem_root, definer, len);
m_definer_user.length= len;
len= definerlen-len-1;
m_definer_host.str= strmake_root(mem_root, p+1, len);
m_definer_host.length= len;
m_created= created; m_created= created;
m_modified= modified; m_modified= modified;
m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics, m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics,
...@@ -1597,6 +1585,34 @@ sp_head::set_info(char *definer, uint definerlen, ...@@ -1597,6 +1585,34 @@ sp_head::set_info(char *definer, uint definerlen,
m_sql_mode= sql_mode; m_sql_mode= sql_mode;
} }
void
sp_head::set_definer(char *definer, uint definerlen)
{
char *p= strrchr(definer, '@');
if (!p)
{
m_definer_user.str= strmake_root(mem_root, "", 0);
m_definer_user.length= 0;
m_definer_host.str= strmake_root(mem_root, "", 0);
m_definer_host.length= 0;
}
else
{
const uint user_name_len= p - definer;
const uint host_name_len= definerlen - user_name_len - 1;
m_definer_user.str= strmake_root(mem_root, definer, user_name_len);
m_definer_user.length= user_name_len;
m_definer_host.str= strmake_root(mem_root, p + 1, host_name_len);
m_definer_host.length= host_name_len;
}
}
void void
sp_head::reset_thd_mem_root(THD *thd) sp_head::reset_thd_mem_root(THD *thd)
{ {
......
...@@ -251,10 +251,11 @@ public: ...@@ -251,10 +251,11 @@ public:
Field *make_field(uint max_length, const char *name, TABLE *dummy); Field *make_field(uint max_length, const char *name, TABLE *dummy);
void set_info(char *definer, uint definerlen, void set_info(longlong created, longlong modified,
longlong created, longlong modified,
st_sp_chistics *chistics, ulong sql_mode); st_sp_chistics *chistics, ulong sql_mode);
void set_definer(char *definer, uint definerlen);
void reset_thd_mem_root(THD *thd); void reset_thd_mem_root(THD *thd);
void restore_thd_mem_root(THD *thd); void restore_thd_mem_root(THD *thd);
......
...@@ -3532,7 +3532,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, ...@@ -3532,7 +3532,7 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
of other queries). For simple queries first_not_own_table is 0. of other queries). For simple queries first_not_own_table is 0.
*/ */
for (i= 0, table= tables; for (i= 0, table= tables;
table != first_not_own_table && i < number; table && table != first_not_own_table && i < number;
table= table->next_global, i++) table= table->next_global, i++)
{ {
/* Remove SHOW_VIEW_ACL, because it will be checked during making view */ /* Remove SHOW_VIEW_ACL, because it will be checked during making view */
......
...@@ -737,10 +737,15 @@ typedef struct st_lex ...@@ -737,10 +737,15 @@ typedef struct st_lex
TABLE_LIST **query_tables_last; TABLE_LIST **query_tables_last;
/* store original leaf_tables for INSERT SELECT and PS/SP */ /* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert; TABLE_LIST *leaf_tables_insert;
st_lex_user *create_view_definer;
char *create_view_start; char *create_view_start;
char *create_view_select_start; char *create_view_select_start;
/*
The definer of the object being created (view, trigger, stored routine).
I.e. the value of DEFINER clause.
*/
LEX_USER *definer;
List<key_part_spec> col_list; List<key_part_spec> col_list;
List<key_part_spec> ref_list; List<key_part_spec> ref_list;
List<String> interval_list; List<String> interval_list;
...@@ -887,6 +892,14 @@ typedef struct st_lex ...@@ -887,6 +892,14 @@ typedef struct st_lex
*/ */
SQL_LIST trg_table_fields; SQL_LIST trg_table_fields;
/*
trigger_definition_begin points to the beginning of the word "TRIGGER" in
CREATE TRIGGER statement. This is used to add possibly omitted DEFINER
clause to the trigger definition statement before dumping it to the
binlog.
*/
const char *trigger_definition_begin;
/* /*
If non-0 then indicates that query requires prelocking and points to If non-0 then indicates that query requires prelocking and points to
next_global member of last own element in query table list (i.e. last next_global member of last own element in query table list (i.e. last
......
...@@ -5057,7 +5057,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables, ...@@ -5057,7 +5057,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
the given table list refers to the list for prelocking (contains tables the given table list refers to the list for prelocking (contains tables
of other queries). For simple queries first_not_own_table is 0. of other queries). For simple queries first_not_own_table is 0.
*/ */
for (; tables != first_not_own_table; tables= tables->next_global) for (; tables && tables != first_not_own_table; tables= tables->next_global)
{ {
if (tables->schema_table && if (tables->schema_table &&
(want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL))) (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
...@@ -7461,32 +7461,81 @@ Item *negate_expression(THD *thd, Item *expr) ...@@ -7461,32 +7461,81 @@ Item *negate_expression(THD *thd, Item *expr)
return new Item_func_not(expr); return new Item_func_not(expr);
} }
/* /*
Assign as view definer current user Set the specified definer to the default value, which is the current user in
the thread. Also check that the current user satisfies to the definers
requirements.
SYNOPSIS SYNOPSIS
default_view_definer() get_default_definer()
sctx current security context thd [in] thread handler
definer structure where it should be assigned definer [out] definer
RETURN RETURN
FALSE OK error status, that is:
TRUE Error - FALSE -- on success;
- TRUE -- on error (current user can not be a definer).
*/ */
bool default_view_definer(Security_context *sctx, st_lex_user *definer) bool get_default_definer(THD *thd, LEX_USER *definer)
{ {
definer->user.str= sctx->priv_user; /* Check that current user has non-empty host name. */
definer->user.length= strlen(sctx->priv_user);
const Security_context *sctx= thd->security_ctx;
if (!*sctx->priv_host) if (sctx->priv_host[0] == 0)
{ {
my_error(ER_NO_VIEW_USER, MYF(0)); my_error(ER_MALFORMED_DEFINER, MYF(0));
return TRUE; return TRUE;
} }
definer->host.str= sctx->priv_host; /* Fill in. */
definer->host.length= strlen(sctx->priv_host);
definer->user.str= (char *) sctx->priv_user;
definer->user.length= strlen(definer->user.str);
definer->host.str= (char *) sctx->priv_host;
definer->host.length= strlen(definer->host.str);
return FALSE; return FALSE;
} }
/*
Create definer with the given user and host names. Also check that the user
and host names satisfy definers requirements.
SYNOPSIS
create_definer()
thd [in] thread handler
user_name [in] user name
host_name [in] host name
RETURN
On success, return a valid pointer to the created and initialized
LEX_STRING, which contains definer information.
On error, return 0.
*/
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
{
LEX_USER *definer;
/* Check that specified host name is valid. */
if (host_name->length == 0)
{
my_error(ER_MALFORMED_DEFINER, MYF(0));
return 0;
}
/* Create and initialize. */
if (! (definer= (LEX_USER*) thd->alloc(sizeof (LEX_USER))))
return 0;
definer->user= *user_name;
definer->host= *host_name;
return definer;
}
...@@ -1060,18 +1060,36 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff) ...@@ -1060,18 +1060,36 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
default: default:
DBUG_ASSERT(0); // never should happen DBUG_ASSERT(0); // never should happen
} }
buff->append("DEFINER=", 8); append_definer(thd, buff, &table->definer.user, &table->definer.host);
append_identifier(thd, buff,
table->definer.user.str, table->definer.user.length);
buff->append('@');
append_identifier(thd, buff,
table->definer.host.str, table->definer.host.length);
if (table->view_suid) if (table->view_suid)
buff->append(" SQL SECURITY DEFINER ", 22); buff->append("SQL SECURITY DEFINER ", 21);
else else
buff->append(" SQL SECURITY INVOKER ", 22); buff->append("SQL SECURITY INVOKER ", 21);
} }
/*
Append DEFINER clause to the given buffer.
SYNOPSIS
append_definer()
thd [in] thread handle
buffer [inout] buffer to hold DEFINER clause
definer_user [in] user name part of definer
definer_host [in] host name part of definer
*/
void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
const LEX_STRING *definer_host)
{
buffer->append(STRING_WITH_LEN("DEFINER="));
append_identifier(thd, buffer, definer_user->str, definer_user->length);
buffer->append('@');
append_identifier(thd, buffer, definer_host->str, definer_host->length);
buffer->append(' ');
}
static int static int
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
{ {
...@@ -3094,7 +3112,8 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db, ...@@ -3094,7 +3112,8 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db,
enum trg_event_type event, enum trg_event_type event,
enum trg_action_time_type timing, enum trg_action_time_type timing,
LEX_STRING *trigger_stmt, LEX_STRING *trigger_stmt,
ulong sql_mode) ulong sql_mode,
LEX_STRING *definer_buffer)
{ {
CHARSET_INFO *cs= system_charset_info; CHARSET_INFO *cs= system_charset_info;
byte *sql_mode_str; byte *sql_mode_str;
...@@ -3119,6 +3138,7 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db, ...@@ -3119,6 +3138,7 @@ static bool store_trigger(THD *thd, TABLE *table, const char *db,
sql_mode, sql_mode,
&sql_mode_len); &sql_mode_len);
table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs); table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
return schema_table_store_record(thd, table); return schema_table_store_record(thd, table);
} }
...@@ -3152,15 +3172,21 @@ static int get_schema_triggers_record(THD *thd, struct st_table_list *tables, ...@@ -3152,15 +3172,21 @@ static int get_schema_triggers_record(THD *thd, struct st_table_list *tables,
LEX_STRING trigger_name; LEX_STRING trigger_name;
LEX_STRING trigger_stmt; LEX_STRING trigger_stmt;
ulong sql_mode; ulong sql_mode;
char definer_holder[HOSTNAME_LENGTH + USERNAME_LENGTH + 2];
LEX_STRING definer_buffer;
definer_buffer.str= definer_holder;
if (triggers->get_trigger_info(thd, (enum trg_event_type) event, if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
(enum trg_action_time_type)timing, (enum trg_action_time_type)timing,
&trigger_name, &trigger_stmt, &trigger_name, &trigger_stmt,
&sql_mode)) &sql_mode,
&definer_buffer))
continue; continue;
if (store_trigger(thd, table, base_name, file_name, &trigger_name, if (store_trigger(thd, table, base_name, file_name, &trigger_name,
(enum trg_event_type) event, (enum trg_event_type) event,
(enum trg_action_time_type) timing, &trigger_stmt, (enum trg_action_time_type) timing, &trigger_stmt,
sql_mode)) sql_mode,
&definer_buffer))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
...@@ -4064,6 +4090,7 @@ ST_FIELD_INFO triggers_fields_info[]= ...@@ -4064,6 +4090,7 @@ ST_FIELD_INFO triggers_fields_info[]=
{"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0}, {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0},
{"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"}, {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"}, {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
{"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0} {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
}; };
......
This diff is collapsed.
...@@ -55,6 +55,12 @@ class Table_triggers_list: public Sql_alloc ...@@ -55,6 +55,12 @@ class Table_triggers_list: public Sql_alloc
*/ */
LEX_STRING sroutines_key; LEX_STRING sroutines_key;
/*
is_special_var_used specifies whether trigger body contains special
variables (NEW/OLD).
*/
bool m_spec_var_used[TRG_EVENT_MAX][TRG_ACTION_MAX];
public: public:
/* /*
Field responsible for storing triggers definitions in file. Field responsible for storing triggers definitions in file.
...@@ -66,6 +72,8 @@ public: ...@@ -66,6 +72,8 @@ public:
*/ */
List<ulonglong> definition_modes_list; List<ulonglong> definition_modes_list;
List<LEX_STRING> definers_list;
Table_triggers_list(TABLE *table_arg): Table_triggers_list(TABLE *table_arg):
record1_field(0), table(table_arg) record1_field(0), table(table_arg)
{ {
...@@ -73,7 +81,9 @@ public: ...@@ -73,7 +81,9 @@ public:
} }
~Table_triggers_list(); ~Table_triggers_list();
bool create_trigger(THD *thd, TABLE_LIST *table); bool create_trigger(THD *thd, TABLE_LIST *table,
LEX_STRING *definer_user,
LEX_STRING *definer_host);
bool drop_trigger(THD *thd, TABLE_LIST *table); bool drop_trigger(THD *thd, TABLE_LIST *table);
bool process_triggers(THD *thd, trg_event_type event, bool process_triggers(THD *thd, trg_event_type event,
trg_action_time_type time_type, trg_action_time_type time_type,
...@@ -81,7 +91,8 @@ public: ...@@ -81,7 +91,8 @@ public:
bool get_trigger_info(THD *thd, trg_event_type event, bool get_trigger_info(THD *thd, trg_event_type event,
trg_action_time_type time_type, trg_action_time_type time_type,
LEX_STRING *trigger_name, LEX_STRING *trigger_stmt, LEX_STRING *trigger_name, LEX_STRING *trigger_stmt,
ulong *sql_mode); ulong *sql_mode,
LEX_STRING *definer);
static bool check_n_load(THD *thd, const char *db, const char *table_name, static bool check_n_load(THD *thd, const char *db, const char *table_name,
TABLE *table, bool names_only); TABLE *table, bool names_only);
...@@ -98,6 +109,11 @@ public: ...@@ -98,6 +109,11 @@ public:
return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]); return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]);
} }
inline bool is_special_var_used(int event, int action_time) const
{
return m_spec_var_used[event][action_time];
}
void set_table(TABLE *new_table); void set_table(TABLE *new_table);
friend class Item_trigger_field; friend class Item_trigger_field;
......
...@@ -214,29 +214,28 @@ bool mysql_create_view(THD *thd, ...@@ -214,29 +214,28 @@ bool mysql_create_view(THD *thd,
- same as current user - same as current user
- current user has SUPER_ACL - current user has SUPER_ACL
*/ */
if (strcmp(lex->create_view_definer->user.str, if (strcmp(lex->definer->user.str,
thd->security_ctx->priv_user) != 0 || thd->security_ctx->priv_user) != 0 ||
my_strcasecmp(system_charset_info, my_strcasecmp(system_charset_info,
lex->create_view_definer->host.str, lex->definer->host.str,
thd->security_ctx->priv_host) != 0) thd->security_ctx->priv_host) != 0)
{ {
if (!(thd->security_ctx->master_access & SUPER_ACL)) if (!(thd->security_ctx->master_access & SUPER_ACL))
{ {
my_error(ER_VIEW_OTHER_USER, MYF(0), lex->create_view_definer->user.str, my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
lex->create_view_definer->host.str);
res= TRUE; res= TRUE;
goto err; goto err;
} }
else else
{ {
if (!is_acl_user(lex->create_view_definer->host.str, if (!is_acl_user(lex->definer->host.str,
lex->create_view_definer->user.str)) lex->definer->user.str))
{ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_SUCH_USER, ER_NO_SUCH_USER,
ER(ER_NO_SUCH_USER), ER(ER_NO_SUCH_USER),
lex->create_view_definer->user.str, lex->definer->user.str,
lex->create_view_definer->host.str); lex->definer->host.str);
} }
} }
} }
...@@ -658,8 +657,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -658,8 +657,8 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
} }
view->algorithm= lex->create_view_algorithm; view->algorithm= lex->create_view_algorithm;
view->definer.user= lex->create_view_definer->user; view->definer.user= lex->definer->user;
view->definer.host= lex->create_view_definer->host; view->definer.host= lex->definer->host;
view->view_suid= lex->create_view_suid; view->view_suid= lex->create_view_suid;
view->with_check= lex->create_view_check; view->with_check= lex->create_view_check;
if ((view->updatable_view= (can_be_merged && if ((view->updatable_view= (can_be_merged &&
...@@ -807,7 +806,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) ...@@ -807,7 +806,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER), ER_VIEW_FRM_NO_USER, ER(ER_VIEW_FRM_NO_USER),
table->db, table->table_name); table->db, table->table_name);
if (default_view_definer(thd->security_ctx, &table->definer)) if (get_default_definer(thd, &table->definer))
goto err; goto err;
} }
......
This diff is collapsed.
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