Commit a32bf7fb authored by unknown's avatar unknown
Browse files

Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch)

  "Triggers have the wrong namespace"
  "Triggers: duplicate names allowed"
  "Triggers: CREATE TRIGGER does not accept fully qualified names"
  "SHOW TRIGGERS"


mysql-test/r/information_schema.result:
  Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command.
mysql-test/r/information_schema_db.result:
  INFORMATION_SCHEMA.TRIGGERS view was added.
mysql-test/r/rpl_sp.result:
  Now DROP TRIGGER interprets first part of trigger identifier as database
  name and not as table name. Adjusted tests properly.
mysql-test/r/trigger.result:
  Now DROP TRIGGER interprets first part of trigger identifier as database
  name and not as table name. Adjusted tests properly.
  Added test checking that triggers have database wide namespace.
  Added test for bug #8791 "Triggers: Allowed to create triggers on a subject
  table in a different DB".
mysql-test/r/view.result:
  Now DROP TRIGGER interprets first part of trigger identifier as database
  name and not as table name. Adjusted tests properly.
mysql-test/t/information_schema.test:
  Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command.
mysql-test/t/rpl_sp.test:
  Now DROP TRIGGER interprets first part of trigger identifier as database
  name and not as table name. Adjusted tests properly.
mysql-test/t/trigger.test:
  Now DROP TRIGGER interprets first part of trigger identifier as database
  name and not as table name. Adjusted tests properly.
  Added test checking that triggers have database wide namespace.
  Added test for bug #8791 "Triggers: Allowed to create triggers on a subject
  table in a different DB".
mysql-test/t/view.test:
  Now DROP TRIGGER interprets first part of trigger identifier as database
  name and not as table name. Adjusted tests properly.
sql/handler.cc:
  Added .TRN tho the list of known file extensions assoicated with tables.
sql/item.h:
  trg_action_time_type/trg_event_type enums:
    Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of
    magical values in various loops where we iterate through all types of trigger
    action times or/and trigger event types.
sql/lex.h:
  Added new symbol "TRIGGERS".
sql/mysql_priv.h:
  Added declaration of constant holding extension for trigger name (.TRN) files.
sql/mysqld.cc:
  Added statistical variable for SHOW TRIGGERS command.
sql/share/errmsg.txt:
  Added error message saying that one attempts to create trigger in wrong schema.
sql/sp.cc:
  Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants.
sql/sql_base.cc:
  open_unireg_entry():
    Now Table_triggers_list::check_n_load() has one more argument which
    controls whether we should prepare Table_triggers_list with fully functional
    triggers or load only their names.
sql/sql_lex.h:
  Added element for new SHOW TRIGGERS command to enum_sql_command enum.
sql/sql_parse.cc:
  prepare_schema_table():
    Added support for SHOW TRIGGERS statement.
sql/sql_show.cc:
  Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command.
sql/sql_table.cc:
  mysql_rm_table_part2():
    Replaced simple deletion of .TRG file with call to
    Table_triggers_list::drop_all_triggers which will also delete .TRN files
    for all triggers associated with table.
sql/sql_trigger.cc:
  Now triggers have database wide namespace. To support it we create special .TRN
  file with same name as trigger for each trigger. This file contains name of
  trigger's table so one does not need to specify it explicitly in DROP TRIGGER.
  Moreover DROP TRIGGER treats first part of trigger identifier as database name
  now. Updated mysql_create_or_drop_trigger() routine and
  Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods
  accordingly. Added add_table_for_trigger() routine and
  Table_triggers_list::drop_all_triggers() method.
  
  Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata.
sql/sql_trigger.h:
  Table_triggers_list:
    Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values.
    Added get_trigger_info() method for obtaining trigger's meta-data.
    Added drop_all_triggers() method which drops all triggers for table.
    Added declarations of trg_action_time_type_names/trg_event_type_names
    arrays which hold names of triggers action time types  and event types.
sql/sql_yacc.yy:
  Changed grammar for CREATE/DROP TRIGGER to support database wide trigger
  namespace. Added new SHOW TRIGGERS statement.
sql/table.h:
  enum enum_schema_tables:
    Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
parent e155a0c0
Loading
Loading
Loading
Loading
+75 −2
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ TABLE_PRIVILEGES
COLUMN_PRIVILEGES
TABLE_CONSTRAINTS
KEY_COLUMN_USAGE
TRIGGERS
columns_priv
db
func
@@ -77,6 +78,7 @@ c table_name
TABLES	TABLES
TABLE_PRIVILEGES	TABLE_PRIVILEGES
TABLE_CONSTRAINTS	TABLE_CONSTRAINTS
TRIGGERS	TRIGGERS
tables_priv	tables_priv
time_zone	time_zone
time_zone_leap_second	time_zone_leap_second
@@ -94,6 +96,7 @@ c table_name
TABLES	TABLES
TABLE_PRIVILEGES	TABLE_PRIVILEGES
TABLE_CONSTRAINTS	TABLE_CONSTRAINTS
TRIGGERS	TRIGGERS
tables_priv	tables_priv
time_zone	time_zone
time_zone_leap_second	time_zone_leap_second
@@ -111,6 +114,7 @@ c table_name
TABLES	TABLES
TABLE_PRIVILEGES	TABLE_PRIVILEGES
TABLE_CONSTRAINTS	TABLE_CONSTRAINTS
TRIGGERS	TRIGGERS
tables_priv	tables_priv
time_zone	time_zone
time_zone_leap_second	time_zone_leap_second
@@ -577,6 +581,7 @@ Tables_in_information_schema (T%)
TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TRIGGERS
create database information_schema;
ERROR HY000: Can't create database 'information_schema'; database exists
use information_schema;
@@ -585,6 +590,7 @@ Tables_in_information_schema (T%) Table_type
TABLES	TEMPORARY
TABLE_PRIVILEGES	TEMPORARY
TABLE_CONSTRAINTS	TEMPORARY
TRIGGERS	TEMPORARY
create table t1(a int);
ERROR 42S02: Unknown table 't1' in information_schema
use test;
@@ -596,6 +602,7 @@ Tables_in_information_schema (T%)
TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TRIGGERS
select table_name from tables where table_name='user';
table_name
user
@@ -690,7 +697,7 @@ CREATE TABLE t_crashme ( f1 BIGINT);
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
count(*)
100
101
drop view a2, a1;
drop table t_crashme;
select table_schema,table_name, column_name from
@@ -701,6 +708,8 @@ information_schema COLUMNS COLUMN_TYPE
information_schema	ROUTINES	ROUTINE_DEFINITION
information_schema	ROUTINES	SQL_MODE
information_schema	VIEWS	VIEW_DEFINITION
information_schema	TRIGGERS	ACTION_CONDITION
information_schema	TRIGGERS	ACTION_STATEMENT
select table_name, column_name, data_type from information_schema.columns
where data_type = 'datetime';
table_name	column_name	data_type
@@ -709,6 +718,7 @@ TABLES UPDATE_TIME datetime
TABLES	CHECK_TIME	datetime
ROUTINES	CREATED	datetime
ROUTINES	LAST_ALTERED	datetime
TRIGGERS	CREATED	datetime
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A
WHERE NOT EXISTS 
(SELECT * FROM INFORMATION_SCHEMA.COLUMNS B
@@ -755,8 +765,71 @@ delete from mysql.db where user='mysqltest_4';
flush privileges;
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
table_schema	count(*)
information_schema	15
information_schema	16
mysql	17
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
begin
if new.j > 10 then
set new.j := 10;
end if;
end|
create trigger trg2 before update on t1 for each row
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end|
create trigger trg3 after update on t1 for each row
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end|
show triggers;
Trigger	Event	Table	Statement	Timing	Created
trg1	INSERT	t1	
begin
if new.j > 10 then
set new.j := 10;
end if;
end	BEFORE	NULL
trg2	UPDATE	t1	
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end	BEFORE	NULL
trg3	UPDATE	t1	
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end	AFTER	NULL
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
NULL	test	trg1	INSERT	NULL	test	t1	0	NULL	
begin
if new.j > 10 then
set new.j := 10;
end if;
end	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL
NULL	test	trg2	UPDATE	NULL	test	t1	0	NULL	
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL
NULL	test	trg3	UPDATE	NULL	test	t1	0	NULL	
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end	ROW	AFTER	NULL	NULL	OLD	NEW	NULL
drop trigger trg1;
drop trigger trg2;
drop trigger trg3;
drop table t1;
create database mysqltest;
create table mysqltest.t1 (f1 int, f2 int);
create table mysqltest.t2 (f1 int);
+2 −0
Original line number Diff line number Diff line
@@ -16,11 +16,13 @@ TABLE_PRIVILEGES
COLUMN_PRIVILEGES
TABLE_CONSTRAINTS
KEY_COLUMN_USAGE
TRIGGERS
show tables from INFORMATION_SCHEMA like 'T%';
Tables_in_information_schema (T%)
TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TRIGGERS
create database `inf%`;
use `inf%`;
show tables;
+2 −2
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ select * from t1;
a
10
delete from t1;
drop trigger t1.trg;
drop trigger trg;
insert into t1 values (1);
select * from t1;
a
@@ -248,7 +248,7 @@ master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000002	#	Query	1	#	use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10
master-bin.000002	#	Query	1	#	use `mysqltest1`; insert into t1 values (1)
master-bin.000002	#	Query	1	#	use `mysqltest1`; delete from t1
master-bin.000002	#	Query	1	#	use `mysqltest1`; drop trigger t1.trg
master-bin.000002	#	Query	1	#	use `mysqltest1`; drop trigger trg
master-bin.000002	#	Query	1	#	use `mysqltest1`; insert into t1 values (1)
select * from t1;
a
+34 −19
Original line number Diff line number Diff line
@@ -12,13 +12,13 @@ insert into t1 values (1);
select @a;
@a
1
drop trigger t1.trg;
drop trigger trg;
create trigger trg before insert on t1 for each row set @a:=new.i;
insert into t1 values (123);
select @a;
@a
123
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int not null, j int);
create trigger trg before insert on t1 for each row 
@@ -33,7 +33,7 @@ select * from t1|
i	j
1	10
2	3
drop trigger t1.trg|
drop trigger trg|
drop table t1|
create table t1 (i int not null primary key);
create trigger trg after insert on t1 for each row 
@@ -43,7 +43,7 @@ insert into t1 values (2),(3),(4),(5);
select @a;
@a
2:3:4:5
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (aid int not null primary key, balance int not null default 0);
insert into t1 values (1, 1000), (2,3000);
@@ -65,7 +65,7 @@ Too big change for aid = 2
aid	balance
1	1500
2	3000
drop trigger t1.trg|
drop trigger trg|
drop table t1|
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
@@ -76,7 +76,7 @@ update t1 set i=3;
select @total_change;
@total_change
2
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
@@ -87,7 +87,7 @@ delete from t1 where i <= 3;
select @del_sum;
@del_sum
6
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
@@ -97,7 +97,7 @@ delete from t1 where i <> 0;
select @del;
@del
1
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row 
@@ -137,9 +137,9 @@ i j
1	20
2	-1
3	20
drop trigger t1.trg1;
drop trigger t1.trg2;
drop trigger t1.trg3;
drop trigger trg1;
drop trigger trg2;
drop trigger trg3;
drop table t1;
create table t1 (id int not null primary key, data int);
create trigger t1_bi before insert on t1 for each row
@@ -197,7 +197,7 @@ select * from t2;
event
INSERT INTO t1 id=1 data='one'
INSERT INTO t1 id=2 data='two'
drop trigger t1.t1_ai;
drop trigger t1_ai;
create trigger t1_bi before insert on t1 for each row
begin
if exists (select id from t3 where id=new.fk) then
@@ -271,6 +271,7 @@ id copy
3	NULL
drop table t1, t2;
create table t1 (i int);
create table t3 (i int);
create trigger trg before insert on t1 for each row set @a:= old.i;
ERROR HY000: There is no OLD row in on INSERT trigger
create trigger trg before delete on t1 for each row set @a:= new.i;
@@ -292,14 +293,19 @@ create trigger trg after insert on t1 for each row set @a:=1;
ERROR HY000: Trigger already exists
create trigger trg2 before insert on t1 for each row set @a:=1;
ERROR HY000: Trigger already exists
drop trigger t1.trg;
drop trigger t1.trg;
create trigger trg before insert on t3 for each row set @a:=1;
ERROR HY000: Trigger already exists
create trigger trg2 before insert on t3 for each row set @a:=1;
drop trigger trg2;
drop trigger trg;
drop trigger trg;
ERROR HY000: Trigger does not exist
create view v1 as select * from t1;
create trigger trg before insert on v1 for each row set @a:=1;
ERROR HY000: 'test.v1' is not BASE TABLE
drop view v1;
drop table t1;
drop table t3;
create temporary table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1;
ERROR HY000: Trigger's 't1' is view or temporary table
@@ -307,7 +313,7 @@ drop table t1;
create table t1 (x1col char);
create trigger tx1 before insert on t1 for each row set new.x1col = 'x';
insert into t1 values ('y');
drop trigger t1.tx1;
drop trigger tx1;
drop table t1;
create table t1 (i int) engine=myisam;
insert into t1 values (1), (2);
@@ -318,8 +324,8 @@ delete from t1;
select @del_before, @del_after;
@del_before	@del_after
3	3
drop trigger t1.trg1;
drop trigger t1.trg2;
drop trigger trg1;
drop trigger trg2;
drop table t1;
create table t1 (a int);
create trigger trg1 before insert on t1 for each row set new.a= 10;
@@ -336,6 +342,15 @@ create table t1 (i int);
create trigger trg1 before insert on t1 for each row set @a:= 1;
drop database mysqltest;
use test;
create database mysqltest;
create table mysqltest.t1 (i int);
create trigger trg1 before insert on mysqltest.t1 for each row set @a:= 1;
ERROR HY000: Trigger in wrong schema
use mysqltest;
create trigger test.trg1 before insert on t1 for each row set @a:= 1;
ERROR HY000: Trigger in wrong schema
drop database mysqltest;
use test;
create table t1 (i int, j int default 10, k int not null, key (k));
create table t2 (i int);
insert into t1 (i, k) values (1, 1);
@@ -549,7 +564,7 @@ i k
1	1
2	2
alter table t1 add primary key (i);
drop trigger t1.bi;
drop trigger bi;
insert into t1 values (2, 4) on duplicate key update k= k + 10;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
@@ -578,5 +593,5 @@ create trigger t1_bu before update on t1 for each row set new.col1= bug5893();
drop function bug5893;
update t1 set col2 = 4;
ERROR 42000: FUNCTION test.bug5893 does not exist
drop trigger t1.t1_bu;
drop trigger t1_bu;
drop table t1;
+1 −1
Original line number Diff line number Diff line
@@ -1245,7 +1245,7 @@ select * from v1;
s1
select * from t1;
s1
drop trigger t1.t1_bi;
drop trigger t1_bi;
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
Loading