diff options
73 files changed, 2544 insertions, 1166 deletions
diff --git a/mysql-test/extra/rpl_tests/rpl_ddl.test b/mysql-test/extra/rpl_tests/rpl_ddl.test index e466a08a541..f11cd979ba8 100644 --- a/mysql-test/extra/rpl_tests/rpl_ddl.test +++ b/mysql-test/extra/rpl_tests/rpl_ddl.test @@ -473,8 +473,10 @@ let $my_stmt= CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; let $my_master_commit= true; let $my_slave_commit= true; --source include/rpl_stmt_seq.inc +--replace_column 6 # SHOW TRIGGERS; connection slave; +--replace_column 6 # SHOW TRIGGERS; connection master; diff --git a/mysql-test/include/ddl_i18n.check_triggers.inc b/mysql-test/include/ddl_i18n.check_triggers.inc index 832ab8091e8..2073021fc9e 100644 --- a/mysql-test/include/ddl_i18n.check_triggers.inc +++ b/mysql-test/include/ddl_i18n.check_triggers.inc @@ -3,12 +3,16 @@ --echo --echo +--replace_column 7 # SHOW CREATE TRIGGER trg1| --echo +--replace_column 7 # SHOW CREATE TRIGGER trg2| --echo +--replace_column 7 # SHOW CREATE TRIGGER mysqltest2.trg3| --echo +--replace_column 7 # SHOW CREATE TRIGGER mysqltest2.trg4| # - Check SHOW statement; @@ -16,6 +20,7 @@ SHOW CREATE TRIGGER mysqltest2.trg4| --echo --echo +--replace_column 6 # SHOW TRIGGERS| --echo @@ -24,6 +29,7 @@ use mysqltest2| --echo +--replace_column 6 # SHOW TRIGGERS| use mysqltest1| diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 36a192c2609..dd10628bce5 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1352,7 +1352,6 @@ CREATE TRIGGER f1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN UPDATE A SET `pk`=1 WHERE `pk`=0 ; END ;| -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' DROP TABLE t1; DROP TABLE B; # diff --git a/mysql-test/r/create_drop_trigger.result b/mysql-test/r/create_drop_trigger.result index a215838b0fd..f7ae8d21a7f 100644 --- a/mysql-test/r/create_drop_trigger.result +++ b/mysql-test/r/create_drop_trigger.result @@ -8,7 +8,6 @@ SELECT @sum; @sum 60 CREATE TRIGGER IF NOT EXISTS val_sum_new BEFORE INSERT ON t1 FOR EACH ROW SET @sum = @sum + NEW.val; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' CREATE TRIGGER IF NOT EXISTS val_sum AFTER INSERT ON t1 FOR EACH ROW SET @sum = @sum + 1 + NEW.val; Warnings: Note 1359 Trigger already exists diff --git a/mysql-test/r/ddl_i18n_koi8r.result b/mysql-test/r/ddl_i18n_koi8r.result index 8423f8fe367..ba43c1c867f 100644 --- a/mysql-test/r/ddl_i18n_koi8r.result +++ b/mysql-test/r/ddl_i18n_koi8r.result @@ -1198,7 +1198,7 @@ END| SHOW CREATE TRIGGER trg1| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg1 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); @@ -1211,10 +1211,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = _koi8r 'ÔÅËÓÔ'; SET @a2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER trg2| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg2 CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; @@ -1227,10 +1227,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = _koi8r 'ÔÅËÓÔ'; SET @b2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg3| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg3 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); @@ -1243,10 +1243,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = _koi8r 'ÔÅËÓÔ'; SET @a2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg4| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg4 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; @@ -1259,7 +1259,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = _koi8r 'ÔÅËÓÔ'; SET @b2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW TRIGGERS| @@ -1275,7 +1275,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = 'ÔÅËÓÔ'; SET @a2 = 'ÔÅËÓÔ'; -END BEFORE NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END BEFORE # root@localhost koi8r koi8r_general_ci utf8_unicode_ci trg2 INSERT t1 BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); @@ -1287,7 +1287,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = 'ÔÅËÓÔ'; SET @b2 = 'ÔÅËÓÔ'; -END AFTER NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END AFTER # root@localhost koi8r koi8r_general_ci utf8_unicode_ci use mysqltest2| @@ -1304,7 +1304,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = 'ÔÅËÓÔ'; SET @a2 = 'ÔÅËÓÔ'; -END BEFORE NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END BEFORE # root@localhost koi8r koi8r_general_ci utf8_unicode_ci trg4 INSERT t1 BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); @@ -1316,13 +1316,13 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = 'ÔÅËÓÔ'; SET @b2 = 'ÔÅËÓÔ'; -END AFTER NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END AFTER # root@localhost koi8r koi8r_general_ci utf8_unicode_ci use mysqltest1| SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg1'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg1 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg1 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1337,7 +1337,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg2 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg2 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1352,7 +1352,7 @@ END ROW AFTER NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci u SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg3 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg3 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1367,7 +1367,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg4 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg4 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1470,7 +1470,7 @@ use mysqltest1| SHOW CREATE TRIGGER trg1| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg1 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); @@ -1483,10 +1483,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = _koi8r 'ÔÅËÓÔ'; SET @a2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER trg2| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg2 CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; @@ -1499,10 +1499,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = _koi8r 'ÔÅËÓÔ'; SET @b2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg3| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg3 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); @@ -1515,10 +1515,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = _koi8r 'ÔÅËÓÔ'; SET @a2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg4| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg4 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; @@ -1531,7 +1531,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = _koi8r 'ÔÅËÓÔ'; SET @b2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW TRIGGERS| @@ -1547,7 +1547,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = 'ÔÅËÓÔ'; SET @a2 = 'ÔÅËÓÔ'; -END BEFORE NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END BEFORE # root@localhost koi8r koi8r_general_ci utf8_unicode_ci trg2 INSERT t1 BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); @@ -1559,7 +1559,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = 'ÔÅËÓÔ'; SET @b2 = 'ÔÅËÓÔ'; -END AFTER NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END AFTER # root@localhost koi8r koi8r_general_ci utf8_unicode_ci use mysqltest2| @@ -1576,7 +1576,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = 'ÔÅËÓÔ'; SET @a2 = 'ÔÅËÓÔ'; -END BEFORE NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END BEFORE # root@localhost koi8r koi8r_general_ci utf8_unicode_ci trg4 INSERT t1 BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); @@ -1588,13 +1588,13 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = 'ÔÅËÓÔ'; SET @b2 = 'ÔÅËÓÔ'; -END AFTER NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END AFTER # root@localhost koi8r koi8r_general_ci utf8_unicode_ci use mysqltest1| SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg1'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg1 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg1 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1609,7 +1609,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg2 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg2 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1624,7 +1624,7 @@ END ROW AFTER NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci u SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg3 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg3 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1639,7 +1639,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg4 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg4 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -1904,7 +1904,7 @@ use mysqltest1| SHOW CREATE TRIGGER trg1| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg1 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); @@ -1917,10 +1917,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = _koi8r 'ÔÅËÓÔ'; SET @a2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER trg2| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg2 CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; @@ -1933,10 +1933,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = _koi8r 'ÔÅËÓÔ'; SET @b2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg3| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg3 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); @@ -1949,10 +1949,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = _koi8r 'ÔÅËÓÔ'; SET @a2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg4| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg4 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; @@ -1965,7 +1965,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = _koi8r 'ÔÅËÓÔ'; SET @b2 = _utf8 'текÑÑ‚'; -END koi8r koi8r_general_ci utf8_unicode_ci +END koi8r koi8r_general_ci utf8_unicode_ci # SHOW TRIGGERS| @@ -1981,7 +1981,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = 'ÔÅËÓÔ'; SET @a2 = 'ÔÅËÓÔ'; -END BEFORE NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END BEFORE # root@localhost koi8r koi8r_general_ci utf8_unicode_ci trg2 INSERT t1 BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); @@ -1993,7 +1993,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = 'ÔÅËÓÔ'; SET @b2 = 'ÔÅËÓÔ'; -END AFTER NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END AFTER # root@localhost koi8r koi8r_general_ci utf8_unicode_ci use mysqltest2| @@ -2010,7 +2010,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'ÔÅËÓÔ'; SET @a1 = 'ÔÅËÓÔ'; SET @a2 = 'ÔÅËÓÔ'; -END BEFORE NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END BEFORE # root@localhost koi8r koi8r_general_ci utf8_unicode_ci trg4 INSERT t1 BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); @@ -2022,13 +2022,13 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'ÔÅËÓÔ'; SET @b1 = 'ÔÅËÓÔ'; SET @b2 = 'ÔÅËÓÔ'; -END AFTER NULL root@localhost koi8r koi8r_general_ci utf8_unicode_ci +END AFTER # root@localhost koi8r koi8r_general_ci utf8_unicode_ci use mysqltest1| SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg1'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg1 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg1 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -2043,7 +2043,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg2 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg2 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -2058,7 +2058,7 @@ END ROW AFTER NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci u SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg3 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg3 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10); INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); @@ -2073,7 +2073,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost koi8r koi8r_general_ci SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg4 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg4 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE ÐÅÒÅÍ1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(ÐÅÒÅÍ1)); INSERT INTO log VALUES(COLLATION('ÔÅËÓÔ')); diff --git a/mysql-test/r/ddl_i18n_utf8.result b/mysql-test/r/ddl_i18n_utf8.result index 2c9ea77b809..47786196037 100644 --- a/mysql-test/r/ddl_i18n_utf8.result +++ b/mysql-test/r/ddl_i18n_utf8.result @@ -1198,7 +1198,7 @@ END| SHOW CREATE TRIGGER trg1| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg1 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10); @@ -1211,10 +1211,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = _utf8 'текÑÑ‚'; SET @a3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER trg2| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg2 CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; @@ -1227,10 +1227,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = _utf8 'текÑÑ‚'; SET @b3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg3| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg3 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10); @@ -1243,10 +1243,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = _utf8 'текÑÑ‚'; SET @a3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg4| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg4 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; @@ -1259,7 +1259,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = _utf8 'текÑÑ‚'; SET @b3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW TRIGGERS| @@ -1275,7 +1275,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = 'текÑÑ‚'; SET @a3 = 'текÑÑ‚'; -END BEFORE NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END BEFORE # root@localhost utf8 utf8_general_ci utf8_unicode_ci trg2 INSERT t1 BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); @@ -1287,7 +1287,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = 'текÑÑ‚'; SET @b3 = 'текÑÑ‚'; -END AFTER NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END AFTER # root@localhost utf8 utf8_general_ci utf8_unicode_ci use mysqltest2| @@ -1304,7 +1304,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = 'текÑÑ‚'; SET @a3 = 'текÑÑ‚'; -END BEFORE NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END BEFORE # root@localhost utf8 utf8_general_ci utf8_unicode_ci trg4 INSERT t1 BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); @@ -1316,13 +1316,13 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = 'текÑÑ‚'; SET @b3 = 'текÑÑ‚'; -END AFTER NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END AFTER # root@localhost utf8 utf8_general_ci utf8_unicode_ci use mysqltest1| SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg1'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg1 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg1 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE перем1 CHAR(10); INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1337,7 +1337,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci ut SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg2 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg2 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1352,7 +1352,7 @@ END ROW AFTER NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci utf SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg3 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg3 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE перем1 CHAR(10); INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1367,7 +1367,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci ut SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg4 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg4 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1470,7 +1470,7 @@ use mysqltest1| SHOW CREATE TRIGGER trg1| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg1 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10); @@ -1483,10 +1483,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = _utf8 'текÑÑ‚'; SET @a3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER trg2| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg2 CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; @@ -1499,10 +1499,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = _utf8 'текÑÑ‚'; SET @b3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg3| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg3 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10); @@ -1515,10 +1515,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = _utf8 'текÑÑ‚'; SET @a3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg4| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg4 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; @@ -1531,7 +1531,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = _utf8 'текÑÑ‚'; SET @b3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW TRIGGERS| @@ -1547,7 +1547,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = 'текÑÑ‚'; SET @a3 = 'текÑÑ‚'; -END BEFORE NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END BEFORE # root@localhost utf8 utf8_general_ci utf8_unicode_ci trg2 INSERT t1 BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); @@ -1559,7 +1559,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = 'текÑÑ‚'; SET @b3 = 'текÑÑ‚'; -END AFTER NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END AFTER # root@localhost utf8 utf8_general_ci utf8_unicode_ci use mysqltest2| @@ -1576,7 +1576,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = 'текÑÑ‚'; SET @a3 = 'текÑÑ‚'; -END BEFORE NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END BEFORE # root@localhost utf8 utf8_general_ci utf8_unicode_ci trg4 INSERT t1 BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); @@ -1588,13 +1588,13 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = 'текÑÑ‚'; SET @b3 = 'текÑÑ‚'; -END AFTER NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END AFTER # root@localhost utf8 utf8_general_ci utf8_unicode_ci use mysqltest1| SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg1'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg1 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg1 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE перем1 CHAR(10); INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1609,7 +1609,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci ut SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg2 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg2 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1624,7 +1624,7 @@ END ROW AFTER NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci utf SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg3 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg3 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE перем1 CHAR(10); INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1639,7 +1639,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci ut SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg4 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg4 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -1904,7 +1904,7 @@ use mysqltest1| SHOW CREATE TRIGGER trg1| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg1 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10); @@ -1917,10 +1917,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = _utf8 'текÑÑ‚'; SET @a3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER trg2| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg2 CREATE DEFINER=`root`@`localhost` TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; @@ -1933,10 +1933,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = _utf8 'текÑÑ‚'; SET @b3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg3| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg3 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg3 BEFORE INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10); @@ -1949,10 +1949,10 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = _utf8 'текÑÑ‚'; SET @a3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW CREATE TRIGGER mysqltest2.trg4| -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created trg4 CREATE DEFINER=`root`@`localhost` TRIGGER mysqltest2.trg4 AFTER INSERT ON mysqltest2.t1 FOR EACH ROW BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; @@ -1965,7 +1965,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = _utf8 'текÑÑ‚'; SET @b3 = _koi8r 'ÔÅËÓÔ'; -END utf8 utf8_general_ci utf8_unicode_ci +END utf8 utf8_general_ci utf8_unicode_ci # SHOW TRIGGERS| @@ -1981,7 +1981,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = 'текÑÑ‚'; SET @a3 = 'текÑÑ‚'; -END BEFORE NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END BEFORE # root@localhost utf8 utf8_general_ci utf8_unicode_ci trg2 INSERT t1 BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); @@ -1993,7 +1993,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = 'текÑÑ‚'; SET @b3 = 'текÑÑ‚'; -END AFTER NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END AFTER # root@localhost utf8 utf8_general_ci utf8_unicode_ci use mysqltest2| @@ -2010,7 +2010,7 @@ INSERT INTO log VALUES(@@character_set_client); SET @a1 = 'текÑÑ‚'; SET @a2 = 'текÑÑ‚'; SET @a3 = 'текÑÑ‚'; -END BEFORE NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END BEFORE # root@localhost utf8 utf8_general_ci utf8_unicode_ci trg4 INSERT t1 BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); @@ -2022,13 +2022,13 @@ INSERT INTO log VALUES(@@character_set_client); SET @b1 = 'текÑÑ‚'; SET @b2 = 'текÑÑ‚'; SET @b3 = 'текÑÑ‚'; -END AFTER NULL root@localhost utf8 utf8_general_ci utf8_unicode_ci +END AFTER # root@localhost utf8 utf8_general_ci utf8_unicode_ci use mysqltest1| SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg1'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg1 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg1 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE перем1 CHAR(10); INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -2043,7 +2043,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci ut SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg2'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest1 trg2 INSERT def mysqltest1 t1 0 NULL BEGIN +def mysqltest1 trg2 INSERT def mysqltest1 t1 1 NULL BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -2058,7 +2058,7 @@ END ROW AFTER NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci utf SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg3'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg3 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg3 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE перем1 CHAR(10); INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); @@ -2073,7 +2073,7 @@ END ROW BEFORE NULL NULL OLD NEW CREATED root@localhost utf8 utf8_general_ci ut SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 'trg4'| 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest2 trg4 INSERT def mysqltest2 t1 0 NULL BEGIN +def mysqltest2 trg4 INSERT def mysqltest2 t1 1 NULL BEGIN DECLARE перем1 CHAR(10) CHARACTER SET utf8; INSERT INTO log VALUES(COLLATION(перем1)); INSERT INTO log VALUES(COLLATION('текÑÑ‚')); diff --git a/mysql-test/r/features.result b/mysql-test/r/features.result index b6a3ffa11ad..c6d1a6b0bac 100644 --- a/mysql-test/r/features.result +++ b/mysql-test/r/features.result @@ -118,7 +118,7 @@ select @a; 1 SHOW TRIGGERS IN test like 't1'; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg INSERT t1 set @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg INSERT t1 set @a:=1 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci drop trigger trg; drop table t1; show status like "%trigger%"; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index c7a4edba65a..8be595a55f1 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -964,34 +964,34 @@ trg1 INSERT t1 begin if new.j > 10 then set new.j := 10; end if; -end BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci trg2 UPDATE t1 begin if old.i % 2 = 0 then set new.j := -1; end if; -end BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci trg3 UPDATE t1 begin if new.j = -1 then set @fired:= "Yes"; end if; -end AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci select * from information_schema.triggers where trigger_schema in ('mysql', 'information_schema', 'test', 'mysqltest'); 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def test trg1 INSERT def test t1 0 NULL begin +def test trg1 INSERT def test t1 1 NULL begin if new.j > 10 then set new.j := 10; end if; -end ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -def test trg2 UPDATE def test t1 0 NULL begin +end ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def test trg2 UPDATE def test t1 1 NULL begin if old.i % 2 = 0 then set new.j := -1; end if; -end ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -def test trg3 UPDATE def test t1 0 NULL begin +end ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def test trg3 UPDATE def test t1 1 NULL begin if new.j = -1 then set @fired:= "Yes"; end if; -end ROW AFTER NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +end ROW AFTER NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci drop trigger trg1; drop trigger trg2; drop trigger trg3; @@ -1406,7 +1406,7 @@ trigger_name t1_ai show triggers from mysqltest; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -t1_ai INSERT t1 set @a = new.a + new.b + new.c AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +t1_ai INSERT t1 set @a = new.a + new.b + new.c AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci connect con27629,localhost,mysqltest_1,,mysqltest; show columns from t1; Field Type Null Key Default Extra diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 93b16896380..7f34d0a9217 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -2289,8 +2289,8 @@ CREATE TABLE t2(a int); CREATE TABLE t3(a int) ENGINE = MERGE UNION(t1, t2); CREATE TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo(); SHOW CREATE TRIGGER tr1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -tr1 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo() latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo() latin1 latin1_swedish_ci latin1_swedish_ci # DROP TRIGGER tr1; DROP TABLE t1, t2, t3; # diff --git a/mysql-test/r/mysql_comments.result b/mysql-test/r/mysql_comments.result index 4865c7a7af0..9ba8dff3d55 100644 --- a/mysql-test/r/mysql_comments.result +++ b/mysql-test/r/mysql_comments.result @@ -27,10 +27,10 @@ Procedure sql_mode Create Procedure character_set_client collation_connection Da foosp CREATE DEFINER=`root`@`localhost` PROCEDURE `foosp`()\ninsert into test.t1\n\n\n\n\n \n\n \n values ("foo", 42) latin1 latin1_swedish_ci latin1_swedish_ci Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation nicesp CREATE DEFINER=`root`@`localhost` PROCEDURE `nicesp`(a int)\nbegin\n \n declare b int;\n declare c float;\n\n \n \n\n \nend latin1 latin1_swedish_ci latin1_swedish_ci -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_empty CREATE DEFINER=`root`@`localhost` trigger t1_empty after delete on t1\nfor each row\nbegin\nend latin1 latin1_swedish_ci latin1_swedish_ci -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi CREATE DEFINER=`root`@`localhost` trigger t1_bi before insert on t1\nfor each row\nbegin\n\n\n\n \n declare b int;\n declare c float;\n\n \n \n\n \n set NEW.data := 12;\nend latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_empty CREATE DEFINER=`root`@`localhost` trigger t1_empty after delete on t1\nfor each row\nbegin\nend latin1 latin1_swedish_ci latin1_swedish_ci --TIME-- +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi CREATE DEFINER=`root`@`localhost` trigger t1_bi before insert on t1\nfor each row\nbegin\n\n\n\n \n declare b int;\n declare c float;\n\n \n \n\n \n set NEW.data := 12;\nend latin1 latin1_swedish_ci latin1_swedish_ci --TIME-- id data trig 12 "Pass 2 : --enable-comments" @@ -54,10 +54,10 @@ Procedure sql_mode Create Procedure character_set_client collation_connection Da foosp CREATE DEFINER=`root`@`localhost` PROCEDURE `foosp`()\ninsert into test.t1\n## These comments are part of the procedure body, and should be kept.\n# Comment 2a\n-- Comment 2b\n/* Comment 2c */\n -- empty line below\n\n -- empty line above\n values ("foo", 42) # comment 3, still part of the body latin1 latin1_swedish_ci latin1_swedish_ci Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation nicesp CREATE DEFINER=`root`@`localhost` PROCEDURE `nicesp`(a int)\nbegin\n -- declare some variables here\n declare b int;\n declare c float;\n\n -- do more stuff here\n -- commented nicely and so on\n\n -- famous last words ...\nend latin1 latin1_swedish_ci latin1_swedish_ci -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_empty CREATE DEFINER=`root`@`localhost` trigger t1_empty after delete on t1\nfor each row\nbegin\nend latin1 latin1_swedish_ci latin1_swedish_ci -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi CREATE DEFINER=`root`@`localhost` trigger t1_bi before insert on t1\nfor each row\nbegin\n# comment 1a\n-- comment 1b\n/*\n comment 1c\n*/\n -- declare some variables here\n declare b int;\n declare c float;\n\n -- do more stuff here\n -- commented nicely and so on\n\n -- famous last words ...\n set NEW.data := 12;\nend latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_empty CREATE DEFINER=`root`@`localhost` trigger t1_empty after delete on t1\nfor each row\nbegin\nend latin1 latin1_swedish_ci latin1_swedish_ci --TIME-- +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi CREATE DEFINER=`root`@`localhost` trigger t1_bi before insert on t1\nfor each row\nbegin\n# comment 1a\n-- comment 1b\n/*\n comment 1c\n*/\n -- declare some variables here\n declare b int;\n declare c float;\n\n -- do more stuff here\n -- commented nicely and so on\n\n -- famous last words ...\n set NEW.data := 12;\nend latin1 latin1_swedish_ci latin1_swedish_ci --TIME-- id data trig 12 set global sql_mode=default; diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index 8894616fbb3..ff9cc5d5c81 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -241,15 +241,15 @@ CREATE TABLE t1 (a INT) engine=myisam; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA="#mysql50#a@b" 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def #mysql50#a@b tr1 INSERT def #mysql50#a@b #mysql50#c@d 0 NULL SET NEW.a = 10 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -def #mysql50#a@b tr2 INSERT def #mysql50#a@b t1 0 NULL SET NEW.a = 100 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def #mysql50#a@b tr1 INSERT def #mysql50#a@b #mysql50#c@d 1 NULL SET NEW.a = 10 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def #mysql50#a@b tr2 INSERT def #mysql50#a@b t1 1 NULL SET NEW.a = 100 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci mysqlcheck --fix-db-names --fix-table-names --all-databases USE `a@b`; SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA="a@b" 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def a@b tr1 INSERT def a@b c@d 0 NULL SET NEW.a = 10 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost utf8 utf8_general_ci latin1_swedish_ci -def a@b tr2 INSERT def a@b t1 0 NULL SET NEW.a = 100 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost utf8 utf8_general_ci latin1_swedish_ci +def a@b tr1 INSERT def a@b c@d 1 NULL SET NEW.a = 10 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost utf8 utf8_general_ci latin1_swedish_ci +def a@b tr2 INSERT def a@b t1 1 NULL SET NEW.a = 100 * NEW.a ROW BEFORE NULL NULL OLD NEW NULL root@localhost utf8 utf8_general_ci latin1_swedish_ci INSERT INTO `c@d` VALUES (2), (1); SELECT * FROM `c@d`; a diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 98594973467..04612e02b7f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2717,7 +2717,7 @@ a2 SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation testref INSERT test1 BEGIN -INSERT INTO test2 SET a2 = NEW.a1; END BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +INSERT INTO test2 SET a2 = NEW.a1; END BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci SELECT * FROM `test1`; a1 1 @@ -4558,7 +4558,7 @@ CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT "Meow"; SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr1 UPDATE t1 SET @f1 = 1 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation test ev1 root@localhost SYSTEM ONE TIME 2030-01-01 00:00:00 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci @@ -4577,7 +4577,7 @@ DROP PROCEDURE pr1; reload table; this should restore table and trigger SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr1 UPDATE t1 SET @f1 = 1 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; @@ -4586,7 +4586,7 @@ name body reload db; this should restore routines and events SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -tr1 UPDATE t1 SET @f1 = 1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr1 UPDATE t1 SET @f1 = 1 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation test ev1 root@localhost SYSTEM ONE TIME 2030-01-01 00:00:00 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci @@ -4812,7 +4812,7 @@ CREATE VIEW v2 AS SELECT * FROM t2; </row> </table_data> <triggers name="t2"> - <trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> + <trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="--TIME--"> <![CDATA[ CREATE DEFINER=`root`@`localhost` TRIGGER trig1 BEFORE INSERT ON t2 FOR EACH ROW BEGIN @@ -4820,7 +4820,7 @@ INSERT INTO t2 VALUES(1); END ]]> </trigger> - <trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> + <trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="--TIME--"> <![CDATA[ CREATE DEFINER=`root`@`localhost` TRIGGER trig2 AFTER INSERT ON t2 FOR EACH ROW BEGIN @@ -4951,7 +4951,7 @@ END </row> </table_data> <triggers name="t2"> - <trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> + <trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="--TIME--"> <![CDATA[ CREATE DEFINER=`root`@`localhost` TRIGGER trig1 BEFORE INSERT ON t2 FOR EACH ROW BEGIN @@ -4959,7 +4959,7 @@ INSERT INTO t2 VALUES(1); END ]]> </trigger> - <trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> + <trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="--TIME--"> <![CDATA[ CREATE DEFINER=`root`@`localhost` TRIGGER trig2 AFTER INSERT ON t2 FOR EACH ROW BEGIN @@ -5093,7 +5093,7 @@ connection conn_1; </row> </table_data> <triggers name="t2"> - <trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> + <trigger Trigger="trig1" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="--TIME--"> <![CDATA[ CREATE DEFINER=`root`@`localhost` TRIGGER trig1 BEFORE INSERT ON t2 FOR EACH ROW BEGIN @@ -5101,7 +5101,7 @@ INSERT INTO t2 VALUES(1); END ]]> </trigger> - <trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci"> + <trigger Trigger="trig2" sql_mode="" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="--TIME--"> <![CDATA[ CREATE DEFINER=`root`@`localhost` TRIGGER trig2 AFTER INSERT ON t2 FOR EACH ROW BEGIN diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index d3c4ec94cb7..ed768343581 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1009,14 +1009,14 @@ def information_schema TRIGGERS TRIGGERS EVENT_MANIPULATION Event 253 18 6 N 1 0 def information_schema TRIGGERS TRIGGERS EVENT_OBJECT_TABLE Table 253 192 2 N 1 0 33 def information_schema TRIGGERS TRIGGERS ACTION_STATEMENT Statement 252 589815 10 N 17 0 33 def information_schema TRIGGERS TRIGGERS ACTION_TIMING Timing 253 18 6 N 1 0 33 -def information_schema TRIGGERS TRIGGERS CREATED Created 12 19 0 Y 128 0 63 +def information_schema TRIGGERS TRIGGERS CREATED Created 12 22 22 Y 128 2 63 def information_schema TRIGGERS TRIGGERS SQL_MODE sql_mode 253 24576 42 N 1 0 33 def information_schema TRIGGERS TRIGGERS DEFINER Definer 253 567 14 N 1 0 33 def information_schema TRIGGERS TRIGGERS CHARACTER_SET_CLIENT character_set_client 253 96 6 N 1 0 33 def information_schema TRIGGERS TRIGGERS COLLATION_CONNECTION collation_connection 253 96 6 N 1 0 33 def information_schema TRIGGERS TRIGGERS DATABASE_COLLATION Database Collation 253 96 17 N 1 0 33 Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -t1_bi INSERT t1 SET @a = 1 BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost binary binary latin1_swedish_ci +t1_bi INSERT t1 SET @a = 1 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost binary binary latin1_swedish_ci ---------------------------------------------------------------- SELECT TRIGGER_CATALOG, @@ -1058,6 +1058,11 @@ def information_schema TRIGGERS TRIGGERS SQL_MODE SQL_MODE 253 24576 42 N 1 0 33 def information_schema TRIGGERS TRIGGERS DEFINER DEFINER 253 567 14 N 1 0 33 TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW SQL_MODE DEFINER def test t1_bi INSERT def test t1 NULL SET @a = 1 ROW BEFORE NULL NULL OLD NEW NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost +SELECT CREATED FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name='t1_bi'; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def information_schema TRIGGERS TRIGGERS CREATED CREATED 12 22 22 Y 128 2 63 +CREATED +# ---------------------------------------------------------------- SHOW CREATE VIEW v1; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr @@ -1363,70 +1368,70 @@ DROP PROCEDURE IF EXISTS p1; CREATE TABLE t1(c1 INT); CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1; SHOW CREATE TRIGGER t1_bi; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CREATE PROCEDURE p1() SHOW CREATE TRIGGER t1_bi; CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # CALL p1(); -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # PREPARE stmt1 FROM 'SHOW CREATE TRIGGER t1_bi'; EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # EXECUTE stmt1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1 latin1 latin1_swedish_ci latin1_swedish_ci # DROP TABLE t1; DROP PROCEDURE p1; DEALLOCATE PREPARE stmt1; @@ -1457,10 +1462,10 @@ Function sql_mode Create Function character_set_client collation_connection Data f1 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS char(10) CHARSET latin1 RETURN 'теÑÑ‚' koi8r koi8r_general_ci latin1_swedish_ci SHOW CREATE TRIGGER t1_bi; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW -SET NEW.c1 = 'теÑÑ‚' koi8r koi8r_general_ci latin1_swedish_ci +SET NEW.c1 = 'теÑÑ‚' koi8r koi8r_general_ci latin1_swedish_ci # SHOW CREATE EVENT ev1; Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation ev1 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION SYSTEM CREATE DEFINER=`root`@`localhost` EVENT `ev1` ON SCHEDULE AT '2030-01-01 00:00:00' ON COMPLETION NOT PRESERVE ENABLE DO SELECT 'теÑÑ‚' AS test koi8r koi8r_general_ci latin1_swedish_ci @@ -1532,16 +1537,16 @@ connect con1, localhost, root; LOCK TABLE t1 WRITE; connection default; SHOW CREATE TRIGGER t1_bi; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1 utf8 utf8_general_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1 utf8 utf8_general_ci latin1_swedish_ci # connection con1; UNLOCK TABLES; # Test 2: ALTER TABLE with SHOW CREATE TRIGGER in transaction connection default; START TRANSACTION; SHOW CREATE TRIGGER t1_bi; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1 utf8 utf8_general_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET new.a = 1 utf8 utf8_general_ci latin1_swedish_ci # connection con1; ALTER TABLE t1 CHARACTER SET = utf8; disconnect con1; diff --git a/mysql-test/r/trigger-compat.result b/mysql-test/r/trigger-compat.result index 3d96507d71f..55793cdf5c2 100644 --- a/mysql-test/r/trigger-compat.result +++ b/mysql-test/r/trigger-compat.result @@ -29,8 +29,8 @@ wl2818_trg2 mysqltest_dfn@localhost 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest_db1 wl2818_trg1 INSERT def mysqltest_db1 t1 0 NULL INSERT INTO t2 VALUES(CURRENT_USER()) ROW BEFORE NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci -def mysqltest_db1 wl2818_trg2 INSERT def mysqltest_db1 t1 0 NULL INSERT INTO t2 VALUES(CURRENT_USER()) ROW AFTER NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION mysqltest_dfn@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 wl2818_trg1 INSERT def mysqltest_db1 t1 1 NULL INSERT INTO t2 VALUES(CURRENT_USER()) ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 wl2818_trg2 INSERT def mysqltest_db1 t1 1 NULL INSERT INTO t2 VALUES(CURRENT_USER()) ROW AFTER NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION mysqltest_dfn@localhost latin1 latin1_swedish_ci latin1_swedish_ci DROP TRIGGER wl2818_trg1; 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. @@ -74,9 +74,11 @@ CREATE TRIGGER tr22 BEFORE INSERT ON t2 FOR EACH ROW DELETE FROM non_existing_ta ERROR 42000: Unknown trigger has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'Not allowed syntax here, and trigger name cant be extracted either.' at line 1' SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -tr11 INSERT t1 DELETE FROM t3 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -tr12 INSERT t1 DELETE FROM t3 AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -tr14 DELETE t1 DELETE FROM non_existing_table AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr11 INSERT t1 DELETE FROM t3 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr12 INSERT t1 DELETE FROM t3 AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr15 UPDATE t1 CREATE DEFINER=`root`@`localhost` TRIGGER tr15 BEFORE UPDATE ON t1 FOR EACH ROW DELETE FROM non_existing_table a USING non_existing_table a BEFORE # latin1 latin1_swedish_ci latin1_swedish_ci +tr13 DELETE t1 CREATE DEFINER=`root`@`localhost` TRIGGER tr13 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a BEFORE # latin1 latin1_swedish_ci latin1_swedish_ci +tr14 DELETE t1 DELETE FROM non_existing_table AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci INSERT INTO t1 VALUES (1); ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a USING t1 a' at line 1' INSERT INTO t2 VALUES (1); @@ -94,9 +96,11 @@ RENAME TABLE t1 TO t1_2; ERROR 42000: Trigger 'tr13' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a USING t1 a' at line 1' SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -tr11 INSERT t1 DELETE FROM t3 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -tr12 INSERT t1 DELETE FROM t3 AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -tr14 DELETE t1 DELETE FROM non_existing_table AFTER NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr11 INSERT t1 DELETE FROM t3 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr12 INSERT t1 DELETE FROM t3 AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr15 UPDATE t1 CREATE DEFINER=`root`@`localhost` TRIGGER tr15 BEFORE UPDATE ON t1 FOR EACH ROW DELETE FROM non_existing_table a USING non_existing_table a BEFORE # latin1 latin1_swedish_ci latin1_swedish_ci +tr13 DELETE t1 CREATE DEFINER=`root`@`localhost` TRIGGER tr13 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a BEFORE # latin1 latin1_swedish_ci latin1_swedish_ci +tr14 DELETE t1 DELETE FROM non_existing_table AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci DROP TRIGGER tr11; Warnings: Warning 1603 Triggers for table `test`.`t1` have no creation context @@ -124,16 +128,16 @@ INSERT INTO t1 VALUES (1), (2), (3); INSERT INTO t2 VALUES (1), (2), (3); # We write three trigger files. First trigger is syntaxically incorrect, next trigger is correct # and last trigger is broken. -# Next we try to execute SHOW CREATE TRGGIR command for broken trigger and then try to drop one. +# Next we try to execute SHOW CREATE TRIGGER command for broken trigger and then try to drop one. FLUSH TABLE t1; SHOW CREATE TRIGGER tr12; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -tr12 CREATE DEFINER=`root`@`localhost` TRIGGER tr12 BEFORE INSERT ON t1 FOR EACH ROW DELETE FROM t2 latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr12 CREATE DEFINER=`root`@`localhost` TRIGGER tr12 BEFORE INSERT ON t1 FOR EACH ROW DELETE FROM t2 latin1 latin1_swedish_ci latin1_swedish_ci NULL Warnings: Warning 1603 Triggers for table `test`.`t1` have no creation context SHOW CREATE TRIGGER tr11; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation -tr11 CREATE DEFINER=`root`@`localhost` TRIGGER tr11 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a latin1 latin1_swedish_ci latin1_swedish_ci +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr11 CREATE DEFINER=`root`@`localhost` TRIGGER tr11 BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t1 a USING t1 a latin1 latin1_swedish_ci latin1_swedish_ci NULL DROP TRIGGER tr12; DROP TRIGGER tr11; DROP TABLE t1; diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 19a8d53a428..2ae70730c3a 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -303,7 +303,7 @@ create trigger trg before insert on t1 for each row set @a:=1; 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 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' +drop trigger trg2; 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; @@ -1988,8 +1988,8 @@ create trigger t1_bi before insert on t1 for each row begin end; create trigger t1_bi before insert on t1 for each row begin end; ERROR HY000: Trigger already exists create trigger t1_bi2 before insert on t1 for each row begin end; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' drop trigger t1_bi; +drop trigger t1_bi2; drop trigger t1_bi; ERROR HY000: Trigger does not exist lock tables t1 read; @@ -2123,6 +2123,7 @@ CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1 # Used to crash SHOW TRIGGERS IN db1; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +trg1 INSERT t2 CREATE DEFINER=`root`@`localhost` TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERTINTOt1 VALUES (1) BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci INSERT INTO t2 VALUES (1); ERROR 42000: Trigger 'trg1' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'VALUES (1)' at line 1' SELECT * FROM t1; @@ -2298,6 +2299,8 @@ SET optimizer_switch=@save_optimizer_switch; DROP TRIGGER tr; DROP TABLE t1, t2; End of 5.3 tests. +set time_zone="+00:00"; +SET TIMESTAMP=UNIX_TIMESTAMP('2001-01-01 10:20:30'); SET @@session.sql_mode = 'STRICT_ALL_TABLES,STRICT_TRANS_TABLES'; CREATE TABLE t1 (c CHAR(1) NOT NULL); CREATE TRIGGER t1_bi @@ -2311,5 +2314,55 @@ END; SET @@session.sql_mode = default; INSERT INTO t1 VALUES ('a'); ERROR 22001: Data too long for column 'c' at row 1 +show create trigger t1_bi; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +t1_bi STRICT_TRANS_TABLES,STRICT_ALL_TABLES CREATE DEFINER=`root`@`localhost` TRIGGER t1_bi +BEFORE INSERT +ON t1 +FOR EACH ROW +BEGIN +SET NEW.c = 'www'; +END latin1 latin1_swedish_ci latin1_swedish_ci 2001-01-01 10:20:30.00 DROP TRIGGER t1_bi; DROP TABLE t1; +SET TIMESTAMP=DEFAULT; +set time_zone= @@global.time_zone; +create table t1 (i int); +create trigger tr1 after insert on t1 for each row set @a=@a+1; +create trigger tr2 after insert on t1 for each row set @a=@a+1; +create trigger tr3 after insert on t1 for each row set @a=@a+1; +flush status; +show status like 'Executed_triggers'; +Variable_name Value +Executed_triggers 0 +set @a=0; +insert into t1 values (1); +show status like 'Executed_triggers'; +Variable_name Value +Executed_triggers 3 +select @a; +@a +3 +drop table t1; +create table t1 (i int); +set time_zone="+0:00"; +SET TIMESTAMP=UNIX_TIMESTAMP('2016-01-01 10:10:10.33'); +select now(2); +now(2) +2016-01-01 10:10:10.33 +create or replace trigger tr1 after insert on t1 for each row set @a=@a+1; +SET TIMESTAMP=UNIX_TIMESTAMP('2016-01-01 10:10:10.99'); +select now(2); +now(2) +2016-01-01 10:10:10.99 +create or replace trigger tr2 after insert on t1 for each row set @a=@a+1; +select now(2); +now(2) +2016-01-01 10:10:10.99 +select trigger_name, action_order, created from information_schema.triggers +where event_object_table = 't1' and trigger_schema='test'; +trigger_name action_order created +tr1 1 2016-01-01 10:10:10.33 +tr2 2 2016-01-01 10:10:10.99 +drop table t1; +set time_zone= @@global.time_zone; diff --git a/mysql-test/r/trigger_notembedded.result b/mysql-test/r/trigger_notembedded.result index b0addf8d50f..36352623998 100644 --- a/mysql-test/r/trigger_notembedded.result +++ b/mysql-test/r/trigger_notembedded.result @@ -133,8 +133,8 @@ INSERT INTO t1 VALUES(6); ERROR HY000: The user specified as a definer ('mysqltest_nonexs'@'localhost') does not exist SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @new_sum = 0 BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION mysqltest_inv@localhost latin1 latin1_swedish_ci latin1_swedish_ci -trg2 INSERT t1 SET @new_sum = 0 AFTER NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION mysqltest_nonexs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @new_sum = 0 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION mysqltest_inv@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg2 INSERT t1 SET @new_sum = 0 AFTER # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION mysqltest_nonexs@localhost latin1 latin1_swedish_ci latin1_swedish_ci DROP TRIGGER trg1; DROP TRIGGER trg2; CREATE TRIGGER trg1 BEFORE INSERT ON t1 @@ -163,11 +163,11 @@ trg5 @abcdef@@@hostname 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mysqltest_db1 trg1 INSERT def mysqltest_db1 t1 0 NULL SET @a = 1 ROW BEFORE NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci -def mysqltest_db1 trg2 INSERT def mysqltest_db1 t1 0 NULL SET @a = 2 ROW AFTER NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @ latin1 latin1_swedish_ci latin1_swedish_ci -def mysqltest_db1 trg3 UPDATE def mysqltest_db1 t1 0 NULL SET @a = 3 ROW BEFORE NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @abc@def@@% latin1 latin1_swedish_ci latin1_swedish_ci -def mysqltest_db1 trg4 UPDATE def mysqltest_db1 t1 0 NULL SET @a = 4 ROW AFTER NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @hostname latin1 latin1_swedish_ci latin1_swedish_ci -def mysqltest_db1 trg5 DELETE def mysqltest_db1 t1 0 NULL SET @a = 5 ROW BEFORE NULL NULL OLD NEW NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @abcdef@@@hostname latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 trg1 INSERT def mysqltest_db1 t1 1 NULL SET @a = 1 ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 trg2 INSERT def mysqltest_db1 t1 1 NULL SET @a = 2 ROW AFTER NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @ latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 trg3 UPDATE def mysqltest_db1 t1 1 NULL SET @a = 3 ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @abc@def@@% latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 trg4 UPDATE def mysqltest_db1 t1 1 NULL SET @a = 4 ROW AFTER NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @hostname latin1 latin1_swedish_ci latin1_swedish_ci +def mysqltest_db1 trg5 DELETE def mysqltest_db1 t1 1 NULL SET @a = 5 ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION @abcdef@@@hostname latin1 latin1_swedish_ci latin1_swedish_ci connection default; DROP USER mysqltest_dfn@localhost; DROP USER mysqltest_inv@localhost; diff --git a/mysql-test/r/trigger_wl3253.result b/mysql-test/r/trigger_wl3253.result new file mode 100644 index 00000000000..c39591fdc17 --- /dev/null +++ b/mysql-test/r/trigger_wl3253.result @@ -0,0 +1,502 @@ +# +# WL#3253: multiple triggers per table +# +SET @binlog_format_saved = @@binlog_format; +SET binlog_format=ROW; +SET time_zone='+00:00'; +# +# Test 1. +# Check that the sequence of triggers for the same combination +# of event type/action type can be created for a table +# and is fired consequently in the order of its creation +# during statement execution. +# In this test we check BEFORE triggers. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; +a b +1 1 +101 2 +DROP TABLE t2; +DROP TABLE t1; +# +# Test 2. +# Check that the sequence of triggers for the same combination +# of event type/action type can be created for a table +# and is fired consequently in the order of its creation +# during statement execution. +# In this test we check AFTER triggers. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1_bi AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bi AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; +a b +1 1 +101 2 +DROP TABLE t2; +DROP TABLE t1; +# +# Test 3. +# Check that the sequences of triggers for the different event types +# can be created for a table and are fired consequently +# in the order of its creation during statement execution. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bu BEFORE UPDATE ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; +a b +1 1 +101 2 +UPDATE t1 SET a = 5; +SELECT * FROM t2 ORDER BY b; +a b +1 1 +101 2 +5 3 +305 4 +DROP TABLE t2; +DROP TABLE t1; +# +# Test 4. +# Check that every new created trigger has unique action_order value +# started from 1 and NOT NULL value for creation timestamp. +# +CREATE TABLE t1 (a INT); +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:00'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +SELECT trigger_name, created, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name created action_order +tr1_bi 2013-01-31 09:00:00.00 1 +tr2_bi 2013-01-31 09:00:01.00 2 +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; +# +# Test 5. +# Check that action_order attribute isn't shown +# in the output of SHOW TRIGGERS and SHOW CREATE TRIGGER +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1_bi INSERT t1 SET @a:=1 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; +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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test tr1_bi INSERT def test t1 1 NULL SET @a:=1 ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE TRIGGER tr1_bi; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 latin1 latin1_swedish_ci latin1_swedish_ci # +DROP TABLE t1; +# +# Test 6. +# Check that action_order attribute is reused when trigger +# are recreated. +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +DROP TRIGGER tr1_bi; +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +DROP TABLE t1; +# +# Test 7. +# Check that it is possible to create several triggers with +# the same value for creation timestamp. +# +CREATE TABLE t1 (a INT); +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +SELECT trigger_name, created, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name created action_order +tr1_bi 2013-01-31 09:00:01.00 1 +tr2_bi 2013-01-31 09:00:01.00 2 +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; +# +# Test 8. +# Check that SHOW CREATE TRIGGER outputs the CREATED attribute +# and it is not NULL +# +CREATE TABLE t1 (a INT); +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SHOW CREATE TRIGGER tr1_bi; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1_bi NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 latin1 latin1_swedish_ci latin1_swedish_ci 2013-01-31 09:00:01.00 +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; +# +# Test 9. +# Check that SHOW TRIGGERS outputs the CREATED attribute +# and it is not NULL. +# +CREATE TABLE t1 (a INT); +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1_bi INSERT t1 SET @a:=1 BEFORE 2013-01-31 09:00:01.00 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; +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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test tr1_bi INSERT def test t1 1 NULL SET @a:=1 ROW BEFORE NULL NULL OLD NEW 2013-01-31 09:00:01.00 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; +# +# Test 10. +# Check that FOLLOWS clause is supported and works correctly. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi INSERT INTO t2 (a) VALUES (NEW.a + 200); +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +tr2_bi 2 +tr3_bi 3 +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; +a b +101 1 +201 2 +301 3 +DROP TABLE t2; +DROP TABLE t1; +# +# Test 11. +# Check that PRECEDES clause is supported and works correctly. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr3_bi INSERT INTO t2 (a) VALUES (NEW.a + 200); +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +tr2_bi 2 +tr3_bi 3 +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; +a b +101 1 +201 2 +301 3 +DROP TABLE t2; +DROP TABLE t1; +# +# Test 12. +# Check that the PRECEDES works properly for the 1st trigger in the chain. +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr1_bi INSERT INTO t2 (a) VALUES (NEW.a); +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr0_bi 1 +tr1_bi 2 +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; +a b +1 1 +101 2 +DROP TABLE t2; +DROP TABLE t1; +# +# Test 13. +# Check that error is reported if the FOLLOWS clause references to +# non-existing trigger +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=3; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr0_bi SET @a:=2; +ERROR HY000: Referenced trigger 'tr0_bi' for the given action time and event type does not exist +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +tr3_bi 2 +DROP TABLE t1; +# +# Test 14. +# Check that error is reported if the PRECEDES clause references to +# non-existing trigger +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=3; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr0_bi SET @a:=2; +ERROR HY000: Referenced trigger 'tr0_bi' for the given action time and event type does not exist +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +tr3_bi 2 +DROP TABLE t1; +# +# Test 15. +# Check that action_order value is independent for each type of event +# (INSERT/UPDATE/DELETE) +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +tr2_bi 2 +tr1_bu 1 +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr2_bi SET @a:=3; +CREATE TRIGGER tr2_bu BEFORE UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bu SET @a:=3; +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; +trigger_name action_order +tr1_bi 1 +tr2_bi 2 +tr3_bi 3 +tr1_bu 1 +tr2_bu 2 +DROP TABLE t1; +# +# Test 16. +# Check that the trigger in the clause FOLLOWS/PRECEDES can refences +# only to the trigger for the same ACTION/TIMINMG +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; +CREATE TRIGGER tr2_bu BEFORE UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=3; +ERROR HY000: Referenced trigger 'tr1_bi' for the given action time and event type does not exist +CREATE TRIGGER tr2_au AFTER UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=3; +ERROR HY000: Referenced trigger 'tr1_bi' for the given action time and event type does not exist +CREATE TRIGGER tr1_au AFTER UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bu SET @a:=3; +ERROR HY000: Referenced trigger 'tr1_bu' for the given action time and event type does not exist +CREATE TRIGGER tr1_ai AFTER INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=3; +ERROR HY000: Referenced trigger 'tr1_bi' for the given action time and event type does not exist +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1_bi INSERT t1 SET @a:=1 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr1_bu UPDATE t1 SET @a:=3 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; +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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test tr1_bi INSERT def test t1 1 NULL SET @a:=1 ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def test tr1_bu UPDATE def test t1 1 NULL SET @a:=3 ROW BEFORE NULL NULL OLD NEW # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +DROP TABLE t1; +# +# Test 17. Check that table's triggers are dumped correctly. +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +DROP TABLE t1; +# +# Test 18. Check that table's triggers are dumped in right order +# taking into account the PRECEDES/FOLLOWS clauses. +# +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr1_bi SET @a:=0; +CREATE TRIGGER tr1_1_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=0; +# Expected order of triggers in the dump is: tr0_bi, tr1_bi, tr1_1_bi, tr2_i. +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=0 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr1_1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=0 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = latin1 */ ; +/*!50003 SET character_set_results = latin1 */ ; +/*!50003 SET collation_connection = latin1_swedish_ci */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +DELIMITER ;; +/*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2 */;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +DROP TABLE t1; +# +# Test 19. Check that table's triggers are dumped correctly in xml. +# +CREATE TABLE t1 (a INT); +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:00'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; +SET TIMESTAMP=DEFAULT; +<?xml version="1.0"?> +<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<database name="test"> + <table_data name="t1"> + </table_data> + <triggers name="t1"> + <trigger Trigger="tr1_bi" sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="2013-01-31 09:00:00.00"> +<![CDATA[ +CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 +]]> + </trigger> + <trigger Trigger="tr2_bi" sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="2013-01-31 09:00:00.00"> +<![CDATA[ +CREATE DEFINER=`root`@`localhost` TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2 +]]> + </trigger> + <trigger Trigger="tr1_bu" sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" character_set_client="latin1" collation_connection="latin1_swedish_ci" Database_Collation="latin1_swedish_ci" Created="2013-01-31 09:00:00.00"> +<![CDATA[ +CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3 +]]> + </trigger> + </triggers> +</database> +</mysqldump> +DROP TABLE t1; +# +# Test 20. Check that the statement CHECK TABLE FOR UPGRADE outputs +# the warnings for triggers created by a server without support for wl3253. +# +CREATE TABLE t1 (a INT); +FLUSH TABLE t1; +CHECK TABLE t1 FOR UPGRADE; +Table Op Msg_type Msg_text +test.t1 check status OK +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1_bi INSERT t1 SET @a:=1 BEFORE NULL NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr1_ai INSERT t1 SET @a:=2 AFTER NULL NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; +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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION +def test tr1_bi INSERT def test t1 1 NULL SET @a:=1 ROW BEFORE NULL NULL OLD NEW NULL NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def test tr1_ai INSERT def test t1 1 NULL SET @a:=2 ROW AFTER NULL NULL OLD NEW NULL NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +SHOW CREATE TRIGGER tr1_bi; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1_bi NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 latin1 latin1_swedish_ci latin1_swedish_ci NULL +SHOW CREATE TRIGGER tr1_ai; +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created +tr1_ai NO_ENGINE_SUBSTITUTION CREATE DEFINER=`root`@`localhost` TRIGGER tr1_ai AFTER INSERT ON t1 FOR EACH ROW SET @a:=2 latin1 latin1_swedish_ci latin1_swedish_ci NULL +DROP TABLE t1; +SET binlog_format=@binlog_format_saved; +# End of tests. +# diff --git a/mysql-test/suite/binlog/r/binlog_trigger.result b/mysql-test/suite/binlog/r/binlog_trigger.result new file mode 100644 index 00000000000..48ec1dd629e --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_trigger.result @@ -0,0 +1,24 @@ +# +# WL#3253: multiple triggers per table +# +# Testing that the FOLLOWS and PRECEDES clauses get logged +CREATE TABLE t1 (a INT, b INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr4_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi INSERT INTO t2 (a) VALUES (NEW.a + 200); +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW precedes tr4_bi INSERT INTO t2 (a) VALUES (NEW.a + 400); +DROP TABLE t1; +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b INT) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr4_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi INSERT INTO t2 (a) VALUES (NEW.a + 200) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW precedes tr4_bi INSERT INTO t2 (a) VALUES (NEW.a + 400) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP TABLE `t1` /* generated by server */ diff --git a/mysql-test/suite/binlog/t/binlog_trigger.test b/mysql-test/suite/binlog/t/binlog_trigger.test new file mode 100644 index 00000000000..4ad5d16a1f8 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_trigger.test @@ -0,0 +1,23 @@ +--source include/not_embedded.inc +--source include/have_binlog_format_statement.inc + +--disable_query_log +reset master; # get rid of previous tests binlog +--enable_query_log + +--echo # +--echo # WL#3253: multiple triggers per table +--echo # + +--echo # Testing that the FOLLOWS and PRECEDES clauses get logged + +CREATE TABLE t1 (a INT, b INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr4_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi INSERT INTO t2 (a) VALUES (NEW.a + 200); +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW precedes tr4_bi INSERT INTO t2 (a) VALUES (NEW.a + 400); +DROP TABLE t1; + + +--let $binlog_file = LAST +source include/show_binlog_events.inc; diff --git a/mysql-test/suite/funcs_1/datadict/is_triggers.inc b/mysql-test/suite/funcs_1/datadict/is_triggers.inc index cb2c461dd39..82cf6f8e21f 100644 --- a/mysql-test/suite/funcs_1/datadict/is_triggers.inc +++ b/mysql-test/suite/funcs_1/datadict/is_triggers.inc @@ -81,6 +81,7 @@ eval SHOW COLUMNS FROM information_schema.$is_table; # information_schema.tables is in is_columns_is.test. # Show that several columns are always NULL. +--replace_column 17 # SELECT * FROM information_schema.triggers WHERE trigger_catalog IS NOT NULL OR event_object_catalog IS NOT NULL OR action_condition IS NOT NULL OR action_reference_old_table IS NOT NULL @@ -134,21 +135,27 @@ ON db_datadict.t1 FOR EACH ROW SET @test_before = 2, new.f1 = @test_before; GRANT ALL ON db_datadict.t1 TO 'testuser2'@'localhost'; REVOKE TRIGGER ON db_datadict.t1 FROM 'testuser2'@'localhost'; GRANT SELECT ON db_datadict.t1 TO 'testuser3'@'localhost'; +--replace_column 17 # eval $my_select; +--replace_column 6 # eval $my_show; --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser2, localhost, testuser2, , db_datadict); SHOW GRANTS FOR 'testuser2'@'localhost'; --echo # No TRIGGER Privilege --> no result for query +--replace_column 17 # eval $my_select; +--replace_column 6 # eval $my_show; --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK connect (testuser3, localhost, testuser3, , test); SHOW GRANTS FOR 'testuser3'@'localhost'; --echo # TRIGGER Privilege + SELECT Privilege on t1 --> result for query +--replace_column 17 # eval $my_select; +--replace_column 6 # eval $my_show; --replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK @@ -158,7 +165,9 @@ SHOW GRANTS FOR 'testuser4'@'localhost'; --disable_abort_on_error SELECT * FROM db_datadict.t1; DESC db_datadict.t1; +--replace_column 17 # eval $my_select; +--replace_column 6 # eval $my_show; connection default; @@ -166,7 +175,9 @@ disconnect testuser1; disconnect testuser2; disconnect testuser3; disconnect testuser4; +--replace_column 17 # eval $my_select; +--replace_column 6 # eval $my_show; DROP USER 'testuser1'@'localhost'; DROP USER 'testuser2'@'localhost'; diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result index e44e17c6392..4e4716fd873 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_03e.result @@ -486,8 +486,8 @@ create trigger trg1_4 before UPDATE on t1 for each row set new.f1 = 'trig 1_4-yes'; show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1_3 INSERT t1 set new.f1 = 'trig 1_3-yes' BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci -trg1_4 UPDATE t1 set new.f1 = 'trig 1_4-yes' BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1_3 INSERT t1 set new.f1 = 'trig 1_3-yes' BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1_4 UPDATE t1 set new.f1 = 'trig 1_4-yes' BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection no_privs; select current_user; current_user diff --git a/mysql-test/suite/funcs_1/r/innodb_trig_0407.result b/mysql-test/suite/funcs_1/r/innodb_trig_0407.result index d450096176d..81ead0c9346 100644 --- a/mysql-test/suite/funcs_1/r/innodb_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/innodb_trig_0407.result @@ -332,11 +332,10 @@ Create trigger trg5_1 BEFORE INSERT on tb3 for each row set new.f122='Trigger1 3.5.7.5/6'; Create trigger trg5_2 BEFORE INSERT on tb3 for each row set new.f122='Trigger2 3.5.7.5'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Insert into tb3 (f121,f122) values ('Test 3.5.7.5/6','Insert 3.5.7.5'); Select f121,f122 from tb3 where f121='Test 3.5.7.5/6'; f121 f122 -Test 3.5.7.5/6 Trigger1 3.5.7.5/6 +Test 3.5.7.5/6 Trigger2 3.5.7.5 update tb3 set f122='Update 3.5.7.6' where f121= 'Test 3.5.7.5/6'; Select f121,f122 from tb3 where f121='Test 3.5.7.5/6'; f121 f122 @@ -352,7 +351,6 @@ Create trigger trg6_1 AFTER INSERT on tb3 for each row set @test_var='Trigger1 3.5.7.7/8'; Create trigger trg6_2 AFTER INSERT on tb3 for each row set @test_var='Trigger2 3.5.7.7'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var Before trig 3.5.7.7 @@ -362,14 +360,14 @@ f121 f122 Test 3.5.7.7/8 Insert 3.5.7.7 select @test_var; @test_var -Trigger1 3.5.7.7/8 +Trigger2 3.5.7.7 update tb3 set f122='Update 3.5.7.8' where f121= 'Test 3.5.7.7/8'; Select f121,f122 from tb3 where f121='Test 3.5.7.7/8'; f121 f122 Test 3.5.7.7/8 Update 3.5.7.8 select @test_var; @test_var -Trigger1 3.5.7.7/8 +Trigger2 3.5.7.7 drop trigger trg6_1; drop trigger trg6_2; delete from tb3 where f121='Test 3.5.7.7/8'; @@ -380,7 +378,6 @@ Create trigger trg7_1 BEFORE UPDATE on tb3 for each row set new.f122='Trigger1 3.5.7.9/10'; Create trigger trg7_2 BEFORE UPDATE on tb3 for each row set new.f122='Trigger2 3.5.7.9'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Insert into tb3 (f121,f122) values ('Test 3.5.7.9/10','Insert 3.5.7.9'); Select f121,f122 from tb3 where f121='Test 3.5.7.9/10'; f121 f122 @@ -388,7 +385,7 @@ Test 3.5.7.9/10 Insert 3.5.7.9 update tb3 set f122='update 3.5.7.10' where f121='Test 3.5.7.9/10'; Select f121,f122 from tb3 where f121='Test 3.5.7.9/10'; f121 f122 -Test 3.5.7.9/10 Trigger1 3.5.7.9/10 +Test 3.5.7.9/10 Trigger2 3.5.7.9 drop trigger trg7_1; drop trigger trg7_2; delete from tb3 where f121='Test 3.5.7.9/10'; @@ -400,7 +397,6 @@ Create trigger trg8_1 AFTER UPDATE on tb3 for each row set @test_var='Trigger 3.5.7.11/12'; Create trigger trg8_2 AFTER UPDATE on tb3 for each row set @test_var='Trigger2 3.5.7.11'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var Before trig 3.5.7.11 @@ -417,7 +413,7 @@ f121 f122 Test 3.5.7.11/12 update 3.5.7.12 select @test_var; @test_var -Trigger 3.5.7.11/12 +Trigger2 3.5.7.11 delete from tb3 where f121='Test 3.5.7.11/12'; drop trigger trg8_1; drop trigger trg8_2; @@ -430,7 +426,6 @@ Create trigger trg9_1 BEFORE DELETE on tb3 for each row set @test_var=@test_var+1; Create trigger trg9_2 BEFORE DELETE on tb3 for each row set @test_var=@test_var+10; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var 1 @@ -446,11 +441,11 @@ Select f121,f122 from tb3 where f121='Test 3.5.7.13/14'; f121 f122 select @test_var; @test_var -2 +12 delete from tb3 where f121='Test 3.5.7.13/14'; select @test_var; @test_var -2 +12 drop trigger trg9_1; drop trigger trg9_2; delete from tb3 where f121='Test 3.5.7.13/14'; @@ -462,7 +457,6 @@ Create trigger trg_3_406010_1 AFTER DELETE on tb3 for each row set @test_var=@test_var+5; Create trigger trg_3_406010_2 AFTER DELETE on tb3 for each row set @test_var=@test_var+50; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Create trigger trg_3_406010_1 AFTER INSERT on tb3 for each row set @test_var=@test_var+1; ERROR HY000: Trigger already exists @@ -481,11 +475,11 @@ Select f121,f122 from tb3 where f121='Test 3.5.7.15/16'; f121 f122 select @test_var; @test_var -6 +56 delete from tb3 where f121='Test 3.5.7.15/16'; select @test_var; @test_var -6 +56 drop trigger trg_3_406010_1; drop trigger trg_3_406010_2; delete from tb3 where f121='Test 3.5.7.15/16'; diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index d21cefa7c57..0f35e66d6a6 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -417,7 +417,7 @@ def information_schema TRIGGERS ACTION_STATEMENT 10 NO longtext 4294967295 4294 def information_schema TRIGGERS ACTION_TIMING 12 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6) select def information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select def information_schema TRIGGERS COLLATION_CONNECTION 21 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select -def information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime select +def information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 2 NULL NULL datetime(2) select def information_schema TRIGGERS DATABASE_COLLATION 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select def information_schema TRIGGERS DEFINER 19 NO varchar 189 567 NULL NULL NULL utf8 utf8_general_ci varchar(189) select def information_schema TRIGGERS EVENT_MANIPULATION 4 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6) select @@ -950,7 +950,7 @@ NULL information_schema TRIGGERS ACTION_ORDER bigint NULL NULL NULL NULL bigint( 3.0000 information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW varchar 3 9 utf8 utf8_general_ci varchar(3) 3.0000 information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW varchar 3 9 utf8 utf8_general_ci varchar(3) -NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime +NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime(2) 3.0000 information_schema TRIGGERS SQL_MODE varchar 8192 24576 utf8 utf8_general_ci varchar(8192) 3.0000 information_schema TRIGGERS DEFINER varchar 189 567 utf8 utf8_general_ci varchar(189) 3.0000 information_schema TRIGGERS CHARACTER_SET_CLIENT varchar 32 96 utf8 utf8_general_ci varchar(32) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index b740a04f015..69c5d79b541 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -417,7 +417,7 @@ def information_schema TRIGGERS ACTION_STATEMENT 10 NO longtext 4294967295 4294 def information_schema TRIGGERS ACTION_TIMING 12 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6) def information_schema TRIGGERS CHARACTER_SET_CLIENT 20 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) def information_schema TRIGGERS COLLATION_CONNECTION 21 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) -def information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime +def information_schema TRIGGERS CREATED 17 NULL YES datetime NULL NULL NULL NULL 2 NULL NULL datetime(2) def information_schema TRIGGERS DATABASE_COLLATION 22 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) def information_schema TRIGGERS DEFINER 19 NO varchar 189 567 NULL NULL NULL utf8 utf8_general_ci varchar(189) def information_schema TRIGGERS EVENT_MANIPULATION 4 NO varchar 6 18 NULL NULL NULL utf8 utf8_general_ci varchar(6) @@ -950,7 +950,7 @@ NULL information_schema TRIGGERS ACTION_ORDER bigint NULL NULL NULL NULL bigint( 3.0000 information_schema TRIGGERS ACTION_REFERENCE_NEW_TABLE varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema TRIGGERS ACTION_REFERENCE_OLD_ROW varchar 3 9 utf8 utf8_general_ci varchar(3) 3.0000 information_schema TRIGGERS ACTION_REFERENCE_NEW_ROW varchar 3 9 utf8 utf8_general_ci varchar(3) -NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime +NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime(2) 3.0000 information_schema TRIGGERS SQL_MODE varchar 8192 24576 utf8 utf8_general_ci varchar(8192) 3.0000 information_schema TRIGGERS DEFINER varchar 189 567 utf8 utf8_general_ci varchar(189) 3.0000 information_schema TRIGGERS CHARACTER_SET_CLIENT varchar 32 96 utf8 utf8_general_ci varchar(32) diff --git a/mysql-test/suite/funcs_1/r/is_triggers.result b/mysql-test/suite/funcs_1/r/is_triggers.result index ac6372b1d84..d20eeb9a319 100644 --- a/mysql-test/suite/funcs_1/r/is_triggers.result +++ b/mysql-test/suite/funcs_1/r/is_triggers.result @@ -45,7 +45,7 @@ ACTION_REFERENCE_OLD_TABLE varchar(64) YES NULL ACTION_REFERENCE_NEW_TABLE varchar(64) YES NULL ACTION_REFERENCE_OLD_ROW varchar(3) NO ACTION_REFERENCE_NEW_ROW varchar(3) NO -CREATED datetime YES NULL +CREATED datetime(2) YES NULL SQL_MODE varchar(8192) NO DEFINER varchar(189) NO CHARACTER_SET_CLIENT varchar(32) NO @@ -70,7 +70,7 @@ TRIGGERS CREATE TEMPORARY TABLE `TRIGGERS` ( `ACTION_REFERENCE_NEW_TABLE` varchar(64) DEFAULT NULL, `ACTION_REFERENCE_OLD_ROW` varchar(3) NOT NULL DEFAULT '', `ACTION_REFERENCE_NEW_ROW` varchar(3) NOT NULL DEFAULT '', - `CREATED` datetime DEFAULT NULL, + `CREATED` datetime(2) DEFAULT NULL, `SQL_MODE` varchar(8192) NOT NULL DEFAULT '', `DEFINER` varchar(189) NOT NULL DEFAULT '', `CHARACTER_SET_CLIENT` varchar(32) NOT NULL DEFAULT '', @@ -95,7 +95,7 @@ ACTION_REFERENCE_OLD_TABLE varchar(64) YES NULL ACTION_REFERENCE_NEW_TABLE varchar(64) YES NULL ACTION_REFERENCE_OLD_ROW varchar(3) NO ACTION_REFERENCE_NEW_ROW varchar(3) NO -CREATED datetime YES NULL +CREATED datetime(2) YES NULL SQL_MODE varchar(8192) NO DEFINER varchar(189) NO CHARACTER_SET_CLIENT varchar(32) NO @@ -106,8 +106,8 @@ WHERE trigger_catalog IS NOT NULL OR event_object_catalog IS NOT NULL OR action_condition IS NOT NULL OR action_reference_old_table IS NOT NULL OR action_reference_new_table IS NOT NULL; 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def mtr gs_insert INSERT def mtr global_suppressions 0 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -def mtr ts_insert INSERT def mtr test_suppressions 0 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def mtr gs_insert INSERT def mtr global_suppressions 1 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def mtr ts_insert INSERT def mtr test_suppressions 1 NULL BEGIN DECLARE dummy INT; SELECT "" REGEXP NEW.pattern INTO dummy; END ROW BEFORE NULL NULL OLD NEW # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci ################################################################################## # Testcase 3.2.18.2 + 3.2.18.3: INFORMATION_SCHEMA.TRIGGERS accessible information ################################################################################## @@ -136,10 +136,10 @@ GRANT SELECT ON db_datadict.t1 TO 'testuser3'@'localhost'; SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg1'; 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def db_datadict trg1 INSERT def db_datadict t1 0 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def db_datadict trg1 INSERT def db_datadict t1 1 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW TRIGGERS FROM db_datadict; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci connect testuser2, localhost, testuser2, , db_datadict; SHOW GRANTS FOR 'testuser2'@'localhost'; Grants for testuser2@localhost @@ -160,10 +160,10 @@ GRANT SELECT ON `db_datadict`.`t1` TO 'testuser3'@'localhost' SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg1'; 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def db_datadict trg1 INSERT def db_datadict t1 0 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def db_datadict trg1 INSERT def db_datadict t1 1 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW TRIGGERS FROM db_datadict; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci connect testuser4, localhost, testuser4, , test; SHOW GRANTS FOR 'testuser4'@'localhost'; Grants for testuser4@localhost @@ -176,10 +176,10 @@ ERROR 42000: SELECT command denied to user 'testuser4'@'localhost' for table 't1 SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg1'; 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def db_datadict trg1 INSERT def db_datadict t1 0 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def db_datadict trg1 INSERT def db_datadict t1 1 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW TRIGGERS FROM db_datadict; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection default; disconnect testuser1; disconnect testuser2; @@ -188,10 +188,10 @@ disconnect testuser4; SELECT * FROM information_schema.triggers WHERE trigger_name = 'trg1'; 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 CHARACTER_SET_CLIENT COLLATION_CONNECTION DATABASE_COLLATION -def db_datadict trg1 INSERT def db_datadict t1 0 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +def db_datadict trg1 INSERT def db_datadict t1 1 NULL SET @test_before = 2, new.f1 = @test_before ROW BEFORE NULL NULL OLD NEW # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci SHOW TRIGGERS FROM db_datadict; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE NULL testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @test_before = 2, new.f1 = @test_before BEFORE # testuser1@localhost latin1 latin1_swedish_ci latin1_swedish_ci DROP USER 'testuser1'@'localhost'; DROP USER 'testuser2'@'localhost'; DROP USER 'testuser3'@'localhost'; diff --git a/mysql-test/suite/funcs_1/r/memory_trig_03e.result b/mysql-test/suite/funcs_1/r/memory_trig_03e.result index 768e1577177..f9e8fc05088 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_03e.result @@ -487,8 +487,8 @@ create trigger trg1_4 before UPDATE on t1 for each row set new.f1 = 'trig 1_4-yes'; show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1_3 INSERT t1 set new.f1 = 'trig 1_3-yes' BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci -trg1_4 UPDATE t1 set new.f1 = 'trig 1_4-yes' BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1_3 INSERT t1 set new.f1 = 'trig 1_3-yes' BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1_4 UPDATE t1 set new.f1 = 'trig 1_4-yes' BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection no_privs; select current_user; current_user diff --git a/mysql-test/suite/funcs_1/r/memory_trig_0407.result b/mysql-test/suite/funcs_1/r/memory_trig_0407.result index 9b23271958a..72a7cb4f01d 100644 --- a/mysql-test/suite/funcs_1/r/memory_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/memory_trig_0407.result @@ -332,11 +332,10 @@ Create trigger trg5_1 BEFORE INSERT on tb3 for each row set new.f122='Trigger1 3.5.7.5/6'; Create trigger trg5_2 BEFORE INSERT on tb3 for each row set new.f122='Trigger2 3.5.7.5'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Insert into tb3 (f121,f122) values ('Test 3.5.7.5/6','Insert 3.5.7.5'); Select f121,f122 from tb3 where f121='Test 3.5.7.5/6'; f121 f122 -Test 3.5.7.5/6 Trigger1 3.5.7.5/6 +Test 3.5.7.5/6 Trigger2 3.5.7.5 update tb3 set f122='Update 3.5.7.6' where f121= 'Test 3.5.7.5/6'; Select f121,f122 from tb3 where f121='Test 3.5.7.5/6'; f121 f122 @@ -352,7 +351,6 @@ Create trigger trg6_1 AFTER INSERT on tb3 for each row set @test_var='Trigger1 3.5.7.7/8'; Create trigger trg6_2 AFTER INSERT on tb3 for each row set @test_var='Trigger2 3.5.7.7'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var Before trig 3.5.7.7 @@ -362,14 +360,14 @@ f121 f122 Test 3.5.7.7/8 Insert 3.5.7.7 select @test_var; @test_var -Trigger1 3.5.7.7/8 +Trigger2 3.5.7.7 update tb3 set f122='Update 3.5.7.8' where f121= 'Test 3.5.7.7/8'; Select f121,f122 from tb3 where f121='Test 3.5.7.7/8'; f121 f122 Test 3.5.7.7/8 Update 3.5.7.8 select @test_var; @test_var -Trigger1 3.5.7.7/8 +Trigger2 3.5.7.7 drop trigger trg6_1; drop trigger trg6_2; delete from tb3 where f121='Test 3.5.7.7/8'; @@ -380,7 +378,6 @@ Create trigger trg7_1 BEFORE UPDATE on tb3 for each row set new.f122='Trigger1 3.5.7.9/10'; Create trigger trg7_2 BEFORE UPDATE on tb3 for each row set new.f122='Trigger2 3.5.7.9'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Insert into tb3 (f121,f122) values ('Test 3.5.7.9/10','Insert 3.5.7.9'); Select f121,f122 from tb3 where f121='Test 3.5.7.9/10'; f121 f122 @@ -388,7 +385,7 @@ Test 3.5.7.9/10 Insert 3.5.7.9 update tb3 set f122='update 3.5.7.10' where f121='Test 3.5.7.9/10'; Select f121,f122 from tb3 where f121='Test 3.5.7.9/10'; f121 f122 -Test 3.5.7.9/10 Trigger1 3.5.7.9/10 +Test 3.5.7.9/10 Trigger2 3.5.7.9 drop trigger trg7_1; drop trigger trg7_2; delete from tb3 where f121='Test 3.5.7.9/10'; @@ -400,7 +397,6 @@ Create trigger trg8_1 AFTER UPDATE on tb3 for each row set @test_var='Trigger 3.5.7.11/12'; Create trigger trg8_2 AFTER UPDATE on tb3 for each row set @test_var='Trigger2 3.5.7.11'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var Before trig 3.5.7.11 @@ -417,7 +413,7 @@ f121 f122 Test 3.5.7.11/12 update 3.5.7.12 select @test_var; @test_var -Trigger 3.5.7.11/12 +Trigger2 3.5.7.11 delete from tb3 where f121='Test 3.5.7.11/12'; drop trigger trg8_1; drop trigger trg8_2; @@ -430,7 +426,6 @@ Create trigger trg9_1 BEFORE DELETE on tb3 for each row set @test_var=@test_var+1; Create trigger trg9_2 BEFORE DELETE on tb3 for each row set @test_var=@test_var+10; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var 1 @@ -446,11 +441,11 @@ Select f121,f122 from tb3 where f121='Test 3.5.7.13/14'; f121 f122 select @test_var; @test_var -2 +12 delete from tb3 where f121='Test 3.5.7.13/14'; select @test_var; @test_var -2 +12 drop trigger trg9_1; drop trigger trg9_2; delete from tb3 where f121='Test 3.5.7.13/14'; @@ -462,7 +457,6 @@ Create trigger trg_3_406010_1 AFTER DELETE on tb3 for each row set @test_var=@test_var+5; Create trigger trg_3_406010_2 AFTER DELETE on tb3 for each row set @test_var=@test_var+50; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Create trigger trg_3_406010_1 AFTER INSERT on tb3 for each row set @test_var=@test_var+1; ERROR HY000: Trigger already exists @@ -481,11 +475,11 @@ Select f121,f122 from tb3 where f121='Test 3.5.7.15/16'; f121 f122 select @test_var; @test_var -6 +56 delete from tb3 where f121='Test 3.5.7.15/16'; select @test_var; @test_var -6 +56 drop trigger trg_3_406010_1; drop trigger trg_3_406010_2; delete from tb3 where f121='Test 3.5.7.15/16'; diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result index 420bdf2dc2d..d1ab5674cb4 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_03e.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_03e.result @@ -487,8 +487,8 @@ create trigger trg1_4 before UPDATE on t1 for each row set new.f1 = 'trig 1_4-yes'; show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1_3 INSERT t1 set new.f1 = 'trig 1_3-yes' BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci -trg1_4 UPDATE t1 set new.f1 = 'trig 1_4-yes' BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1_3 INSERT t1 set new.f1 = 'trig 1_3-yes' BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1_4 UPDATE t1 set new.f1 = 'trig 1_4-yes' BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION test_yesprivs@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection no_privs; select current_user; current_user diff --git a/mysql-test/suite/funcs_1/r/myisam_trig_0407.result b/mysql-test/suite/funcs_1/r/myisam_trig_0407.result index 9b23271958a..72a7cb4f01d 100644 --- a/mysql-test/suite/funcs_1/r/myisam_trig_0407.result +++ b/mysql-test/suite/funcs_1/r/myisam_trig_0407.result @@ -332,11 +332,10 @@ Create trigger trg5_1 BEFORE INSERT on tb3 for each row set new.f122='Trigger1 3.5.7.5/6'; Create trigger trg5_2 BEFORE INSERT on tb3 for each row set new.f122='Trigger2 3.5.7.5'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Insert into tb3 (f121,f122) values ('Test 3.5.7.5/6','Insert 3.5.7.5'); Select f121,f122 from tb3 where f121='Test 3.5.7.5/6'; f121 f122 -Test 3.5.7.5/6 Trigger1 3.5.7.5/6 +Test 3.5.7.5/6 Trigger2 3.5.7.5 update tb3 set f122='Update 3.5.7.6' where f121= 'Test 3.5.7.5/6'; Select f121,f122 from tb3 where f121='Test 3.5.7.5/6'; f121 f122 @@ -352,7 +351,6 @@ Create trigger trg6_1 AFTER INSERT on tb3 for each row set @test_var='Trigger1 3.5.7.7/8'; Create trigger trg6_2 AFTER INSERT on tb3 for each row set @test_var='Trigger2 3.5.7.7'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var Before trig 3.5.7.7 @@ -362,14 +360,14 @@ f121 f122 Test 3.5.7.7/8 Insert 3.5.7.7 select @test_var; @test_var -Trigger1 3.5.7.7/8 +Trigger2 3.5.7.7 update tb3 set f122='Update 3.5.7.8' where f121= 'Test 3.5.7.7/8'; Select f121,f122 from tb3 where f121='Test 3.5.7.7/8'; f121 f122 Test 3.5.7.7/8 Update 3.5.7.8 select @test_var; @test_var -Trigger1 3.5.7.7/8 +Trigger2 3.5.7.7 drop trigger trg6_1; drop trigger trg6_2; delete from tb3 where f121='Test 3.5.7.7/8'; @@ -380,7 +378,6 @@ Create trigger trg7_1 BEFORE UPDATE on tb3 for each row set new.f122='Trigger1 3.5.7.9/10'; Create trigger trg7_2 BEFORE UPDATE on tb3 for each row set new.f122='Trigger2 3.5.7.9'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Insert into tb3 (f121,f122) values ('Test 3.5.7.9/10','Insert 3.5.7.9'); Select f121,f122 from tb3 where f121='Test 3.5.7.9/10'; f121 f122 @@ -388,7 +385,7 @@ Test 3.5.7.9/10 Insert 3.5.7.9 update tb3 set f122='update 3.5.7.10' where f121='Test 3.5.7.9/10'; Select f121,f122 from tb3 where f121='Test 3.5.7.9/10'; f121 f122 -Test 3.5.7.9/10 Trigger1 3.5.7.9/10 +Test 3.5.7.9/10 Trigger2 3.5.7.9 drop trigger trg7_1; drop trigger trg7_2; delete from tb3 where f121='Test 3.5.7.9/10'; @@ -400,7 +397,6 @@ Create trigger trg8_1 AFTER UPDATE on tb3 for each row set @test_var='Trigger 3.5.7.11/12'; Create trigger trg8_2 AFTER UPDATE on tb3 for each row set @test_var='Trigger2 3.5.7.11'; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var Before trig 3.5.7.11 @@ -417,7 +413,7 @@ f121 f122 Test 3.5.7.11/12 update 3.5.7.12 select @test_var; @test_var -Trigger 3.5.7.11/12 +Trigger2 3.5.7.11 delete from tb3 where f121='Test 3.5.7.11/12'; drop trigger trg8_1; drop trigger trg8_2; @@ -430,7 +426,6 @@ Create trigger trg9_1 BEFORE DELETE on tb3 for each row set @test_var=@test_var+1; Create trigger trg9_2 BEFORE DELETE on tb3 for each row set @test_var=@test_var+10; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' select @test_var; @test_var 1 @@ -446,11 +441,11 @@ Select f121,f122 from tb3 where f121='Test 3.5.7.13/14'; f121 f122 select @test_var; @test_var -2 +12 delete from tb3 where f121='Test 3.5.7.13/14'; select @test_var; @test_var -2 +12 drop trigger trg9_1; drop trigger trg9_2; delete from tb3 where f121='Test 3.5.7.13/14'; @@ -462,7 +457,6 @@ Create trigger trg_3_406010_1 AFTER DELETE on tb3 for each row set @test_var=@test_var+5; Create trigger trg_3_406010_2 AFTER DELETE on tb3 for each row set @test_var=@test_var+50; -ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table' Create trigger trg_3_406010_1 AFTER INSERT on tb3 for each row set @test_var=@test_var+1; ERROR HY000: Trigger already exists @@ -481,11 +475,11 @@ Select f121,f122 from tb3 where f121='Test 3.5.7.15/16'; f121 f122 select @test_var; @test_var -6 +56 delete from tb3 where f121='Test 3.5.7.15/16'; select @test_var; @test_var -6 +56 drop trigger trg_3_406010_1; drop trigger trg_3_406010_2; delete from tb3 where f121='Test 3.5.7.15/16'; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc index 2bbcc5f88f0..e56a5972ce6 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_db_table_mix.inc @@ -120,6 +120,7 @@ let $message= no trigger privilege on table level for create:; connection default; select current_user; +--replace_column 6 # show triggers; grant TRIGGER on priv1_db.t1 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; @@ -128,6 +129,7 @@ let $message= trigger privilege on table level for create:; --source include/show_msg.inc connection yes_privs; select current_user; +--replace_column 6 # show triggers; create trigger trg1_2 before INSERT on t1 for each row set new.f1 = 'trig 1_2-yes'; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc index eebdff5b588..f84474f1541 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_global_db_mix.inc @@ -84,6 +84,7 @@ let $message= trigger privilege on user level for create:; connect (yes_privs,localhost,test_yesprivs,PWD,test,$MASTER_MYPORT,$MASTER_MYSOCK); select current_user; use priv_db; +--replace_column 6 # show triggers; select * from information_schema.triggers; --error ER_TABLEACCESS_DENIED_ERROR diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc index 6258b040642..e2efa5774fa 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_prepare.inc @@ -36,6 +36,7 @@ let $message= #### Testcase for trigger privilege on execution time ########; connection default; select current_user; +--replace_column 6 # show triggers; grant select, insert, update ,trigger on priv_db.t1 to test_yesprivs@localhost diff --git a/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc b/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc index ca4b9e2a0a9..bd6bee9bcf2 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_03e_table_level.inc @@ -44,6 +44,7 @@ let $message= no trigger privilege on table level for create:; --source include/show_msg.inc connection default; select current_user; +--replace_column 6 # show triggers; grant select, insert, update on priv_db.t1 to test_yesprivs@localhost; show grants for test_yesprivs@localhost; @@ -68,6 +69,7 @@ let $message= no trigger privilege on table level for create:; connection default; select current_user; +--replace_column 6 # show triggers; show tables; insert into t1 (f1) values ('insert2-yes'); @@ -81,6 +83,7 @@ let $message= trigger privilege on table level for create:; --source include/show_msg.inc connection yes_privs; select current_user; +--replace_column 6 # show triggers; create trigger trg1_2 before INSERT on t1 for each row set new.f1 = 'trig 1_2-yes'; @@ -179,6 +182,7 @@ let $message= use table with trigger privilege and without...:; set new.f1 = 'trig 2_2-no'; create trigger trg1_4 before UPDATE on t1 for each row set new.f1 = 'trig 1_4-yes'; +--replace_column 6 # show triggers; connection no_privs; select current_user; diff --git a/mysql-test/suite/funcs_1/triggers/triggers_0407.inc b/mysql-test/suite/funcs_1/triggers/triggers_0407.inc index 907260a00f0..71471696761 100644 --- a/mysql-test/suite/funcs_1/triggers/triggers_0407.inc +++ b/mysql-test/suite/funcs_1/triggers/triggers_0407.inc @@ -420,16 +420,15 @@ let $message= Testcase 3.5.7.4:; --enable_warnings #Section 3.5.7.5 / 3.5.7.6 -# Test case: Ensure that it is not possible to create multiple BEFORE INSERT triggers -# on the same table, even if the triggers have different names / different -# triggered actions. +# Test case: Ensure that it is possible to create multiple BEFORE INSERT +# triggers on the same table +# let $message= Testcase 3.5.7.5 / 3.5.7.6:; --source include/show_msg.inc Create trigger trg5_1 BEFORE INSERT on tb3 for each row set new.f122='Trigger1 3.5.7.5/6'; - --error ER_NOT_SUPPORTED_YET Create trigger trg5_2 BEFORE INSERT on tb3 for each row set new.f122='Trigger2 3.5.7.5'; @@ -441,16 +440,14 @@ let $message= Testcase 3.5.7.5 / 3.5.7.6:; #Cleanup --disable_warnings drop trigger trg5_1; - --error 0, ER_TRG_DOES_NOT_EXIST drop trigger trg5_2; delete from tb3 where f121='Test 3.5.7.5/6'; --enable_warnings #Section 3.5.7.7 / 3.5.7.8 -# Test case: Ensure that it is not possible to create multiple AFTER INSERT triggers -# on the same table, even if the triggers have different names / different -# triggered actions. +# Test case: Ensure that it is possible to create multiple AFTER INSERT +# triggers on the same table let $message= Testcase 3.5.7.7 / 3.5.7.8:; --source include/show_msg.inc @@ -458,7 +455,6 @@ let $message= Testcase 3.5.7.7 / 3.5.7.8:; Create trigger trg6_1 AFTER INSERT on tb3 for each row set @test_var='Trigger1 3.5.7.7/8'; - --error ER_NOT_SUPPORTED_YET Create trigger trg6_2 AFTER INSERT on tb3 for each row set @test_var='Trigger2 3.5.7.7'; @@ -473,23 +469,20 @@ let $message= Testcase 3.5.7.7 / 3.5.7.8:; #Cleanup --disable_warnings drop trigger trg6_1; - --error 0, ER_TRG_DOES_NOT_EXIST drop trigger trg6_2; delete from tb3 where f121='Test 3.5.7.7/8'; --enable_warnings #Section 3.5.7.9 / 3.5.7.10 -# Test case: Ensure that it is not possible to create multiple BEFORE UPDATE triggers -# on the same table, even if the triggers have different names / different -# triggered actions. +# Test case: Ensure that it is possible to create multiple BEFORE UPDATE +# triggers on the same table let $message= Testcase 3.5.7.9/10:; --source include/show_msg.inc Create trigger trg7_1 BEFORE UPDATE on tb3 for each row set new.f122='Trigger1 3.5.7.9/10'; - --error ER_NOT_SUPPORTED_YET Create trigger trg7_2 BEFORE UPDATE on tb3 for each row set new.f122='Trigger2 3.5.7.9'; @@ -501,14 +494,12 @@ let $message= Testcase 3.5.7.9/10:; #Cleanup --disable_warnings drop trigger trg7_1; - --error 0, ER_TRG_DOES_NOT_EXIST drop trigger trg7_2; delete from tb3 where f121='Test 3.5.7.9/10'; #Section 3.5.7.11 / 3.5.7.12 -# Test case: Ensure that it is not possible to create multiple AFTER UPDATE triggers -# on the same table, even if the triggers have different names / different -# triggered actions. +# Test case: Ensure that it is possible to create multiple AFTER UPDATE +# triggers on the same table let $message= Testcase 3.5.7.11/12:; --source include/show_msg.inc @@ -516,11 +507,9 @@ let $message= Testcase 3.5.7.11/12:; Create trigger trg8_1 AFTER UPDATE on tb3 for each row set @test_var='Trigger 3.5.7.11/12'; - --error ER_NOT_SUPPORTED_YET Create trigger trg8_2 AFTER UPDATE on tb3 for each row set @test_var='Trigger2 3.5.7.11'; - select @test_var; Insert into tb3 (f121,f122) values ('Test 3.5.7.11/12','Insert 3.5.7.11/12'); select @test_var; @@ -533,14 +522,12 @@ let $message= Testcase 3.5.7.11/12:; #Cleanup --disable_warnings drop trigger trg8_1; - --error 0, ER_TRG_DOES_NOT_EXIST drop trigger trg8_2; delete from tb3 where f121='Test 3.5.7.11/12'; #Section 3.5.7.13 / 3.5.7.14 -# Test case: Ensure that it is not possible to create multiple BEFORE DELETE triggers -# on the same table, even if the triggers have different names / different -# triggered actions. +# Test case: Ensure that it is possible to create multiple BEFORE DELETE +# triggers on the same table let $message= Testcase 3.5.7.13/14:; --source include/show_msg.inc @@ -548,7 +535,6 @@ let $message= Testcase 3.5.7.13/14:; Create trigger trg9_1 BEFORE DELETE on tb3 for each row set @test_var=@test_var+1; - --error ER_NOT_SUPPORTED_YET Create trigger trg9_2 BEFORE DELETE on tb3 for each row set @test_var=@test_var+10; @@ -565,14 +551,12 @@ let $message= Testcase 3.5.7.13/14:; #Cleanup --disable_warnings drop trigger trg9_1; - --error 0, ER_TRG_DOES_NOT_EXIST drop trigger trg9_2; delete from tb3 where f121='Test 3.5.7.13/14'; #Section 3.5.7.15 / 3.5.7.16 -# Test case: Ensure that it is not possible to create multiple AFTER DELETE triggers -# on the same table, even if the triggers have different names / different -# triggered actions. +# Test case: Ensure that possible to create multiple AFTER DELETE triggers +# on the same table let $message= Testcase 3.5.7.15/16:; --source include/show_msg.inc @@ -580,7 +564,6 @@ let $message= Testcase 3.5.7.15/16:; Create trigger trg_3_406010_1 AFTER DELETE on tb3 for each row set @test_var=@test_var+5; - --error ER_NOT_SUPPORTED_YET Create trigger trg_3_406010_2 AFTER DELETE on tb3 for each row set @test_var=@test_var+50; @@ -601,7 +584,6 @@ let $message= Testcase 3.5.7.15/16:; #Cleanup --disable_warnings drop trigger trg_3_406010_1; - --error 0, ER_TRG_DOES_NOT_EXIST drop trigger trg_3_406010_2; delete from tb3 where f121='Test 3.5.7.15/16'; --enable_warnings diff --git a/mysql-test/suite/roles/definer.result b/mysql-test/suite/roles/definer.result index 4810e597763..e3b2d6ac758 100644 --- a/mysql-test/suite/roles/definer.result +++ b/mysql-test/suite/roles/definer.result @@ -108,9 +108,9 @@ set role role1; create definer=current_role trigger tr1 before insert on t2 for each row insert t1 values (111, 222, 333); show create trigger tr1; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created tr1 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role1` trigger tr1 before insert on t2 for each row -insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # set role none; insert t2 values (11,22,33); ERROR 42000: INSERT command denied to user ''@'' for table 't1' @@ -125,9 +125,9 @@ a b c create definer=role2 trigger tr2 before delete on t2 for each row insert t1 values (111, 222, 333); show create trigger tr2; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created tr2 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role2` trigger tr2 before delete on t2 for each row -insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # delete from t2 where a=1; select * from t1; a b c @@ -143,9 +143,9 @@ insert t1 values (111, 222, 333); Warnings: Note 1449 The user specified as a definer ('role3'@'%') does not exist show create trigger tr3; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created tr3 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role3`@`%` trigger tr3 before update on t2 for each row -insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # update t2 set b=2 where a=2; ERROR HY000: The user specified as a definer ('role3'@'%') does not exist select * from t1; @@ -157,9 +157,9 @@ a b c 2 20 200 flush tables; show create trigger tr2; -Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation +Trigger sql_mode SQL Original Statement character_set_client collation_connection Database Collation Created tr2 NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION CREATE DEFINER=`role2`@`` trigger tr2 before delete on t2 for each row -insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci +insert t1 values (111, 222, 333) latin1 latin1_swedish_ci latin1_swedish_ci # delete from t2 where a=2; ERROR HY000: The user specified as a definer ('role2'@'%') does not exist select * from t1; diff --git a/mysql-test/suite/roles/definer.test b/mysql-test/suite/roles/definer.test index 090c60917c9..a4a65a77a9b 100644 --- a/mysql-test/suite/roles/definer.test +++ b/mysql-test/suite/roles/definer.test @@ -138,6 +138,7 @@ create definer=current_role trigger tr1 before insert on t2 for each row 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; @@ -149,6 +150,7 @@ 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; @@ -158,6 +160,7 @@ 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; @@ -178,6 +181,7 @@ 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; diff --git a/mysql-test/suite/rpl/r/rpl_ddl.result b/mysql-test/suite/rpl/r/rpl_ddl.result index 7bb9bd02cba..68c5e91f42e 100644 --- a/mysql-test/suite/rpl/r/rpl_ddl.result +++ b/mysql-test/suite/rpl/r/rpl_ddl.result @@ -1267,11 +1267,11 @@ TEST-INFO: SLAVE: The INSERT is committed (Succeeded) connection master; SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @a:=1 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection slave; SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 SET @a:=1 BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection master; ######## DROP TRIGGER trg1 ######## diff --git a/mysql-test/suite/rpl/r/rpl_replicate_do.result b/mysql-test/suite/rpl/r/rpl_replicate_do.result index c7ac37a9654..115c27d9387 100644 --- a/mysql-test/suite/rpl/r/rpl_replicate_do.result +++ b/mysql-test/suite/rpl/r/rpl_replicate_do.result @@ -39,8 +39,8 @@ t1 t2 show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 set new.b=2 BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci -trg2 INSERT t2 set new.b=2 BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 set new.b=2 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg2 INSERT t2 set new.b=2 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection slave; connection slave; show tables; @@ -48,7 +48,7 @@ Tables_in_test t1 show triggers; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 set new.b=2 BEFORE NULL NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 set new.b=2 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci connection master; drop trigger trg1; drop trigger trg2; diff --git a/mysql-test/suite/rpl/r/rpl_trigger.result b/mysql-test/suite/rpl/r/rpl_trigger.result index 729d31fb001..dcf0c70ffc4 100644 --- a/mysql-test/suite/rpl/r/rpl_trigger.result +++ b/mysql-test/suite/rpl/r/rpl_trigger.result @@ -972,7 +972,7 @@ t1 t2 SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation -trg1 INSERT t1 INSERT INTO t2 VALUES(CURRENT_USER()) AFTER NULL latin1 latin1_swedish_ci latin1_swedish_ci +trg1 INSERT t1 INSERT INTO t2 VALUES(CURRENT_USER()) AFTER # latin1 latin1_swedish_ci latin1_swedish_ci SELECT * FROM t1; c 1 @@ -1115,4 +1115,47 @@ Log_name Pos Event_type Server_id End_log_pos Info slave-bin.000001 # Gtid # # GTID #-#-# slave-bin.000001 # Query # # use `test`; drop trigger if exists notexistent connection master; +create table t1 (a int primary key, b int); +create trigger tr3 +before insert on t1 +for each row set NEW.b := (NEW.b+1)*4; +create trigger tr1 +before insert on t1 +for each row precedes tr3 set NEW.b := (NEW.b+1)*2; +create trigger tr2 +before insert on t1 +for each row follows tr1 set NEW.b := (NEW.b+1)*3; +show triggers; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1 INSERT t1 set NEW.b := (NEW.b+1)*2 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr2 INSERT t1 set NEW.b := (NEW.b+1)*3 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr3 INSERT t1 set NEW.b := (NEW.b+1)*4 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +insert into t1 values (1,1); +select * from t1; +a b +1 64 +connection slave; +show triggers; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr1 INSERT t1 set NEW.b := (NEW.b+1)*2 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr2 INSERT t1 set NEW.b := (NEW.b+1)*3 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +tr3 INSERT t1 set NEW.b := (NEW.b+1)*4 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +select * from t1; +a b +1 64 +connection master; +drop table t1; +CREATE TABLE t1 (i INT); +CREATE OR REPLACE TRIGGER tr BEFORE INSERT ON t1 FOR EACH ROW SET @a=1; +CREATE OR REPLACE TRIGGER tr BEFORE DELETE ON t1 FOR EACH ROW PRECEDES non_existing_trigger SET @a=2; +ERROR HY000: Referenced trigger 'non_existing_trigger' for the given action time and event type does not exist +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr INSERT t1 SET @a=1 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +connection slave; +SHOW TRIGGERS; +Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation +tr INSERT t1 SET @a=1 BEFORE # NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION root@localhost latin1 latin1_swedish_ci latin1_swedish_ci +connection master; +drop table t1; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_replicate_do.test b/mysql-test/suite/rpl/t/rpl_replicate_do.test index e2b488394d1..66ddf2dfe0a 100644 --- a/mysql-test/suite/rpl/t/rpl_replicate_do.test +++ b/mysql-test/suite/rpl/t/rpl_replicate_do.test @@ -41,18 +41,22 @@ create trigger trg1 before insert on t1 for each row set new.b=2; create table t2 (a int, b int); create trigger trg2 before insert on t2 for each row set new.b=2; show tables; +--replace_column 6 # show triggers; sync_slave_with_master; connection slave; show tables; +--replace_column 6 # show triggers; connection master; drop trigger trg1; drop trigger trg2; +--replace_column 6 # show triggers; sync_slave_with_master; connection slave; show tables; +--replace_column 6 # show triggers; connection master; drop table t1; diff --git a/mysql-test/suite/rpl/t/rpl_trigger.test b/mysql-test/suite/rpl/t/rpl_trigger.test index 83097e7bd0a..f692816bf82 100644 --- a/mysql-test/suite/rpl/t/rpl_trigger.test +++ b/mysql-test/suite/rpl/t/rpl_trigger.test @@ -337,6 +337,7 @@ SELECT MASTER_POS_WAIT('master-bin.000001', 513) >= 0; # Check that the replication succeeded. SHOW TABLES LIKE 't_'; +--replace_column 6 # SHOW TRIGGERS; SELECT * FROM t1; SELECT * FROM t2; @@ -367,6 +368,7 @@ RESET SLAVE; connection master; SHOW TABLES LIKE 't_'; +--replace_column 6 # SHOW TRIGGERS; RESET MASTER; @@ -535,6 +537,49 @@ source include/show_binlog_events.inc; connection master; # +# MDEV-6112 multiple triggers per table +# + +create table t1 (a int primary key, b int); +create trigger tr3 + before insert on t1 + for each row set NEW.b := (NEW.b+1)*4; +create trigger tr1 + before insert on t1 + for each row precedes tr3 set NEW.b := (NEW.b+1)*2; +create trigger tr2 + before insert on t1 + for each row follows tr1 set NEW.b := (NEW.b+1)*3; + +--replace_column 6 # +show triggers; +insert into t1 values (1,1); +select * from t1; +sync_slave_with_master; +--replace_column 6 # +show triggers; +select * from t1; +connection master; +drop table t1; + +# +# MDEV-10924 CREATE OR REPLACE TRIGGER which fails on PRECEDES/FOLLOWS drops +# the trigger, but isn't written to binlog; replication fails +# + +CREATE TABLE t1 (i INT); +CREATE OR REPLACE TRIGGER tr BEFORE INSERT ON t1 FOR EACH ROW SET @a=1; +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE OR REPLACE TRIGGER tr BEFORE DELETE ON t1 FOR EACH ROW PRECEDES non_existing_trigger SET @a=2; +--replace_column 6 # +SHOW TRIGGERS; +--sync_slave_with_master +--replace_column 6 # +SHOW TRIGGERS; +connection master; +drop table t1; + +# # End of tests # --source include/rpl_end.inc diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 0fd3e31a5b4..d619fed240f 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1297,7 +1297,6 @@ BEGIN UPDATE A SET `pk`=1 WHERE `pk`=0 ; END ;| ---error ER_NOT_SUPPORTED_YET CREATE TRIGGER f1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN UPDATE A SET `pk`=1 WHERE `pk`=0 ; diff --git a/mysql-test/t/create_drop_trigger.test b/mysql-test/t/create_drop_trigger.test index a8afc8716d6..0f19f5cf09f 100644 --- a/mysql-test/t/create_drop_trigger.test +++ b/mysql-test/t/create_drop_trigger.test @@ -6,7 +6,6 @@ SET @sum=0; INSERT INTO t1 VALUES (10), (20), (30); SELECT @sum; ---error ER_NOT_SUPPORTED_YET CREATE TRIGGER IF NOT EXISTS val_sum_new BEFORE INSERT ON t1 FOR EACH ROW SET @sum = @sum + NEW.val; CREATE TRIGGER IF NOT EXISTS val_sum AFTER INSERT ON t1 FOR EACH ROW SET @sum = @sum + 1 + NEW.val; diff --git a/mysql-test/t/features.test b/mysql-test/t/features.test index 63e923a772b..1241bd50bdd 100644 --- a/mysql-test/t/features.test +++ b/mysql-test/t/features.test @@ -98,6 +98,7 @@ set @a:=0; select @a; insert into t1 values (1),(2); select @a; +--replace_column 6 # SHOW TRIGGERS IN test like 't1'; drop trigger trg; drop table t1; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 13f368b6dbe..1443f654809 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -576,7 +576,9 @@ begin end if; end| delimiter ;| +--replace_column 6 # show triggers; +--replace_column 17 # select * from information_schema.triggers where trigger_schema in ('mysql', 'information_schema', 'test', 'mysqltest'); drop trigger trg1; @@ -1034,12 +1036,14 @@ grant select(b) on mysqltest.t1 to mysqltest_1@localhost; select trigger_name from information_schema.triggers where event_object_table='t1'; +--replace_column 6 # show triggers from mysqltest; connect (con27629,localhost,mysqltest_1,,mysqltest); show columns from t1; select column_name from information_schema.columns where table_name='t1'; +--replace_column 6 # show triggers; select trigger_name from information_schema.triggers where event_object_table='t1'; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index faa420fd275..689c52faabc 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -1678,6 +1678,7 @@ CREATE TABLE t1(a int); CREATE TABLE t2(a int); CREATE TABLE t3(a int) ENGINE = MERGE UNION(t1, t2); CREATE TRIGGER tr1 AFTER INSERT ON t3 FOR EACH ROW CALL foo(); +--replace_column 7 # SHOW CREATE TRIGGER tr1; DROP TRIGGER tr1; DROP TABLE t1, t2, t3; diff --git a/mysql-test/t/mysql_comments.test b/mysql-test/t/mysql_comments.test index 7b00f17e259..fb0e5f94950 100644 --- a/mysql-test/t/mysql_comments.test +++ b/mysql-test/t/mysql_comments.test @@ -30,10 +30,12 @@ drop trigger if exists t1_bi; # Test without comments --echo "Pass 1 : --disable-comments" +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/ --exec $MYSQL --disable-comments test 2>&1 < "./t/mysql_comments.sql" # Test with comments --echo "Pass 2 : --enable-comments" +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/ --exec $MYSQL --enable-comments test 2>&1 < "./t/mysql_comments.sql" diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index ccc68485bd6..299698ed04b 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1007,6 +1007,7 @@ SELECT * FROM `test2`; #DROP TABLE test2; # restore --exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/mysqldump.sql +--replace_column 6 # SHOW TRIGGERS; SELECT * FROM `test1`; SELECT * FROM `test2`; @@ -2053,6 +2054,7 @@ CREATE PROCEDURE pr1 () SELECT "Meow"; CREATE EVENT ev1 ON SCHEDULE AT '2030-01-01 00:00:00' DO SELECT "Meow"; --echo +--replace_column 6 # SHOW TRIGGERS; SHOW EVENTS; SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; @@ -2071,6 +2073,7 @@ DROP PROCEDURE pr1; --echo --echo reload table; this should restore table and trigger --exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/t1.sql +--replace_column 6 # SHOW TRIGGERS; SHOW EVENTS; SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; @@ -2078,6 +2081,7 @@ SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; --echo --echo reload db; this should restore routines and events --exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/test_34861.sql +--replace_column 6 # SHOW TRIGGERS; SHOW EVENTS; SELECT name,body FROM mysql.proc WHERE NAME = 'pr1'; @@ -2311,13 +2315,13 @@ CREATE VIEW v2 AS SELECT * FROM t2; --echo # Dumping BUG52792 database in xml format. --echo --echo # Running 'replace_regex on timestamp' ---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/ --exec $MYSQL_DUMP --user=root --compact -R -E --triggers -X BUG52792 --echo --echo # Dumping BUG52792 database in xml format with comments. --echo --echo # Running 'replace_regex on timestamp' ---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/ --exec $MYSQL_DUMP --comments --user=root -R -E --triggers -X BUG52792 --echo @@ -2330,7 +2334,8 @@ connect (conn_1, localhost, user1, , BUG52792, $MASTER_MYPORT, $MASTER_MYSOCK); connection conn_1; --echo # Running 'replace_regex on timestamp' ---replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/--TIME--/ +--replace_regex /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]{2})*/--TIME--/ + --replace_result mysqldump.exe mysqldump --error 2 --exec $MYSQL_DUMP --user=user1 -R -E --triggers -X BUG52792 diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index a14c42d8ade..13ca9a528c6 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -774,6 +774,7 @@ SHOW COLUMNS FROM t1; --echo ---------------------------------------------------------------- +--replace_column 6 # SHOW TRIGGERS LIKE 't1'; --echo ---------------------------------------------------------------- @@ -799,6 +800,14 @@ SELECT FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name = 't1_bi'; +# Metadata is different for the field "CREATED" with and without --ps +# So test it separately. + +--disable_ps_protocol +--replace_column 1 # +SELECT CREATED FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_name='t1_bi'; +--enable_ps_protocol + --echo ---------------------------------------------------------------- SHOW CREATE VIEW v1; @@ -1092,32 +1101,53 @@ CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1; # Test. +--replace_column 7 # SHOW CREATE TRIGGER t1_bi; CREATE PROCEDURE p1() SHOW CREATE TRIGGER t1_bi; +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); +--replace_column 7 # CALL p1(); PREPARE stmt1 FROM 'SHOW CREATE TRIGGER t1_bi'; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; +--replace_column 7 # EXECUTE stmt1; # Cleanup. @@ -1178,6 +1208,7 @@ SHOW CREATE PROCEDURE p1; SHOW CREATE FUNCTION f1; +--replace_column 7 # SHOW CREATE TRIGGER t1_bi; SHOW CREATE EVENT ev1; @@ -1291,6 +1322,7 @@ LOCK TABLE t1 WRITE; connection default; # Should not block. +--replace_column 7 # SHOW CREATE TRIGGER t1_bi; connection con1; @@ -1300,6 +1332,7 @@ UNLOCK TABLES; connection default; START TRANSACTION; +--replace_column 7 # SHOW CREATE TRIGGER t1_bi; connection con1; diff --git a/mysql-test/t/trigger-compat.test b/mysql-test/t/trigger-compat.test index 2d949b0c91e..437df89b4b1 100644 --- a/mysql-test/t/trigger-compat.test +++ b/mysql-test/t/trigger-compat.test @@ -90,6 +90,7 @@ SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_n --echo +--replace_column 17 # SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name; # Clean up @@ -181,6 +182,7 @@ FLUSH TABLE t2; CREATE TRIGGER tr16 AFTER UPDATE ON t1 FOR EACH ROW INSERT INTO t1 VALUES (1); --error ER_PARSE_ERROR CREATE TRIGGER tr22 BEFORE INSERT ON t2 FOR EACH ROW DELETE FROM non_existing_table; +--replace_column 6 # SHOW TRIGGERS; --error ER_PARSE_ERROR INSERT INTO t1 VALUES (1); @@ -193,6 +195,7 @@ UPDATE t1 SET a = 1 WHERE a = 1; SELECT * FROM t1; --error ER_PARSE_ERROR RENAME TABLE t1 TO t1_2; +--replace_column 6 # SHOW TRIGGERS; DROP TRIGGER tr11; @@ -201,6 +204,7 @@ DROP TRIGGER tr13; DROP TRIGGER tr14; DROP TRIGGER tr15; +--replace_column 6 # SHOW TRIGGERS; --echo # Make sure there is no trigger file left. @@ -257,7 +261,7 @@ INSERT INTO t2 VALUES (1), (2), (3); --echo # We write three trigger files. First trigger is syntaxically incorrect, next trigger is correct --echo # and last trigger is broken. ---echo # Next we try to execute SHOW CREATE TRGGIR command for broken trigger and then try to drop one. +--echo # Next we try to execute SHOW CREATE TRIGGER command for broken trigger and then try to drop one. --write_file $MYSQLD_DATADIR/test/tr11.TRN TYPE=TRIGGERNAME trigger_table=t1 diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index a02dce34837..050bd5ea56e 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -324,8 +324,8 @@ create trigger trg before insert on t2 for each row set @a:=1; create trigger trg before insert on t1 for each row set @a:=1; --error ER_TRG_ALREADY_EXISTS create trigger trg after insert on t1 for each row set @a:=1; ---error ER_NOT_SUPPORTED_YET create trigger trg2 before insert on t1 for each row set @a:=1; +drop trigger trg2; --error ER_TRG_ALREADY_EXISTS create trigger trg before insert on t3 for each row set @a:=1; create trigger trg2 before insert on t3 for each row set @a:=1; @@ -2238,9 +2238,9 @@ create table t1 (i int, j int); create trigger t1_bi before insert on t1 for each row begin end; --error ER_TRG_ALREADY_EXISTS create trigger t1_bi before insert on t1 for each row begin end; ---error ER_NOT_SUPPORTED_YET create trigger t1_bi2 before insert on t1 for each row begin end; drop trigger t1_bi; +drop trigger t1_bi2; --error ER_TRG_DOES_NOT_EXIST drop trigger t1_bi; @@ -2392,6 +2392,7 @@ CREATE TABLE t2 (a INT); CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1); --echo # Used to crash +--replace_column 6 # SHOW TRIGGERS IN db1; --error ER_PARSE_ERROR INSERT INTO t2 VALUES (1); @@ -2614,8 +2615,11 @@ DROP TABLE t1, t2; # # MDEV-4829 BEFORE INSERT triggers dont issue 1406 error +# Also check timestamp for trigger # +set time_zone="+00:00"; +SET TIMESTAMP=UNIX_TIMESTAMP('2001-01-01 10:20:30'); SET @@session.sql_mode = 'STRICT_ALL_TABLES,STRICT_TRANS_TABLES'; CREATE TABLE t1 (c CHAR(1) NOT NULL); DELIMITER |; @@ -2631,6 +2635,42 @@ DELIMITER ;| SET @@session.sql_mode = default; --error ER_DATA_TOO_LONG INSERT INTO t1 VALUES ('a'); +show create trigger t1_bi; DROP TRIGGER t1_bi; DROP TABLE t1; +SET TIMESTAMP=DEFAULT; +set time_zone= @@global.time_zone; + +# +# MDEV-10915 Count number of exceuted triggers +# + +create table t1 (i int); +create trigger tr1 after insert on t1 for each row set @a=@a+1; +create trigger tr2 after insert on t1 for each row set @a=@a+1; +create trigger tr3 after insert on t1 for each row set @a=@a+1; +flush status; +show status like 'Executed_triggers'; +set @a=0; +insert into t1 values (1); +show status like 'Executed_triggers'; +select @a; +drop table t1; + +# +# MDEV-10916 In trigger's CREATED time microseconds are misinterpreted +# +create table t1 (i int); +set time_zone="+0:00"; +SET TIMESTAMP=UNIX_TIMESTAMP('2016-01-01 10:10:10.33'); +select now(2); +create or replace trigger tr1 after insert on t1 for each row set @a=@a+1; +SET TIMESTAMP=UNIX_TIMESTAMP('2016-01-01 10:10:10.99'); +select now(2); +create or replace trigger tr2 after insert on t1 for each row set @a=@a+1; +select now(2); +select trigger_name, action_order, created from information_schema.triggers + where event_object_table = 't1' and trigger_schema='test'; +drop table t1; +set time_zone= @@global.time_zone; diff --git a/mysql-test/t/trigger_notembedded.test b/mysql-test/t/trigger_notembedded.test index df5637790af..a31594826e7 100644 --- a/mysql-test/t/trigger_notembedded.test +++ b/mysql-test/t/trigger_notembedded.test @@ -281,6 +281,7 @@ INSERT INTO t1 VALUES(6); # Check that SHOW TRIGGERS statement provides "Definer" column. # +--replace_column 6 # SHOW TRIGGERS; # @@ -339,6 +340,7 @@ SELECT trigger_name, definer FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_n --echo +--replace_column 17 # SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name; # diff --git a/mysql-test/t/trigger_wl3253.test b/mysql-test/t/trigger_wl3253.test new file mode 100644 index 00000000000..3504eeaf889 --- /dev/null +++ b/mysql-test/t/trigger_wl3253.test @@ -0,0 +1,428 @@ +--echo # +--echo # WL#3253: multiple triggers per table +--echo # + +SET @binlog_format_saved = @@binlog_format; +SET binlog_format=ROW; +SET time_zone='+00:00'; + +--echo # +--echo # Test 1. +--echo # Check that the sequence of triggers for the same combination +--echo # of event type/action type can be created for a table +--echo # and is fired consequently in the order of its creation +--echo # during statement execution. +--echo # In this test we check BEFORE triggers. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); + +INSERT INTO t1 VALUES (1); + +SELECT * FROM t2 ORDER BY b; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Test 2. +--echo # Check that the sequence of triggers for the same combination +--echo # of event type/action type can be created for a table +--echo # and is fired consequently in the order of its creation +--echo # during statement execution. +--echo # In this test we check AFTER triggers. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1_bi AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bi AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); + +INSERT INTO t1 VALUES (1); + +SELECT * FROM t2 ORDER BY b; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Test 3. +--echo # Check that the sequences of triggers for the different event types +--echo # can be created for a table and are fired consequently +--echo # in the order of its creation during statement execution. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); + +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a); +CREATE TRIGGER tr2_bu BEFORE UPDATE ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); + +INSERT INTO t1 VALUES (1); + +SELECT * FROM t2 ORDER BY b; + +UPDATE t1 SET a = 5; + +SELECT * FROM t2 ORDER BY b; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Test 4. +--echo # Check that every new created trigger has unique action_order value +--echo # started from 1 and NOT NULL value for creation timestamp. +--echo # + +CREATE TABLE t1 (a INT); + +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:00'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; + +SELECT trigger_name, created, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; + +--echo # +--echo # Test 5. +--echo # Check that action_order attribute isn't shown +--echo # in the output of SHOW TRIGGERS and SHOW CREATE TRIGGER +--echo # + +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; + +--replace_column 6 # +SHOW TRIGGERS; + +--replace_column 17 # +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; + +--replace_column 7 # +SHOW CREATE TRIGGER tr1_bi; + +DROP TABLE t1; + +--echo # +--echo # Test 6. +--echo # Check that action_order attribute is reused when trigger +--echo # are recreated. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TRIGGER tr1_bi; + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TABLE t1; + +--echo # +--echo # Test 7. +--echo # Check that it is possible to create several triggers with +--echo # the same value for creation timestamp. +--echo # + +CREATE TABLE t1 (a INT); + +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; + +SELECT trigger_name, created, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; + +--echo # +--echo # Test 8. +--echo # Check that SHOW CREATE TRIGGER outputs the CREATED attribute +--echo # and it is not NULL +--echo # + +CREATE TABLE t1 (a INT); + +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +SHOW CREATE TRIGGER tr1_bi; + +DROP TABLE t1; +SET TIMESTAMP=DEFAULT; + +--echo # +--echo # Test 9. +--echo # Check that SHOW TRIGGERS outputs the CREATED attribute +--echo # and it is not NULL. +--echo # + +CREATE TABLE t1 (a INT); + +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:01'); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; + +SHOW TRIGGERS; + +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; + +DROP TABLE t1; + +SET TIMESTAMP=DEFAULT; + +--echo # +--echo # Test 10. +--echo # Check that FOLLOWS clause is supported and works correctly. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi INSERT INTO t2 (a) VALUES (NEW.a + 200); + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Test 11. +--echo # Check that PRECEDES clause is supported and works correctly. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 300); +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr3_bi INSERT INTO t2 (a) VALUES (NEW.a + 200); + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Test 12. +--echo # Check that the PRECEDES works properly for the 1st trigger in the chain. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT AUTO_INCREMENT PRIMARY KEY); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 (a) VALUES (NEW.a + 100); +CREATE TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr1_bi INSERT INTO t2 (a) VALUES (NEW.a); + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +INSERT INTO t1 VALUES (1); +SELECT * FROM t2 ORDER BY b; + +DROP TABLE t2; +DROP TABLE t1; + +--echo # +--echo # Test 13. +--echo # Check that error is reported if the FOLLOWS clause references to +--echo # non-existing trigger +--echo # + +CREATE TABLE t1 (a INT); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=3; + +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr0_bi SET @a:=2; + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TABLE t1; + +--echo # +--echo # Test 14. +--echo # Check that error is reported if the PRECEDES clause references to +--echo # non-existing trigger +--echo # + +CREATE TABLE t1 (a INT); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=3; + +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr0_bi SET @a:=2; + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TABLE t1; + +--echo # +--echo # Test 15. +--echo # Check that action_order value is independent for each type of event +--echo # (INSERT/UPDATE/DELETE) +--echo # + +CREATE TABLE t1 (a INT); + +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +CREATE TRIGGER tr3_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr2_bi SET @a:=3; +CREATE TRIGGER tr2_bu BEFORE UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bu SET @a:=3; + +SELECT trigger_name, action_order FROM information_schema.triggers WHERE trigger_schema='test'; + +DROP TABLE t1; + +--echo # +--echo # Test 16. +--echo # Check that the trigger in the clause FOLLOWS/PRECEDES can refences +--echo # only to the trigger for the same ACTION/TIMINMG +--echo # + +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; + +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE TRIGGER tr2_bu BEFORE UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=3; + +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE TRIGGER tr2_au AFTER UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=3; + +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE TRIGGER tr1_au AFTER UPDATE ON t1 FOR EACH ROW FOLLOWS tr1_bu SET @a:=3; + +--error ER_REFERENCED_TRG_DOES_NOT_EXIST +CREATE TRIGGER tr1_ai AFTER INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=3; + +--replace_column 6 # +SHOW TRIGGERS; + +--replace_column 17 # +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; + +DROP TABLE t1; + +# Binlog is required +--source include/have_log_bin.inc + +--echo # +--echo # Test 17. Check that table's triggers are dumped correctly. +--echo # +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; + +# dump tables and triggers +--exec $MYSQL_DUMP --compact test + +DROP TABLE t1; + +--echo # +--echo # Test 18. Check that table's triggers are dumped in right order +--echo # taking into account the PRECEDES/FOLLOWS clauses. +--echo # + +CREATE TABLE t1 (a INT); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr0_bi BEFORE INSERT ON t1 FOR EACH ROW PRECEDES tr1_bi SET @a:=0; +CREATE TRIGGER tr1_1_bi BEFORE INSERT ON t1 FOR EACH ROW FOLLOWS tr1_bi SET @a:=0; + +--echo # Expected order of triggers in the dump is: tr0_bi, tr1_bi, tr1_1_bi, tr2_i. +# dump tables and triggers +--exec $MYSQL_DUMP --compact test + +DROP TABLE t1; + +--echo # +--echo # Test 19. Check that table's triggers are dumped correctly in xml. +--echo # + +CREATE TABLE t1 (a INT); +SET TIMESTAMP=UNIX_TIMESTAMP('2013-01-31 09:00:00'); +CREATE TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1; +CREATE TRIGGER tr2_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=2; +CREATE TRIGGER tr1_bu BEFORE UPDATE ON t1 FOR EACH ROW SET @a:=3; +SET TIMESTAMP=DEFAULT; + +# dump tables and triggers +--exec $MYSQL_DUMP --compact --no-create-info --xml test + +DROP TABLE t1; + +--echo # +--echo # Test 20. Check that the statement CHECK TABLE FOR UPGRADE outputs +--echo # the warnings for triggers created by a server without support for wl3253. +--echo # + +CREATE TABLE t1 (a INT); + +let $MYSQLD_DATADIR=`SELECT @@datadir`; +--write_file $MYSQLD_DATADIR/test/t1.TRG +TYPE=TRIGGERS +triggers='CREATE DEFINER=`root`@`localhost` TRIGGER tr1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1' 'CREATE DEFINER=`root`@`localhost` TRIGGER tr1_ai AFTER INSERT ON t1 FOR EACH ROW SET @a:=2' +sql_modes=1073741824 1073741824 +definers='root@localhost' 'root@localhost' +client_cs_names='latin1' 'latin1' +connection_cl_names='latin1_swedish_ci' 'latin1_swedish_ci' +db_cl_names='latin1_swedish_ci' 'latin1_swedish_ci' +EOF + +--write_file $MYSQLD_DATADIR/test/tr1_bi.TRN +TYPE=TRIGGERNAME +trigger_table=t1 +EOF + +--write_file $MYSQLD_DATADIR/test/tr1_ai.TRN +TYPE=TRIGGERNAME +trigger_table=t1 +EOF + +FLUSH TABLE t1; + +CHECK TABLE t1 FOR UPGRADE; + +SHOW TRIGGERS; + +SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE trigger_schema = 'test'; + +SHOW CREATE TRIGGER tr1_bi; +SHOW CREATE TRIGGER tr1_ai; + +DROP TABLE t1; + +SET binlog_format=@binlog_format_saved; + +--echo # End of tests. +--echo # diff --git a/sql/item.cc b/sql/item.cc index 61635ea4ca8..ceb05911a63 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -8694,7 +8694,7 @@ void Item_insert_value::print(String *str, enum_query_type query_type) this stage we can't say exactly what Field object (corresponding to TABLE::record[0] or TABLE::record[1]) should be bound to this Item, we only find out index of the Field and then select concrete - Field object in fix_fields() (by that time Table_trigger_list::old_field/ + Field object in fix_fields() (by that time Table_triggers_list::old_field/ new_field should point to proper array of Fields). It also binds Item_trigger_field to Table_triggers_list object for table of trigger which uses this item. diff --git a/sql/lex.h b/sql/lex.h index 003e88d2d9d..d82dcf4e94a 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -240,6 +240,7 @@ static SYMBOL symbols[] = { { "FLOAT8", SYM(DOUBLE_SYM)}, { "FLUSH", SYM(FLUSH_SYM)}, { "FOLLOWING", SYM(FOLLOWING_SYM)}, + { "FOLLOWS", SYM(FOLLOWS_SYM)}, { "FOR", SYM(FOR_SYM)}, { "FORCE", SYM(FORCE_SYM)}, { "FOREIGN", SYM(FOREIGN)}, @@ -447,6 +448,7 @@ static SYMBOL symbols[] = { { "POINT", SYM(POINT_SYM)}, { "POLYGON", SYM(POLYGON)}, { "PORT", SYM(PORT_SYM)}, + { "PRECEDES", SYM(PRECEDES_SYM)}, { "PRECEDING", SYM(PRECEDING_SYM)}, { "PRECISION", SYM(PRECISION)}, { "PREPARE", SYM(PREPARE_SYM)}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a5cfd0527e8..0c742a5c484 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2147,7 +2147,10 @@ static void mysqld_exit(int exit_code) shutdown_performance_schema(); // we do it as late as possible #endif set_malloc_size_cb(NULL); - DBUG_ASSERT(global_status_var.global_memory_used == 0); + if (!opt_debugging) + { + DBUG_ASSERT(global_status_var.global_memory_used == 0); + } cleanup_tls(); DBUG_LEAVE; if (opt_endinfo && global_status_var.global_memory_used) diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 9d31667a6a8..273c0afb9ac 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -330,11 +330,7 @@ bool partition_info::can_prune_insert(THD* thd, partitioning column, since they may change the row to be in another partition. */ - if (table->triggers && - table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE) && - table->triggers->is_fields_updated_in_trigger(&full_part_field_set, - TRG_EVENT_INSERT, - TRG_ACTION_BEFORE)) + if (is_fields_updated_in_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE)) DBUG_RETURN(false); if (table->found_next_number_field) @@ -371,15 +367,8 @@ bool partition_info::can_prune_insert(THD* thd, partitioning column, since they may change the row to be in another partition. */ - if (table->triggers && - table->triggers->has_triggers(TRG_EVENT_UPDATE, - TRG_ACTION_BEFORE) && - table->triggers->is_fields_updated_in_trigger(&full_part_field_set, - TRG_EVENT_UPDATE, - TRG_ACTION_BEFORE)) - { + if (is_fields_updated_in_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE)) DBUG_RETURN(false); - } } /* diff --git a/sql/partition_info.h b/sql/partition_info.h index 66579be6384..99a71fea798 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -375,6 +375,20 @@ public: MY_BITMAP *used_partitions); bool has_same_partitioning(partition_info *new_part_info); private: + bool is_fields_updated_in_triggers(trg_event_type event_type, + trg_action_time_type action_time_type) + { + if (table->triggers) + { + Trigger *t; + for (t= table->triggers->get_trigger(event_type, action_time_type); + t; + t= t->next) + if (t->is_fields_updated_in_trigger(&full_part_field_set)) + return true; + } + return false; + } static int list_part_cmp(const void* a, const void* b); bool set_up_default_partitions(THD *thd, handler *file, HA_CREATE_INFO *info, uint start_no); diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index 3272d2a41f0..03d4b150434 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -419,6 +419,7 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd, { sys_var *svar; LEX_STRING var; + uint not_used; lasts= (char *) memchr(token, separator, rest); @@ -432,7 +433,7 @@ bool Session_sysvars_tracker::vars_list::parse_var_list(THD *thd, var.length= rest; /* Remove leading/trailing whitespace. */ - trim_whitespace(char_set, &var); + trim_whitespace(char_set, &var, ¬_used); if(!strcmp(var.str,(const char *)"*")) { @@ -500,6 +501,7 @@ bool Session_sysvars_tracker::check_var_list(THD *thd, for (;;) { LEX_STRING var; + uint not_used; lasts= (char *) memchr(token, separator, rest); @@ -513,7 +515,7 @@ bool Session_sysvars_tracker::check_var_list(THD *thd, var.length= rest; /* Remove leading/trailing whitespace. */ - trim_whitespace(char_set, &var); + trim_whitespace(char_set, &var, ¬_used); if(!strcmp(var.str,(const char *)"*") && !find_sys_var_ex(thd, var.str, var.length, throw_error, true)) diff --git a/sql/set_var.h b/sql/set_var.h index ba8027edc72..ee62f6db7ec 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -411,7 +411,7 @@ inline bool IS_SYSVAR_AUTOSIZE(void *ptr) bool fix_delay_key_write(sys_var *self, THD *thd, enum_var_type type); ulonglong expand_sql_mode(ulonglong sql_mode); -bool sql_mode_string_representation(THD *thd, ulonglong sql_mode, LEX_STRING *ls); +bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode, LEX_STRING *ls); int default_regex_flags_pcre(const THD *thd); extern sys_var *Sys_autocommit_ptr; diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 4d3861b2936..c555d9c732c 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -7230,3 +7230,5 @@ ER_EXPRESSION_REFERS_TO_UNINIT_FIELD 01000 ER_PARTITION_DEFAULT_ERROR eng "Only one DEFAULT partition allowed" ukr "ПрипуÑтимо мати тільки один DEFAULT розділ" +ER_REFERENCED_TRG_DOES_NOT_EXIST + eng "Referenced trigger '%s' for the given action time and event type does not exist" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 41006f07a0a..37479c14047 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -707,6 +707,7 @@ sp_head::set_stmt_end(THD *thd) { Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */ const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */ + uint not_used; /* Make the string of parameters. */ @@ -724,7 +725,7 @@ sp_head::set_stmt_end(THD *thd) m_body.length= end_ptr - m_body_begin; m_body.str= thd->strmake(m_body_begin, m_body.length); - trim_whitespace(thd->charset(), & m_body); + trim_whitespace(thd->charset(), &m_body, ¬_used); /* Make the string of UTF-body. */ @@ -732,7 +733,7 @@ sp_head::set_stmt_end(THD *thd) m_body_utf8.length= lip->get_body_utf8_length(); m_body_utf8.str= thd->strmake(lip->get_body_utf8_str(), m_body_utf8.length); - trim_whitespace(thd->charset(), & m_body_utf8); + trim_whitespace(thd->charset(), &m_body_utf8, ¬_used); /* Make the string of whole stored-program-definition query (in the @@ -741,7 +742,7 @@ sp_head::set_stmt_end(THD *thd) m_defstr.length= end_ptr - lip->get_cpp_buf(); m_defstr.str= thd->strmake(lip->get_cpp_buf(), m_defstr.length); - trim_whitespace(thd->charset(), & m_defstr); + trim_whitespace(thd->charset(), &m_defstr, ¬_used); } diff --git a/sql/sql_base.h b/sql/sql_base.h index f487887ddc9..bdfbe400e54 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -16,8 +16,8 @@ #ifndef SQL_BASE_INCLUDED #define SQL_BASE_INCLUDED -#include "sql_trigger.h" /* trg_event_type */ #include "sql_class.h" /* enum_mark_columns */ +#include "sql_trigger.h" /* trg_event_type */ #include "mysqld.h" /* key_map */ #include "table_cache.h" diff --git a/sql/sql_class.h b/sql/sql_class.h index 51642ecf798..9a41a0d4981 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -502,6 +502,8 @@ enum killed_type KILL_TYPE_QUERY }; +typedef ulonglong sql_mode_t; + #include "sql_lex.h" /* Must be here */ class Delayed_insert; @@ -513,8 +515,6 @@ class Time_zone; #define THD_CHECK_SENTRY(thd) DBUG_ASSERT(thd->dbug_sentry == THD_SENTRY_MAGIC) -typedef ulonglong sql_mode_t; - typedef struct system_variables { /* diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 4d161b32577..c53daf7d92d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2013,7 +2013,7 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) } -void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str) +void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str, uint *prefix_length) { /* TODO: @@ -2021,8 +2021,10 @@ void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str) that can be considered white-space. */ + *prefix_length= 0; while ((str->length > 0) && (my_isspace(cs, str->str[0]))) { + (*prefix_length)++; str->length --; str->str ++; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 6387b6d1c2d..5310e2a018f 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -29,7 +29,7 @@ #include "sql_cmd.h" #include "sql_alter.h" // Alter_info #include "sql_window.h" - +#include "sql_trigger.h" /* YACC and LEX Definitions */ @@ -1196,10 +1196,16 @@ struct st_sp_chistics enum enum_sp_data_access daccess; }; -struct st_trg_chistics + + +struct st_trg_chistics: public st_trg_execution_order { enum trg_action_time_type action_time; enum trg_event_type event; + + const char *ordering_clause_begin; + const char *ordering_clause_end; + }; extern sys_var *trg_new_row_fake_var; @@ -3278,7 +3284,8 @@ void end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex); int init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex); extern int MYSQLlex(union YYSTYPE *yylval, THD *thd); -extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str); +extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str, + uint *prefix_removed); extern bool is_lex_native_function(const LEX_STRING *name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index c4ca23cba78..de284cbe39d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -92,6 +92,20 @@ enum enum_i_s_events_fields #define USERNAME_WITH_HOST_CHAR_LENGTH (USERNAME_CHAR_LENGTH + HOSTNAME_LENGTH + 2) + +static const LEX_STRING trg_action_time_type_names[]= +{ + { C_STRING_WITH_LEN("BEFORE") }, + { C_STRING_WITH_LEN("AFTER") } +}; + +static const LEX_STRING trg_event_type_names[]= +{ + { C_STRING_WITH_LEN("INSERT") }, + { C_STRING_WITH_LEN("UPDATE") }, + { C_STRING_WITH_LEN("DELETE") } +}; + #ifndef NO_EMBEDDED_ACCESS_CHECKS static const char *grant_names[]={ "select","insert","update","delete","create","drop","reload","shutdown", @@ -6385,43 +6399,56 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, } -static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name, - LEX_STRING *table_name, LEX_STRING *trigger_name, - enum trg_event_type event, - enum trg_action_time_type timing, - LEX_STRING *trigger_stmt, - ulong sql_mode, - LEX_STRING *definer_buffer, - LEX_STRING *client_cs_name, - LEX_STRING *connection_cl_name, - LEX_STRING *db_cl_name) +static bool store_trigger(THD *thd, Trigger *trigger, + TABLE *table, LEX_STRING *db_name, + LEX_STRING *table_name) { CHARSET_INFO *cs= system_charset_info; LEX_STRING sql_mode_rep; + MYSQL_TIME timestamp; + char definer_holder[USER_HOST_BUFF_SIZE]; + LEX_STRING definer_buffer, trigger_stmt, trigger_body; + definer_buffer.str= definer_holder; + + trigger->get_trigger_info(&trigger_stmt, &trigger_body, &definer_buffer); restore_record(table, s->default_values); table->field[0]->store(STRING_WITH_LEN("def"), cs); table->field[1]->store(db_name->str, db_name->length, cs); - table->field[2]->store(trigger_name->str, trigger_name->length, cs); - table->field[3]->store(trg_event_type_names[event].str, - trg_event_type_names[event].length, cs); + table->field[2]->store(trigger->name.str, trigger->name.length, cs); + table->field[3]->store(trg_event_type_names[trigger->event].str, + trg_event_type_names[trigger->event].length, cs); table->field[4]->store(STRING_WITH_LEN("def"), cs); table->field[5]->store(db_name->str, db_name->length, cs); table->field[6]->store(table_name->str, table_name->length, cs); - table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs); + table->field[7]->store(trigger->action_order); + table->field[9]->store(trigger_body.str, trigger_body.length, cs); table->field[10]->store(STRING_WITH_LEN("ROW"), cs); - table->field[11]->store(trg_action_time_type_names[timing].str, - trg_action_time_type_names[timing].length, cs); + table->field[11]->store(trg_action_time_type_names[trigger->action_time].str, + trg_action_time_type_names[trigger->action_time].length, cs); table->field[14]->store(STRING_WITH_LEN("OLD"), cs); table->field[15]->store(STRING_WITH_LEN("NEW"), cs); - sql_mode_string_representation(thd, sql_mode, &sql_mode_rep); + if (trigger->create_time) + { + table->field[16]->set_notnull(); + thd->variables.time_zone->gmt_sec_to_TIME(×tamp, + trigger->create_time/100); + /* timestamp is with 6 digits */ + timestamp.second_part= (trigger->create_time % 100) * 10000; + ((Field_temporal_with_date*) table->field[16])->store_time_dec(×tamp, + 2); + } + + sql_mode_string_representation(thd, trigger->sql_mode, &sql_mode_rep); table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs); - table->field[18]->store(definer_buffer->str, definer_buffer->length, cs); - table->field[19]->store(client_cs_name->str, client_cs_name->length, cs); - table->field[20]->store(connection_cl_name->str, - connection_cl_name->length, cs); - table->field[21]->store(db_cl_name->str, db_cl_name->length, cs); + table->field[18]->store(definer_buffer.str, definer_buffer.length, cs); + table->field[19]->store(trigger->client_cs_name.str, + trigger->client_cs_name.length, cs); + table->field[20]->store(trigger->connection_cl_name.str, + trigger->connection_cl_name.length, cs); + table->field[21]->store(trigger->db_cl_name.str, + trigger->db_cl_name.length, cs); return schema_table_store_record(thd, table); } @@ -6458,35 +6485,16 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, { for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++) { - LEX_STRING trigger_name; - LEX_STRING trigger_stmt; - ulong sql_mode; - char definer_holder[USER_HOST_BUFF_SIZE]; - LEX_STRING definer_buffer; - LEX_STRING client_cs_name; - LEX_STRING connection_cl_name; - LEX_STRING db_cl_name; - - definer_buffer.str= definer_holder; - if (triggers->get_trigger_info(thd, (enum trg_event_type) event, - (enum trg_action_time_type)timing, - &trigger_name, &trigger_stmt, - &sql_mode, - &definer_buffer, - &client_cs_name, - &connection_cl_name, - &db_cl_name)) - continue; - - if (store_trigger(thd, table, db_name, table_name, &trigger_name, - (enum trg_event_type) event, - (enum trg_action_time_type) timing, &trigger_stmt, - sql_mode, - &definer_buffer, - &client_cs_name, - &connection_cl_name, - &db_cl_name)) - DBUG_RETURN(1); + Trigger *trigger; + for (trigger= triggers-> + get_trigger((enum trg_event_type) event, + (enum trg_action_time_type) timing) ; + trigger; + trigger= trigger->next) + { + if (store_trigger(thd, trigger, table, db_name, table_name)) + DBUG_RETURN(1); + } } } } @@ -7569,6 +7577,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) strlen(fields_info->field_name), fields_info->field_type))) DBUG_RETURN(0); + item->decimals= fields_info->field_length; break; case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: @@ -8776,7 +8785,8 @@ ST_FIELD_INFO triggers_fields_info[]= OPEN_FRM_ONLY}, {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY}, - {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FRM_ONLY}, + /* 2 here indicates 2 decimals */ + {"CREATED", 2, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FRM_ONLY}, {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FRM_ONLY}, {"DEFINER", DEFINER_CHAR_LENGTH, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FRM_ONLY}, {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, @@ -9307,35 +9317,35 @@ int finalize_schema_table(st_plugin_int *plugin) DBUG_RETURN(0); } +/* + This is used to create a timestamp field +*/ + +MYSQL_TIME zero_time={ 0,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_TIME }; /** Output trigger information (SHOW CREATE TRIGGER) to the client. @param thd Thread context. - @param triggers List of triggers for the table. - @param trigger_idx Index of the trigger to dump. + @param trigger Trigger to dump @return Operation status @retval TRUE Error. @retval FALSE Success. */ -static bool show_create_trigger_impl(THD *thd, - Table_triggers_list *triggers, - int trigger_idx) +static bool show_create_trigger_impl(THD *thd, Trigger *trigger) { int ret_code; Protocol *p= thd->protocol; List<Item> fields; - LEX_STRING trg_name; - ulonglong trg_sql_mode; - LEX_STRING trg_sql_mode_str; + LEX_STRING trg_sql_mode_str, trg_body; LEX_STRING trg_sql_original_stmt; - LEX_STRING trg_client_cs_name; - LEX_STRING trg_connection_cl_name; - LEX_STRING trg_db_cl_name; + LEX_STRING trg_definer; CHARSET_INFO *trg_client_cs; MEM_ROOT *mem_root= thd->mem_root; + char definer_holder[USER_HOST_BUFF_SIZE]; + trg_definer.str= definer_holder; /* TODO: Check privileges here. This functionality will be added by @@ -9349,20 +9359,12 @@ static bool show_create_trigger_impl(THD *thd, /* Prepare trigger "object". */ - triggers->get_trigger_info(thd, - trigger_idx, - &trg_name, - &trg_sql_mode, - &trg_sql_original_stmt, - &trg_client_cs_name, - &trg_connection_cl_name, - &trg_db_cl_name); - - sql_mode_string_representation(thd, trg_sql_mode, &trg_sql_mode_str); + trigger->get_trigger_info(&trg_sql_original_stmt, &trg_body, &trg_definer); + sql_mode_string_representation(thd, trigger->sql_mode, &trg_sql_mode_str); /* Resolve trigger client character set. */ - if (resolve_charset(trg_client_cs_name.str, NULL, &trg_client_cs)) + if (resolve_charset(trigger->client_cs_name.str, NULL, &trg_client_cs)) return TRUE; /* Send header. */ @@ -9404,6 +9406,11 @@ static bool show_create_trigger_impl(THD *thd, MY_CS_NAME_SIZE), mem_root); + Item_datetime_literal *tmp= (new (mem_root) + Item_datetime_literal(thd, &zero_time, 2)); + tmp->set_name(thd, STRING_WITH_LEN("Created"), system_charset_info); + fields.push_back(tmp, mem_root); + if (p->send_result_set_metadata(&fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) @@ -9413,8 +9420,8 @@ static bool show_create_trigger_impl(THD *thd, p->prepare_for_resend(); - p->store(trg_name.str, - trg_name.length, + p->store(trigger->name.str, + trigger->name.length, system_charset_info); p->store(trg_sql_mode_str.str, @@ -9425,18 +9432,30 @@ static bool show_create_trigger_impl(THD *thd, trg_sql_original_stmt.length, trg_client_cs); - p->store(trg_client_cs_name.str, - trg_client_cs_name.length, + p->store(trigger->client_cs_name.str, + trigger->client_cs_name.length, system_charset_info); - p->store(trg_connection_cl_name.str, - trg_connection_cl_name.length, + p->store(trigger->connection_cl_name.str, + trigger->connection_cl_name.length, system_charset_info); - p->store(trg_db_cl_name.str, - trg_db_cl_name.length, + p->store(trigger->db_cl_name.str, + trigger->db_cl_name.length, system_charset_info); + if (trigger->create_time) + { + MYSQL_TIME timestamp; + thd->variables.time_zone->gmt_sec_to_TIME(×tamp, + trigger->create_time/100); + timestamp.second_part= (trigger->create_time % 100) * 10000; + p->store(×tamp, 2); + } + else + p->store_null(); + + ret_code= p->write(); if (!ret_code) @@ -9528,7 +9547,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) TABLE_LIST *lst= get_trigger_table(thd, trg_name); uint num_tables; /* NOTE: unused, only to pass to open_tables(). */ Table_triggers_list *triggers; - int trigger_idx; + Trigger *trigger; bool error= TRUE; if (!lst) @@ -9569,9 +9588,9 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) goto exit; } - trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name); + trigger= triggers->find_trigger(&trg_name->m_name, 0); - if (trigger_idx < 0) + if (!trigger) { my_error(ER_TRG_CORRUPTED_FILE, MYF(0), (const char *) trg_name->m_db.str, @@ -9580,7 +9599,7 @@ bool show_create_trigger(THD *thd, const sp_name *trg_name) goto exit; } - error= show_create_trigger_impl(thd, triggers, trigger_idx); + error= show_create_trigger_impl(thd, trigger); /* NOTE: if show_create_trigger_impl() failed, that means we could not diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 5213c21e8a2..d3954d0ee73 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -34,30 +34,17 @@ #include "sp_cache.h" // sp_invalidate_cache #include <mysys_err.h> -/*************************************************************************/ - -template <class T> -inline T *alloc_type(MEM_ROOT *m) -{ - return (T *) alloc_root(m, sizeof (T)); -} - -/* - NOTE: Since alloc_type() is declared as inline, alloc_root() calls should - be inlined by the compiler. So, implementation of alloc_root() is not - needed. However, let's put the implementation in object file just in case - of stupid MS or other old compilers. -*/ - -template LEX_STRING *alloc_type<LEX_STRING>(MEM_ROOT *m); -template ulonglong *alloc_type<ulonglong>(MEM_ROOT *m); - -inline LEX_STRING *alloc_lex_string(MEM_ROOT *m) +LEX_STRING *make_lex_string(LEX_STRING *lex_str, const char* str, uint length, + MEM_ROOT *mem_root) { - return alloc_type<LEX_STRING>(m); + if (!(lex_str->str= strmake_root(mem_root, str, length))) + return 0; + lex_str->length= length; + return lex_str; } /*************************************************************************/ + /** Trigger_creation_ctx -- creation context of triggers. */ @@ -73,7 +60,12 @@ public: const LEX_STRING *connection_cl_name, const LEX_STRING *db_cl_name); -public: + Trigger_creation_ctx(CHARSET_INFO *client_cs, + CHARSET_INFO *connection_cl, + CHARSET_INFO *db_cl) + :Stored_program_creation_ctx(client_cs, connection_cl, db_cl) + { } + virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root) { return new (mem_root) Trigger_creation_ctx(m_client_cs, @@ -87,16 +79,9 @@ protected: return new Trigger_creation_ctx(thd); } -private: Trigger_creation_ctx(THD *thd) :Stored_program_creation_ctx(thd) { } - - Trigger_creation_ctx(CHARSET_INFO *client_cs, - CHARSET_INFO *connection_cl, - CHARSET_INFO *db_cl) - :Stored_program_creation_ctx(client_cs, connection_cl, db_cl) - { } }; /************************************************************************** @@ -220,6 +205,11 @@ static File_option triggers_file_parameters[]= my_offsetof(class Table_triggers_list, db_cl_names), FILE_OPTIONS_STRLIST }, + { + { C_STRING_WITH_LEN("created") }, + my_offsetof(class Table_triggers_list, create_times), + FILE_OPTIONS_ULLLIST + }, { { 0, 0 }, 0, FILE_OPTIONS_STRING } }; @@ -234,9 +224,12 @@ File_option sql_modes_parameters= This must be kept up to date whenever a new option is added to the list above, as it specifies the number of required parameters of the trigger in .trg file. + This defines the maximum number of parameters that is read. If there are + more paramaters in the file they are ignored. Less number of parameters + is regarded as ok. */ -static const int TRG_NUM_REQUIRED_PARAMETERS= 6; +static const int TRG_NUM_REQUIRED_PARAMETERS= 7; /* Structure representing contents of .TRN file which are used to support @@ -315,7 +308,7 @@ private: Also, if possible, grabs name of the trigger being parsed so it can be used to correctly drop problematic trigger. */ -class Deprecated_trigger_syntax_handler : public Internal_error_handler +class Deprecated_trigger_syntax_handler : public Internal_error_handler { private: @@ -355,6 +348,38 @@ public: }; +Trigger::~Trigger() +{ + delete body; +} + + +/** + Call a Table_triggers_list function for all triggers + + @return 0 ok + @return # Something went wrong. Pointer to the trigger that mailfuncted + returned +*/ + +Trigger* Table_triggers_list::for_all_triggers(Triggers_processor func, + void *arg) +{ + for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++) + { + for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++) + { + for (Trigger *trigger= get_trigger(i,j) ; + trigger ; + trigger= trigger->next) + if ((trigger->*func)(arg)) + return trigger; + } + } + return 0; +} + + /** Create or drop trigger for table. @@ -378,6 +403,7 @@ public: @retval TRUE error */ + bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) { /* @@ -393,7 +419,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) bool lock_upgrade_done= FALSE; MDL_ticket *mdl_ticket= NULL; Query_tables_list backup; - DBUG_ENTER("mysql_create_or_drop_trigger"); /* Charset of the buffer for statement must be system one. */ @@ -517,7 +542,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) tables->required_type= FRMTYPE_TABLE; /* Also prevent DROP TRIGGER from opening temporary table which might - shadow base table on which trigger to be dropped is defined. + shadow the subject table on which trigger to be dropped is defined. */ tables->open_type= OT_BASE_ONLY; @@ -586,9 +611,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) end: if (!result) - { result= write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length()); - } /* If we are under LOCK TABLES we should restore original state of @@ -609,8 +632,8 @@ end: } /** - Build stmt_query to write it in the bin-log - and get the trigger definer. + Build stmt_query to write it in the bin-log, the statement to write in + the trigger file and the trigger definer. @param thd current thread context (including trigger definition in LEX) @@ -618,7 +641,8 @@ end: trigger is created. @param[out] stmt_query after successful return, this string contains well-formed statement for creation this trigger. - + @param[out] trigger_def query to be stored in trigger file. As stmt_query, + but without "OR REPLACE" and no FOLLOWS/PRECEDES. @param[out] trg_definer The triggger definer. @param[out] trg_definer_holder Used as a buffer for definer. @@ -630,12 +654,16 @@ end: simultaneously NULL-strings (non-SUID/old trigger) or valid strings (SUID/new trigger). */ + static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, - String *stmt_query, + String *stmt_query, String *trigger_def, LEX_STRING *trg_definer, char trg_definer_holder[]) { + LEX_STRING stmt_definition; LEX *lex= thd->lex; + uint prefix_trimmed, suffix_trimmed; + size_t original_length; /* Create a query with the full trigger definition. @@ -643,6 +671,8 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, */ stmt_query->append(STRING_WITH_LEN("CREATE ")); + trigger_def->copy(*stmt_query); + if (lex->create_info.or_replace()) stmt_query->append(STRING_WITH_LEN("OR REPLACE ")); @@ -651,18 +681,42 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, /* SUID trigger */ lex->definer->set_lex_string(trg_definer, trg_definer_holder); append_definer(thd, stmt_query, &lex->definer->user, &lex->definer->host); + append_definer(thd, trigger_def, &lex->definer->user, &lex->definer->host); } else { *trg_definer= empty_lex_str; } - LEX_STRING stmt_definition; - stmt_definition.str= (char*) thd->lex->stmt_definition_begin; - stmt_definition.length= thd->lex->stmt_definition_end - - thd->lex->stmt_definition_begin; - trim_whitespace(thd->charset(), &stmt_definition); + + /* Create statement for binary logging */ + stmt_definition.str= (char*) lex->stmt_definition_begin; + stmt_definition.length= (lex->stmt_definition_end - + lex->stmt_definition_begin); + original_length= stmt_definition.length; + trim_whitespace(thd->charset(), &stmt_definition, &prefix_trimmed); + suffix_trimmed= original_length - stmt_definition.length - prefix_trimmed; + stmt_query->append(stmt_definition.str, stmt_definition.length); + + /* Create statement for storing trigger (without trigger order) */ + if (lex->trg_chistics.ordering_clause == TRG_ORDER_NONE) + trigger_def->append(stmt_definition.str, stmt_definition.length); + else + { + /* Copy data before FOLLOWS/PRECEDES trigger_name */ + trigger_def->append(stmt_definition.str, + (lex->trg_chistics.ordering_clause_begin - + lex->stmt_definition_begin) - prefix_trimmed); + /* Copy data after FOLLOWS/PRECEDES trigger_name */ + trigger_def->append(stmt_definition.str + + (lex->trg_chistics.ordering_clause_end - + lex->stmt_definition_begin) + - prefix_trimmed, + (lex->stmt_definition_end - + lex->trg_chistics.ordering_clause_end) - + suffix_trimmed); + } } @@ -689,6 +743,7 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, @retval True error */ + bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, String *stmt_query) { @@ -696,51 +751,27 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, TABLE *table= tables->table; char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN]; LEX_STRING file, trigname_file; - LEX_STRING *trg_def; - ulonglong *trg_sql_mode; char trg_definer_holder[USER_HOST_BUFF_SIZE]; - LEX_STRING *trg_definer; Item_trigger_field *trg_field; struct st_trigname trigname; - LEX_STRING *trg_client_cs_name; - LEX_STRING *trg_connection_cl_name; - LEX_STRING *trg_db_cl_name; - sp_head *trg_body= bodies[lex->trg_chistics.event] - [lex->trg_chistics.action_time]; + String trigger_definition; + Trigger *trigger= 0; + bool trigger_dropped= 0; + DBUG_ENTER("create_trigger"); if (check_for_broken_triggers()) - return true; + DBUG_RETURN(true); /* Trigger must be in the same schema as target table. */ if (my_strcasecmp(table_alias_charset, table->s->db.str, lex->spname->m_db.str)) { my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0)); - return true; - } - - /* - We don't allow creation of several triggers of the same type yet. - If a trigger with the same type already exists: - a. Throw a ER_NOT_SUPPORTED_YET error, - if the old and the new trigger names are different; - b. Or continue, if the old and the new trigger names are the same: - - either to recreate the trigger on "CREATE OR REPLACE" - - or send a "already exists" warning on "CREATE IF NOT EXISTS" - - or send an "alredy exists" error on normal CREATE. - */ - if (trg_body != 0 && - my_strcasecmp(table_alias_charset, - trg_body->m_name.str, lex->spname->m_name.str)) - { - my_error(ER_NOT_SUPPORTED_YET, MYF(0), - "multiple triggers with the same action time" - " and event for one table"); - return true; + DBUG_RETURN(true); } if (sp_process_definer(thd)) - return true; + DBUG_RETURN(true); /* Let us check if all references to fields in old/new versions of row in @@ -769,7 +800,20 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, if (!trg_field->fixed && trg_field->fix_fields(thd, (Item **)0)) - return true; + DBUG_RETURN(true); + } + + /* Ensure anchor trigger exists */ + if (lex->trg_chistics.ordering_clause != TRG_ORDER_NONE) + { + if (!(trigger= find_trigger(&lex->trg_chistics.anchor_trigger_name, 0)) || + trigger->event != lex->trg_chistics.event || + trigger->action_time != lex->trg_chistics.action_time) + { + my_error(ER_REFERENCED_TRG_DOES_NOT_EXIST, MYF(0), + lex->trg_chistics.anchor_trigger_name.str); + DBUG_RETURN(true); + } } /* @@ -793,10 +837,13 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, if (lex->create_info.or_replace()) { String drop_trg_query; - drop_trg_query.append("DROP TRIGGER "); - drop_trg_query.append(lex->spname->m_name.str); - if (drop_trigger(thd, tables, &drop_trg_query)) - return 1; + /* + The following can fail if the trigger is for another table or + there exists a .TRN file but there was no trigger for it in + the .TRG file + */ + if (unlikely(drop_trigger(thd, tables, &drop_trg_query))) + DBUG_RETURN(true); } else if (lex->create_info.if_not_exists()) { @@ -805,54 +852,48 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, ER_THD(thd, ER_TRG_ALREADY_EXISTS), trigname_buff); LEX_STRING trg_definer_tmp; - build_trig_stmt_query(thd, tables, stmt_query, + String trigger_def; + + /* + Log query with IF NOT EXISTS to binary log. This is in line with + CREATE TABLE IF NOT EXISTS. + */ + build_trig_stmt_query(thd, tables, stmt_query, &trigger_def, &trg_definer_tmp, trg_definer_holder); - return false; + DBUG_RETURN(false); } else { my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); - return true; + DBUG_RETURN(true); } } trigname.trigger_table.str= tables->table_name; trigname.trigger_table.length= tables->table_name_length; - if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, - (uchar*)&trigname, trigname_file_parameters)) - return true; - /* - Soon we will invalidate table object and thus Table_triggers_list object - so don't care about place to which trg_def->ptr points and other - invariants (e.g. we don't bother to update names_list) - - QQ: Hmm... probably we should not care about setting up active thread - mem_root too. + We are not using lex->sphead here as an argument to Trigger() as we are + going to access lex->sphead later in build_trig_stmt_query() */ - if (!(trg_def= alloc_lex_string(&table->mem_root)) || - definitions_list.push_back(trg_def, &table->mem_root) || - - !(trg_sql_mode= alloc_type<ulonglong>(&table->mem_root)) || - definition_modes_list.push_back(trg_sql_mode, &table->mem_root) || + if (!(trigger= new (&table->mem_root) Trigger(this, 0))) + goto err_without_cleanup; - !(trg_definer= alloc_lex_string(&table->mem_root)) || - definers_list.push_back(trg_definer, &table->mem_root) || + /* Create trigger_name.TRN file to ensure trigger name is unique */ + if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, + (uchar*)&trigname, trigname_file_parameters)) + goto err_without_cleanup; - !(trg_client_cs_name= alloc_lex_string(&table->mem_root)) || - client_cs_names.push_back(trg_client_cs_name, &table->mem_root) || + /* Populate the trigger object */ - !(trg_connection_cl_name= alloc_lex_string(&table->mem_root)) || - connection_cl_names.push_back(trg_connection_cl_name, &table->mem_root) || + trigger->sql_mode= thd->variables.sql_mode; + /* Time with 2 decimals, like in MySQL 5.7 */ + trigger->create_time= ((ulonglong) thd->query_start())*100 + thd->query_start_sec_part()/10000; + build_trig_stmt_query(thd, tables, stmt_query, &trigger_definition, + &trigger->definer, trg_definer_holder); - !(trg_db_cl_name= alloc_lex_string(&table->mem_root)) || - db_cl_names.push_back(trg_db_cl_name, &table->mem_root)) - { - goto err_with_cleanup; - } - - *trg_sql_mode= thd->variables.sql_mode; + trigger->definition.str= trigger_definition.c_ptr(); + trigger->definition.length= trigger_definition.length(); /* Fill character set information: @@ -860,34 +901,105 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, - connection collation contains pair {character set, collation}; - database collation contains pair {character set, collation}; */ - - lex_string_set(trg_client_cs_name, thd->charset()->csname); - - lex_string_set(trg_connection_cl_name, + lex_string_set(&trigger->client_cs_name, thd->charset()->csname); + lex_string_set(&trigger->connection_cl_name, thd->variables.collation_connection->name); - - lex_string_set(trg_db_cl_name, + lex_string_set(&trigger->db_cl_name, get_default_db_collation(thd, tables->db)->name); - build_trig_stmt_query(thd, tables, stmt_query, - trg_definer, trg_definer_holder); + /* Add trigger in it's correct place */ + add_trigger(lex->trg_chistics.event, + lex->trg_chistics.action_time, + lex->trg_chistics.ordering_clause, + &lex->trg_chistics.anchor_trigger_name, + trigger); - trg_def->str= stmt_query->c_ptr_safe(); - trg_def->length= stmt_query->length(); - - /* Create trigger definition file. */ + /* Create trigger definition file .TRG */ + if (unlikely(create_lists_needed_for_files(thd->mem_root))) + goto err_with_cleanup; if (!sql_create_definition_file(NULL, &file, &triggers_file_type, (uchar*)this, triggers_file_parameters)) - return false; + DBUG_RETURN(false); err_with_cleanup: + /* Delete .TRN file */ mysql_file_delete(key_file_trn, trigname_buff, MYF(MY_WME)); - return true; + +err_without_cleanup: + delete trigger; // Safety, not critical + + if (trigger_dropped) + { + String drop_trg_query; + drop_trg_query.append("DROP TRIGGER /* generated by failed CREATE TRIGGER */ "); + drop_trg_query.append(lex->spname->m_name.str); + /* + We dropped an existing trigger and was not able to recreate it because + of an internal error. Ensure it's also dropped on the slave. + */ + write_bin_log(thd, FALSE, drop_trg_query.ptr(), drop_trg_query.length()); + } + DBUG_RETURN(true); } /** + Empty all list used to load and create .TRG file +*/ + +void Table_triggers_list::empty_lists() +{ + definitions_list.empty(); + definition_modes_list.empty(); + definers_list.empty(); + client_cs_names.empty(); + connection_cl_names.empty(); + db_cl_names.empty(); + create_times.empty(); +} + + +/** + Create list of all trigger parameters for sql_create_definition_file() +*/ + +struct create_lists_param +{ + MEM_ROOT *root; +}; + + +bool Table_triggers_list::create_lists_needed_for_files(MEM_ROOT *root) +{ + create_lists_param param; + + empty_lists(); + param.root= root; + + return for_all_triggers(&Trigger::add_to_file_list, ¶m); +} + + +bool Trigger::add_to_file_list(void* param_arg) +{ + create_lists_param *param= (create_lists_param*) param_arg; + MEM_ROOT *mem_root= param->root; + + if (base->definitions_list.push_back(&definition, mem_root) || + base->definition_modes_list.push_back(&sql_mode, mem_root) || + base->definers_list.push_back(&definer, mem_root) || + base->client_cs_names.push_back(&client_cs_name, mem_root) || + base->connection_cl_names.push_back(&connection_cl_name, mem_root) || + base->db_cl_names.push_back(&db_cl_name, mem_root) || + base->create_times.push_back(&create_time, mem_root)) + return 1; + return 0; +} + + + +/** Deletes the .TRG file for a table. @param path char buffer of size FN_REFLEN to be used @@ -944,17 +1056,57 @@ static bool rm_trigname_file(char *path, const char *db, TRUE Error */ -static bool save_trigger_file(Table_triggers_list *triggers, const char *db, - const char *table_name) +bool Table_triggers_list::save_trigger_file(THD *thd, const char *db, + const char *table_name) { char file_buff[FN_REFLEN]; LEX_STRING file; + if (create_lists_needed_for_files(thd->mem_root)) + return true; + file.length= build_table_filename(file_buff, FN_REFLEN - 1, db, table_name, TRG_EXT, 0); file.str= file_buff; return sql_create_definition_file(NULL, &file, &triggers_file_type, - (uchar*)triggers, triggers_file_parameters); + (uchar*) this, triggers_file_parameters); +} + + +/** + Find a trigger with a given name + + @param name Name of trigger + @param remove_from_list If set, remove trigger if found +*/ + +Trigger *Table_triggers_list::find_trigger(const LEX_STRING *name, + bool remove_from_list) +{ + for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++) + { + for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++) + { + Trigger **parent, *trigger; + + for (parent= &triggers[i][j]; + (trigger= *parent); + parent= &trigger->next) + { + if (my_strcasecmp(table_alias_charset, + trigger->name.str, name->str) == 0) + { + if (remove_from_list) + { + *parent= trigger->next; + count--; + } + return trigger; + } + } + } + } + return 0; } @@ -979,85 +1131,70 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, @retval True error */ + bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables, String *stmt_query) { - const char *sp_name= thd->lex->spname->m_name.str; // alias - - LEX_STRING *name; + const LEX_STRING *sp_name= &thd->lex->spname->m_name; // alias char path[FN_REFLEN]; + Trigger *trigger; - List_iterator_fast<LEX_STRING> it_name(names_list); + stmt_query->set(thd->query(), thd->query_length(), stmt_query->charset()); - List_iterator<ulonglong> it_mod(definition_modes_list); - List_iterator<LEX_STRING> it_def(definitions_list); - List_iterator<LEX_STRING> it_definer(definers_list); - List_iterator<LEX_STRING> it_client_cs_name(client_cs_names); - List_iterator<LEX_STRING> it_connection_cl_name(connection_cl_names); - List_iterator<LEX_STRING> it_db_cl_name(db_cl_names); - - stmt_query->append(thd->query(), thd->query_length()); - - while ((name= it_name++)) + /* Find and delete trigger from list */ + if (!(trigger= find_trigger(sp_name, true))) { - it_def++; - it_mod++; - it_definer++; - it_client_cs_name++; - it_connection_cl_name++; - it_db_cl_name++; - - if (my_strcasecmp(table_alias_charset, sp_name, name->str) == 0) - { - /* - Again we don't care much about other things required for - clean trigger removing since table will be reopened anyway. - */ - it_def.remove(); - it_mod.remove(); - it_definer.remove(); - it_client_cs_name.remove(); - it_connection_cl_name.remove(); - it_db_cl_name.remove(); - - if (definitions_list.is_empty()) - { - /* - TODO: Probably instead of removing .TRG file we should move - to archive directory but this should be done as part of - parse_file.cc functionality (because we will need it - elsewhere). - */ - if (rm_trigger_file(path, tables->db, tables->table_name)) - return 1; - } - else - { - if (save_trigger_file(this, tables->db, tables->table_name)) - return 1; - } + my_message(ER_TRG_DOES_NOT_EXIST, ER_THD(thd, ER_TRG_DOES_NOT_EXIST), + MYF(0)); + return 1; + } - if (rm_trigname_file(path, tables->db, sp_name)) - return 1; - return 0; - } + if (!count) // If no more triggers + { + /* + TODO: Probably instead of removing .TRG file we should move + to archive directory but this should be done as part of + parse_file.cc functionality (because we will need it + elsewhere). + */ + if (rm_trigger_file(path, tables->db, tables->table_name)) + return 1; } + else + { + if (save_trigger_file(thd, tables->db, tables->table_name)) + return 1; + } + + if (rm_trigname_file(path, tables->db, sp_name->str)) + return 1; - my_message(ER_TRG_DOES_NOT_EXIST, ER_THD(thd, ER_TRG_DOES_NOT_EXIST), - MYF(0)); - return 1; + delete trigger; + return 0; } Table_triggers_list::~Table_triggers_list() { - for (int i= 0; i < (int)TRG_EVENT_MAX; i++) - for (int j= 0; j < (int)TRG_ACTION_MAX; j++) - delete bodies[i][j]; + DBUG_ENTER("Table_triggers_list::~Table_triggers_list"); + for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++) + { + for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++) + { + Trigger *next, *trigger; + for (trigger= get_trigger(i,j) ; trigger ; trigger= next) + { + next= trigger->next; + delete trigger; + } + } + } if (record1_field) for (Field **fld_ptr= record1_field; *fld_ptr; fld_ptr++) delete *fld_ptr; + + DBUG_VOID_RETURN; } @@ -1073,13 +1210,14 @@ Table_triggers_list::~Table_triggers_list() @retval True error */ + bool Table_triggers_list::prepare_record_accessors(TABLE *table) { Field **fld, **trg_fld; - if ((bodies[TRG_EVENT_INSERT][TRG_ACTION_BEFORE] || - bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]) - && (table->s->stored_fields != table->s->null_fields)) + if ((has_triggers(TRG_EVENT_INSERT,TRG_ACTION_BEFORE) || + has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE)) && + (table->s->stored_fields != table->s->null_fields)) { int null_bytes= (table->s->stored_fields - table->s->null_fields + 7)/8; @@ -1119,10 +1257,10 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) else record0_field= table->field; - if (bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE] || - bodies[TRG_EVENT_UPDATE][TRG_ACTION_AFTER] || - bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || - bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]) + if (has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE) || + has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_AFTER) || + has_triggers(TRG_EVENT_DELETE,TRG_ACTION_BEFORE) || + has_triggers(TRG_EVENT_DELETE,TRG_ACTION_AFTER)) { if (!(record1_field= (Field **)alloc_root(&table->mem_root, (table->s->fields + 1) * @@ -1173,7 +1311,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, LEX_STRING path; File_parser *parser; LEX_STRING save_db; - DBUG_ENTER("Table_triggers_list::check_n_load"); path.length= build_table_filename(path_buff, FN_REFLEN - 1, @@ -1184,194 +1321,54 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, if (access(path_buff, F_OK)) DBUG_RETURN(0); - /* - File exists so we got to load triggers. - FIXME: A lot of things to do here e.g. how about other funcs and being - more paranoical ? - */ + /* File exists so we got to load triggers */ if ((parser= sql_parse_prepare(&path, &table->mem_root, 1))) { if (is_equal(&triggers_file_type, parser->type())) { - Table_triggers_list *triggers= - new (&table->mem_root) Table_triggers_list(table); Handle_old_incorrect_sql_modes_hook sql_modes_hook(path.str); + LEX_STRING *trg_create_str; + ulonglong *trg_sql_mode, *trg_create_time; + Trigger *trigger; + Table_triggers_list *trigger_list= + new (&table->mem_root) Table_triggers_list(table); + if (unlikely(!trigger_list)) + goto error; - if (!triggers) - DBUG_RETURN(1); - - /* - We don't have the following attributes in old versions of .TRG file, so - we should initialize the list for safety: - - sql_modes; - - definers; - - character sets (client, connection, database); - */ - triggers->definition_modes_list.empty(); - triggers->definers_list.empty(); - triggers->client_cs_names.empty(); - triggers->connection_cl_names.empty(); - triggers->db_cl_names.empty(); - - if (parser->parse((uchar*)triggers, &table->mem_root, + if (parser->parse((uchar*)trigger_list, &table->mem_root, triggers_file_parameters, TRG_NUM_REQUIRED_PARAMETERS, &sql_modes_hook)) - DBUG_RETURN(1); - - List_iterator_fast<LEX_STRING> it(triggers->definitions_list); - LEX_STRING *trg_create_str; - ulonglong *trg_sql_mode; - - if (triggers->definition_modes_list.is_empty() && - !triggers->definitions_list.is_empty()) - { - /* - It is old file format => we should fill list of sql_modes. - - We use one mode (current) for all triggers, because we have not - information about mode in old format. - */ - if (!(trg_sql_mode= alloc_type<ulonglong>(&table->mem_root))) - { - DBUG_RETURN(1); // EOM - } - *trg_sql_mode= global_system_variables.sql_mode; - while (it++) - { - if (triggers->definition_modes_list.push_back(trg_sql_mode, - &table->mem_root)) - { - DBUG_RETURN(1); // EOM - } - } - it.rewind(); - } - - if (triggers->definers_list.is_empty() && - !triggers->definitions_list.is_empty()) - { - /* - It is old file format => we should fill list of definers. + goto error; - If there is no definer information, we should not switch context to - definer when checking privileges. I.e. privileges for such triggers - are checked for "invoker" rather than for "definer". - */ - - LEX_STRING *trg_definer; - - if (!(trg_definer= alloc_lex_string(&table->mem_root))) - DBUG_RETURN(1); // EOM + List_iterator_fast<LEX_STRING> it(trigger_list->definitions_list); - trg_definer->str= (char*) ""; - trg_definer->length= 0; - - while (it++) - { - if (triggers->definers_list.push_back(trg_definer, - &table->mem_root)) - { - DBUG_RETURN(1); // EOM - } - } - - it.rewind(); - } - - if (!triggers->definitions_list.is_empty() && - (triggers->client_cs_names.is_empty() || - triggers->connection_cl_names.is_empty() || - triggers->db_cl_names.is_empty())) + if (!trigger_list->definitions_list.is_empty() && + (trigger_list->client_cs_names.is_empty() || + trigger_list->connection_cl_names.is_empty() || + trigger_list->db_cl_names.is_empty())) { - /* - It is old file format => we should fill lists of character sets. - */ - - LEX_STRING *trg_client_cs_name; - LEX_STRING *trg_connection_cl_name; - LEX_STRING *trg_db_cl_name; - - if (!triggers->client_cs_names.is_empty() || - !triggers->connection_cl_names.is_empty() || - !triggers->db_cl_names.is_empty()) - { - my_error(ER_TRG_CORRUPTED_FILE, MYF(0), - (const char *) db, - (const char *) table_name); - - DBUG_RETURN(1); // EOM - } - + /* We will later use the current character sets */ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_TRG_NO_CREATION_CTX, ER_THD(thd, ER_TRG_NO_CREATION_CTX), (const char*) db, (const char*) table_name); - - if (!(trg_client_cs_name= alloc_lex_string(&table->mem_root)) || - !(trg_connection_cl_name= alloc_lex_string(&table->mem_root)) || - !(trg_db_cl_name= alloc_lex_string(&table->mem_root))) - { - DBUG_RETURN(1); // EOM - } - - /* - Backward compatibility: assume that the query is in the current - character set. - */ - - lex_string_set(trg_client_cs_name, - thd->variables.character_set_client->csname); - - lex_string_set(trg_connection_cl_name, - thd->variables.collation_connection->name); - - lex_string_set(trg_db_cl_name, - thd->variables.collation_database->name); - - while (it++) - { - if (triggers->client_cs_names.push_back(trg_client_cs_name, - &table->mem_root) || - - triggers->connection_cl_names.push_back(trg_connection_cl_name, - &table->mem_root) || - - triggers->db_cl_names.push_back(trg_db_cl_name, - &table->mem_root)) - { - DBUG_RETURN(1); // EOM - } - } - - it.rewind(); } - DBUG_ASSERT(triggers->definition_modes_list.elements == - triggers->definitions_list.elements); - DBUG_ASSERT(triggers->definers_list.elements == - triggers->definitions_list.elements); - DBUG_ASSERT(triggers->client_cs_names.elements == - triggers->definitions_list.elements); - DBUG_ASSERT(triggers->connection_cl_names.elements == - triggers->definitions_list.elements); - DBUG_ASSERT(triggers->db_cl_names.elements == - triggers->definitions_list.elements); - - table->triggers= triggers; + table->triggers= trigger_list; status_var_increment(thd->status_var.feature_trigger); - List_iterator_fast<ulonglong> itm(triggers->definition_modes_list); - List_iterator_fast<LEX_STRING> it_definer(triggers->definers_list); - List_iterator_fast<LEX_STRING> it_client_cs_name(triggers->client_cs_names); - List_iterator_fast<LEX_STRING> it_connection_cl_name(triggers->connection_cl_names); - List_iterator_fast<LEX_STRING> it_db_cl_name(triggers->db_cl_names); + List_iterator_fast<ulonglong> itm(trigger_list->definition_modes_list); + List_iterator_fast<LEX_STRING> it_definer(trigger_list->definers_list); + List_iterator_fast<LEX_STRING> it_client_cs_name(trigger_list->client_cs_names); + List_iterator_fast<LEX_STRING> it_connection_cl_name(trigger_list->connection_cl_names); + List_iterator_fast<LEX_STRING> it_db_cl_name(trigger_list->db_cl_names); + List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times); LEX *old_lex= thd->lex, lex; sp_rcontext *save_spcont= thd->spcont; - ulonglong save_sql_mode= thd->variables.sql_mode; - LEX_STRING *on_table_name; + sql_mode_t save_sql_mode= thd->variables.sql_mode; thd->lex= &lex; @@ -1381,30 +1378,55 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, while ((trg_create_str= it++)) { sp_head *sp; - trg_sql_mode= itm++; - LEX_STRING *trg_definer= it_definer++; + sql_mode_t sql_mode; + LEX_STRING *trg_definer; + Trigger_creation_ctx *creation_ctx; - thd->variables.sql_mode= (ulong)*trg_sql_mode; + /* + It is old file format then sql_mode may not be filled in. + We use one mode (current) for all triggers, because we have not + information about mode in old format. + */ + sql_mode= ((trg_sql_mode= itm++) ? *trg_sql_mode : + global_system_variables.sql_mode); + + trg_create_time= it_create_times++; // May be NULL if old file + trg_definer= it_definer++; // May be NULL if old file + + thd->variables.sql_mode= sql_mode; Parser_state parser_state; if (parser_state.init(thd, trg_create_str->str, trg_create_str->length)) goto err_with_lex_cleanup; - Trigger_creation_ctx *creation_ctx= - Trigger_creation_ctx::create(thd, - db, - table_name, - it_client_cs_name++, - it_connection_cl_name++, - it_db_cl_name++); + if (!trigger_list->client_cs_names.is_empty()) + creation_ctx= Trigger_creation_ctx::create(thd, + db, + table_name, + it_client_cs_name++, + it_connection_cl_name++, + it_db_cl_name++); + else + { + /* Old file with not stored character sets. Use current */ + creation_ctx= new + Trigger_creation_ctx(thd->variables.character_set_client, + thd->variables.collation_connection, + thd->variables.collation_database); + } lex_start(thd); thd->spcont= NULL; + /* The following is for catching parse errors */ + lex.trg_chistics.event= TRG_EVENT_MAX; + lex.trg_chistics.action_time= TRG_ACTION_MAX; Deprecated_trigger_syntax_handler error_handler; thd->push_internal_handler(&error_handler); + bool parse_error= parse_sql(thd, & parser_state, creation_ctx); thd->pop_internal_handler(); + DBUG_ASSERT(!parse_error || lex.sphead == 0); /* Not strictly necessary to invoke this method here, since we know @@ -1416,68 +1438,73 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, */ lex.set_trg_event_type_for_tables(); + if (lex.sphead) + lex.sphead->set_info(0, 0, &lex.sp_chistics, sql_mode); + + if (unlikely(!(trigger= (new (&table->mem_root) + Trigger(trigger_list, lex.sphead))))) + goto err_with_lex_cleanup; + lex.sphead= NULL; /* Prevent double cleanup. */ + + sp= trigger->body; + + trigger->sql_mode= sql_mode; + trigger->definition= *trg_create_str; + trigger->create_time= trg_create_time ? *trg_create_time : 0; + trigger->name= sp ? sp->m_name : empty_lex_str; + trigger->on_table_name.str= (char*) lex.raw_trg_on_table_name_begin; + trigger->on_table_name.length= (lex.raw_trg_on_table_name_end - + lex.raw_trg_on_table_name_begin); + + /* Copy pointers to character sets to make trigger easier to use */ + lex_string_set(&trigger->client_cs_name, + creation_ctx->get_client_cs()->csname); + lex_string_set(&trigger->connection_cl_name, + creation_ctx->get_connection_cl()->name); + lex_string_set(&trigger->db_cl_name, + creation_ctx->get_db_cl()->name); + + /* event can only be TRG_EVENT_MAX in case of fatal parse errors */ + if (lex.trg_chistics.event != TRG_EVENT_MAX) + trigger_list->add_trigger(lex.trg_chistics.event, + lex.trg_chistics.action_time, + TRG_ORDER_NONE, + &lex.trg_chistics.anchor_trigger_name, + trigger); + if (parse_error) { - if (!triggers->m_has_unparseable_trigger) - triggers->set_parse_error_message(error_handler.get_error_message()); + LEX_STRING *name; + + /* + In case of errors, disable all triggers for the table, but keep + the wrong trigger around to allow the user to fix it + */ + if (!trigger_list->m_has_unparseable_trigger) + trigger_list->set_parse_error_message(error_handler.get_error_message()); /* Currently sphead is always set to NULL in case of a parse error */ DBUG_ASSERT(lex.sphead == 0); - if (error_handler.get_trigger_name()) - { - LEX_STRING *trigger_name; - const LEX_STRING *orig_trigger_name= error_handler.get_trigger_name(); - - if (!(trigger_name= alloc_lex_string(&table->mem_root)) || - !(trigger_name->str= strmake_root(&table->mem_root, - orig_trigger_name->str, - orig_trigger_name->length))) - goto err_with_lex_cleanup; - - trigger_name->length= orig_trigger_name->length; + lex_end(&lex); - if (triggers->names_list.push_back(trigger_name, - &table->mem_root)) - goto err_with_lex_cleanup; - } - else + if ((name= error_handler.get_trigger_name())) { - /* - The Table_triggers_list is not constructed as a list of - trigger objects as one would expect, but rather of lists of - properties of equal length. Thus, even if we don't get the - trigger name, we still fill all in all the lists with - placeholders as we might otherwise create a skew in the - lists. Obviously, this has to be refactored. - */ - LEX_STRING *empty= alloc_lex_string(&table->mem_root); - if (!empty) - goto err_with_lex_cleanup; - - empty->str= const_cast<char*>(""); - empty->length= 0; - if (triggers->names_list.push_back(empty, &table->mem_root)) + if (!(make_lex_string(&trigger->name, name->str, + name->length, &table->mem_root))) goto err_with_lex_cleanup; } - lex_end(&lex); + trigger->definer= ((!trg_definer || !trg_definer->length) ? + empty_lex_str : *trg_definer); continue; } - lex.sphead->set_info(0, 0, &lex.sp_chistics, (ulong) *trg_sql_mode); - - int event= lex.trg_chistics.event; - int action_time= lex.trg_chistics.action_time; - - sp= triggers->bodies[event][action_time]= lex.sphead; - lex.sphead= NULL; /* Prevent double cleanup. */ - - sp->set_info(0, 0, &lex.sp_chistics, (ulong) *trg_sql_mode); + sp->set_info(0, 0, &lex.sp_chistics, sql_mode); sp->set_creation_ctx(creation_ctx); - if (!trg_definer->length) + if (!trg_definer || !trg_definer->length) { /* This trigger was created/imported from the previous version of - MySQL, which does not support triggers definers. We should emit + MySQL, which does not support trigger_list definers. We should emit warning here. */ @@ -1493,34 +1520,26 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, */ sp->set_definer((char*) "", 0); + trigger->definer= empty_lex_str; /* - Triggers without definer information are executed under the + trigger_list without definer information are executed under the authorization of the invoker. */ sp->m_chistics->suid= SP_IS_NOT_SUID; } else + { sp->set_definer(trg_definer->str, trg_definer->length); + trigger->definer= *trg_definer; + } - if (triggers->names_list.push_back(&sp->m_name, &table->mem_root)) - goto err_with_lex_cleanup; - - if (!(on_table_name= alloc_lex_string(&table->mem_root))) - goto err_with_lex_cleanup; - - on_table_name->str= (char*) lex.raw_trg_on_table_name_begin; - on_table_name->length= lex.raw_trg_on_table_name_end - - lex.raw_trg_on_table_name_begin; - - if (triggers->on_table_names_list.push_back(on_table_name, &table->mem_root)) - goto err_with_lex_cleanup; #ifndef DBUG_OFF /* Let us check that we correctly update trigger definitions when we - rename tables with triggers. - + rename tables with trigger_list. + In special cases like "RENAME TABLE `#mysql50#somename` TO `somename`" or "ALTER DATABASE `#mysql50#somename` UPGRADE DATA DIRECTORY NAME" we might be given table or database name with "#mysql50#" prefix (and @@ -1545,11 +1564,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, /* Gather all Item_trigger_field objects representing access to fields in old/new versions of row in trigger into lists containing all such - objects for the triggers with same action and timing. + objects for the trigger_list with same action and timing. */ - triggers->trigger_fields[lex.trg_chistics.event] - [lex.trg_chistics.action_time]= - lex.trg_table_fields.first; + trigger->trigger_fields= lex.trg_table_fields.first; /* Also let us bind these objects to Field objects in table being opened. @@ -1564,8 +1581,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, trg_field= trg_field->next_trg_field) { trg_field->setup_field(thd, table, - &triggers->subject_table_grants[lex.trg_chistics.event] - [lex.trg_chistics.action_time]); + &trigger->subject_table_grants); } lex_end(&lex); @@ -1575,9 +1591,11 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; - if (!names_only && triggers->prepare_record_accessors(table)) - DBUG_RETURN(1); + if (!names_only && trigger_list->prepare_record_accessors(table)) + goto error; + /* Ensure no one is accidently using the temporary load lists */ + trigger_list->empty_lists(); DBUG_RETURN(0); err_with_lex_cleanup: @@ -1586,31 +1604,75 @@ err_with_lex_cleanup: thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; thd->reset_db(save_db.str, save_db.length); - DBUG_RETURN(1); + /* Fall trough to error */ } + } +error: + if (!thd->is_error()) + { /* We don't care about this error message much because .TRG files will be merged into .FRM anyway. */ my_error(ER_WRONG_OBJECT, MYF(0), table_name, TRG_EXT + 1, "TRIGGER"); - DBUG_RETURN(1); } - DBUG_RETURN(1); } /** + Add trigger in the correct position according to ordering clause + Also update action order + + If anchor_trigger doesn't exist, add it last. +*/ + +void Table_triggers_list::add_trigger(trg_event_type event, + trg_action_time_type action_time, + trigger_order_type ordering_clause, + LEX_STRING *anchor_trigger_name, + Trigger *trigger) +{ + Trigger **parent= &triggers[event][action_time]; + uint position= 0; + + for ( ; *parent ; parent= &(*parent)->next, position++) + { + if (ordering_clause != TRG_ORDER_NONE && + !my_strcasecmp(table_alias_charset, anchor_trigger_name->str, + (*parent)->name.str)) + { + if (ordering_clause == TRG_ORDER_FOLLOWS) + { + parent= &(*parent)->next; // Add after this one + position++; + } + break; + } + } + + /* Add trigger where parent points to */ + trigger->next= *parent; + *parent= trigger; + + /* Update action_orders and position */ + trigger->event= event; + trigger->action_time= action_time; + trigger->action_order= ++position; + while ((trigger= trigger->next)) + trigger->action_order= ++position; + + count++; +} + + +/** Obtains and returns trigger metadata. @param thd current thread context - @param event trigger event type - @param time_type trigger action time - @param trigger_name returns name of trigger @param trigger_stmt returns statement of trigger - @param sql_mode returns sql_mode of trigger @param definer returns definer/creator of trigger. The caller is responsible to allocate enough space for storing definer information. @@ -1621,106 +1683,34 @@ err_with_lex_cleanup: True error */ -bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event, - trg_action_time_type time_type, - LEX_STRING *trigger_name, - LEX_STRING *trigger_stmt, - ulong *sql_mode, - LEX_STRING *definer, - LEX_STRING *client_cs_name, - LEX_STRING *connection_cl_name, - LEX_STRING *db_cl_name) +void Trigger::get_trigger_info(LEX_STRING *trigger_stmt, + LEX_STRING *trigger_body, LEX_STRING *definer) { - sp_head *body; DBUG_ENTER("get_trigger_info"); - if ((body= bodies[event][time_type])) - { - Stored_program_creation_ctx *creation_ctx= - bodies[event][time_type]->get_creation_ctx(); - - *trigger_name= body->m_name; - *trigger_stmt= body->m_body_utf8; - *sql_mode= body->m_sql_mode; - - if (body->m_chistics->suid == SP_IS_NOT_SUID) - { - definer->str[0]= 0; - definer->length= 0; - } - else - { - definer->length= strxmov(definer->str, body->m_definer_user.str, "@", - body->m_definer_host.str, NullS) - definer->str; - } - - lex_string_set(client_cs_name, - creation_ctx->get_client_cs()->csname); - - lex_string_set(connection_cl_name, - creation_ctx->get_connection_cl()->name); - - lex_string_set(db_cl_name, - creation_ctx->get_db_cl()->name); - DBUG_RETURN(0); + *trigger_stmt= definition; + if (!body) + { + /* Parse error */ + *trigger_body= definition; + *definer= empty_lex_str; + DBUG_VOID_RETURN; } - DBUG_RETURN(1); -} - + *trigger_body= body->m_body_utf8; -void Table_triggers_list::get_trigger_info(THD *thd, - int trigger_idx, - LEX_STRING *trigger_name, - ulonglong *sql_mode, - LEX_STRING *sql_original_stmt, - LEX_STRING *client_cs_name, - LEX_STRING *connection_cl_name, - LEX_STRING *db_cl_name) -{ - List_iterator_fast<LEX_STRING> it_trigger_name(names_list); - List_iterator_fast<ulonglong> it_sql_mode(definition_modes_list); - List_iterator_fast<LEX_STRING> it_sql_orig_stmt(definitions_list); - List_iterator_fast<LEX_STRING> it_client_cs_name(client_cs_names); - List_iterator_fast<LEX_STRING> it_connection_cl_name(connection_cl_names); - List_iterator_fast<LEX_STRING> it_db_cl_name(db_cl_names); - - for (int i = 0; i < trigger_idx; ++i) + if (body->m_chistics->suid == SP_IS_NOT_SUID) { - it_trigger_name.next_fast(); - it_sql_mode.next_fast(); - it_sql_orig_stmt.next_fast(); - - it_client_cs_name.next_fast(); - it_connection_cl_name.next_fast(); - it_db_cl_name.next_fast(); + *definer= empty_lex_str; } - - *trigger_name= *(it_trigger_name++); - *sql_mode= *(it_sql_mode++); - *sql_original_stmt= *(it_sql_orig_stmt++); - - *client_cs_name= *(it_client_cs_name++); - *connection_cl_name= *(it_connection_cl_name++); - *db_cl_name= *(it_db_cl_name++); -} - - -int Table_triggers_list::find_trigger_by_name(const LEX_STRING *trg_name) -{ - List_iterator_fast<LEX_STRING> it(names_list); - - for (int i = 0; ; ++i) + else { - LEX_STRING *cur_name= it++; - - if (!cur_name) - return -1; - - if (strcmp(cur_name->str, trg_name->str) == 0) - return i; + definer->length= strxmov(definer->str, body->m_definer_user.str, "@", + body->m_definer_host.str, NullS) - definer->str; } + DBUG_VOID_RETURN; } + /** Find trigger's table from trigger identifier and add it to the statement table list. @@ -1811,38 +1801,37 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name) } if (table.triggers) { - LEX_STRING *trigger; - List_iterator_fast<LEX_STRING> it_name(table.triggers->names_list); - - while ((trigger= it_name++)) + for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++) { - /* - Trigger, which body we failed to parse during call - Table_triggers_list::check_n_load(), might be missing name. - Such triggers have zero-length name and are skipped here. - */ - if (trigger->length == 0) - continue; - if (rm_trigname_file(path, db, trigger->str)) + for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++) { - /* - Instead of immediately bailing out with error if we were unable - to remove .TRN file we will try to drop other files. - */ - result= 1; - continue; + Trigger *trigger; + for (trigger= table.triggers->get_trigger(i,j) ; + trigger ; + trigger= trigger->next) + { + /* + Trigger, which body we failed to parse during call + Table_triggers_list::check_n_load(), might be missing name. + Such triggers have zero-length name and are skipped here. + */ + if (trigger->name.length && + rm_trigname_file(path, db, trigger->name.str)) + { + /* + Instead of immediately bailing out with error if we were unable + to remove .TRN file we will try to drop other files. + */ + result= 1; + } + } } } - if (rm_trigger_file(path, db, name)) - { result= 1; - goto end; - } + delete table.triggers; } end: - if (table.triggers) - delete table.triggers; free_root(&table.mem_root, MYF(0)); DBUG_RETURN(result); } @@ -1864,6 +1853,16 @@ end: TRUE Failure */ +struct change_table_name_param +{ + THD *thd; + const char *old_db_name; + const char *new_db_name; + LEX_STRING *new_table_name; + Trigger *stopper; +}; + + bool Table_triggers_list::change_table_name_in_triggers(THD *thd, const char *old_db_name, @@ -1871,57 +1870,23 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd, LEX_STRING *old_table_name, LEX_STRING *new_table_name) { - char path_buff[FN_REFLEN]; - LEX_STRING *def, *on_table_name, new_def; + struct change_table_name_param param; ulonglong save_sql_mode= thd->variables.sql_mode; - List_iterator_fast<LEX_STRING> it_def(definitions_list); - List_iterator_fast<LEX_STRING> it_on_table_name(on_table_names_list); - List_iterator_fast<ulonglong> it_mode(definition_modes_list); - size_t on_q_table_name_len, before_on_len; - String buff; + char path_buff[FN_REFLEN]; - DBUG_ASSERT(definitions_list.elements == on_table_names_list.elements && - definitions_list.elements == definition_modes_list.elements); + param.thd= thd; + param.new_table_name= new_table_name; - while ((def= it_def++)) - { - on_table_name= it_on_table_name++; - thd->variables.sql_mode= (ulong) *(it_mode++); - - /* Construct CREATE TRIGGER statement with new table name. */ - buff.length(0); - - /* WARNING: 'on_table_name' is supposed to point inside 'def' */ - DBUG_ASSERT(on_table_name->str > def->str); - DBUG_ASSERT(on_table_name->str < (def->str + def->length)); - before_on_len= on_table_name->str - def->str; - - buff.append(def->str, before_on_len); - buff.append(STRING_WITH_LEN("ON ")); - append_identifier(thd, &buff, new_table_name->str, new_table_name->length); - buff.append(STRING_WITH_LEN(" ")); - on_q_table_name_len= buff.length() - before_on_len; - buff.append(on_table_name->str + on_table_name->length, - def->length - (before_on_len + on_table_name->length)); - /* - It is OK to allocate some memory on table's MEM_ROOT since this - table instance will be thrown out at the end of rename anyway. - */ - new_def.str= (char*) memdup_root(&trigger_table->mem_root, buff.ptr(), - buff.length()); - new_def.length= buff.length(); - on_table_name->str= new_def.str + before_on_len; - on_table_name->length= on_q_table_name_len; - *def= new_def; - } + for_all_triggers(&Trigger::change_table_name, ¶m); thd->variables.sql_mode= save_sql_mode; if (thd->is_fatal_error) return TRUE; /* OOM */ - if (save_trigger_file(this, new_db_name, new_table_name->str)) + if (save_trigger_file(thd, new_db_name, new_table_name->str)) return TRUE; + if (rm_trigger_file(path_buff, old_db_name, old_table_name->str)) { (void) rm_trigger_file(path_buff, new_db_name, new_table_name->str); @@ -1931,6 +1896,47 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd, } +bool Trigger::change_table_name(void* param_arg) +{ + change_table_name_param *param= (change_table_name_param*) param_arg; + THD *thd= param->thd; + LEX_STRING *new_table_name= param->new_table_name; + + LEX_STRING *def= &definition, new_def; + size_t on_q_table_name_len, before_on_len; + String buff; + + thd->variables.sql_mode= sql_mode; + + /* Construct CREATE TRIGGER statement with new table name. */ + buff.length(0); + + /* WARNING: 'on_table_name' is supposed to point inside 'def' */ + DBUG_ASSERT(on_table_name.str > def->str); + DBUG_ASSERT(on_table_name.str < (def->str + def->length)); + before_on_len= on_table_name.str - def->str; + + buff.append(def->str, before_on_len); + buff.append(STRING_WITH_LEN("ON ")); + append_identifier(thd, &buff, new_table_name->str, new_table_name->length); + buff.append(STRING_WITH_LEN(" ")); + on_q_table_name_len= buff.length() - before_on_len; + buff.append(on_table_name.str + on_table_name.length, + def->length - (before_on_len + on_table_name.length)); + /* + It is OK to allocate some memory on table's MEM_ROOT since this + table instance will be thrown out at the end of rename anyway. + */ + new_def.str= (char*) memdup_root(&base->trigger_table->mem_root, buff.ptr(), + buff.length()); + new_def.length= buff.length(); + on_table_name.str= new_def.str + before_on_len; + on_table_name.length= on_q_table_name_len; + definition= new_def; + return 0; +} + + /** Iterate though Table_triggers_list::names_list list and update .TRN files after renaming triggers' subject table. @@ -1948,42 +1954,56 @@ Table_triggers_list::change_table_name_in_triggers(THD *thd, for which update failed. */ -LEX_STRING* +Trigger * Table_triggers_list::change_table_name_in_trignames(const char *old_db_name, const char *new_db_name, LEX_STRING *new_table_name, - LEX_STRING *stopper) + Trigger *trigger) +{ + struct change_table_name_param param; + param.old_db_name= old_db_name; + param.new_db_name= new_db_name; + param.new_table_name= new_table_name; + param.stopper= trigger; + + return for_all_triggers(&Trigger::change_on_table_name, ¶m); +} + + +bool Trigger::change_on_table_name(void* param_arg) { + change_table_name_param *param= (change_table_name_param*) param_arg; + char trigname_buff[FN_REFLEN]; struct st_trigname trigname; LEX_STRING trigname_file; - LEX_STRING *trigger; - List_iterator_fast<LEX_STRING> it_name(names_list); - while ((trigger= it_name++) != stopper) + if (param->stopper == this) + return 0; // Stop processing + + trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, + param->new_db_name, name.str, + TRN_EXT, 0); + trigname_file.str= trigname_buff; + + trigname.trigger_table= *param->new_table_name; + + if (base->create_lists_needed_for_files(current_thd->mem_root)) + return true; + + if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, + (uchar*)&trigname, trigname_file_parameters)) + return this; + + /* Remove stale .TRN file in case of database upgrade */ + if (param->old_db_name) { - trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, - new_db_name, trigger->str, - TRN_EXT, 0); - trigname_file.str= trigname_buff; - - trigname.trigger_table= *new_table_name; - - if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, - (uchar*)&trigname, trigname_file_parameters)) - return trigger; - - /* Remove stale .TRN file in case of database upgrade */ - if (old_db_name) + if (rm_trigname_file(trigname_buff, param->old_db_name, name.str)) { - if (rm_trigname_file(trigname_buff, old_db_name, trigger->str)) - { - (void) rm_trigname_file(trigname_buff, new_db_name, trigger->str); - return trigger; - } + (void) rm_trigname_file(trigname_buff, param->new_db_name, name.str); + return 1; } } - return 0; } @@ -2017,8 +2037,8 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, { TABLE table; bool result= 0; - bool upgrading50to51= FALSE; - LEX_STRING *err_trigname; + bool upgrading50to51= FALSE; + Trigger *err_trigger; DBUG_ENTER("change_table_name"); bzero(&table, sizeof(table)); @@ -2053,7 +2073,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, moving table with them between two schemas raises too many questions. (E.g. what should happen if in new schema we already have trigger with same name ?). - + In case of "ALTER DATABASE `#mysql50#db1` UPGRADE DATA DIRECTORY NAME" we will be given table name with "#mysql50#" prefix To remove this prefix we use check_n_cut_mysql50_prefix(). @@ -2061,7 +2081,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, if (my_strcasecmp(table_alias_charset, db, new_db)) { char dbname[SAFE_NAME_LEN + 1]; - if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) && + if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) && !my_strcasecmp(table_alias_charset, dbname, new_db)) { upgrading50to51= TRUE; @@ -2080,8 +2100,8 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, result= 1; goto end; } - if ((err_trigname= table.triggers->change_table_name_in_trignames( - upgrading50to51 ? db : NULL, + if ((err_trigger= table.triggers-> + change_table_name_in_trignames( upgrading50to51 ? db : NULL, new_db, &new_table_name, 0))) { /* @@ -2092,7 +2112,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, */ (void) table.triggers->change_table_name_in_trignames( upgrading50to51 ? new_db : NULL, db, - &old_table_name, err_trigname); + &old_table_name, err_trigger); (void) table.triggers->change_table_name_in_triggers( thd, db, new_db, &new_table_name, &old_table_name); @@ -2100,7 +2120,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, goto end; } } - + end: delete table.triggers; free_root(&table.mem_root, MYF(0)); @@ -2131,17 +2151,15 @@ bool Table_triggers_list::process_triggers(THD *thd, { bool err_status; Sub_statement_state statement_state; - sp_head *sp_trigger= bodies[event][time_type]; + Trigger *trigger; SELECT_LEX *save_current_select; if (check_for_broken_triggers()) - return true; + return TRUE; - if (sp_trigger == NULL) + if (!(trigger= get_trigger(event, time_type))) return FALSE; - status_var_increment(thd->status_var.executed_triggers); - if (old_row_is_record1) { old_field= record1_field; @@ -2168,12 +2186,16 @@ bool Table_triggers_list::process_triggers(THD *thd, in case of failure during trigger execution. */ save_current_select= thd->lex->current_select; - thd->lex->current_select= NULL; - err_status= - sp_trigger->execute_trigger(thd, - &trigger_table->s->db, - &trigger_table->s->table_name, - &subject_table_grants[event][time_type]); + + do { + thd->lex->current_select= NULL; + err_status= + trigger->body->execute_trigger(thd, + &trigger_table->s->db, + &trigger_table->s->table_name, + &trigger->subject_table_grants); + status_var_increment(thd->status_var.executed_triggers); + } while (!err_status && (trigger= trigger->next)); thd->lex->current_select= save_current_select; thd->restore_sub_statement_state(&statement_state); @@ -2211,11 +2233,15 @@ add_tables_and_routines_for_triggers(THD *thd, { for (int j= 0; j < (int)TRG_ACTION_MAX; j++) { - /* We can have only one trigger per action type currently */ - sp_head *trigger= table_list->table->triggers->bodies[i][j]; + Trigger *triggers= table_list->table->triggers->get_trigger(i,j); - if (trigger) + for ( ; triggers ; triggers= triggers->next) { + sp_head *trigger= triggers->body; + + if (!triggers->body) // Parse error + continue; + MDL_key key(MDL_key::TRIGGER, trigger->m_db.str, trigger->m_name.str); if (sp_add_used_routine(prelocking_ctx, thd->stmt_arena, @@ -2245,13 +2271,11 @@ add_tables_and_routines_for_triggers(THD *thd, @param action_time Type of trigger action time we are going to inspect */ -bool Table_triggers_list::is_fields_updated_in_trigger(MY_BITMAP *used_fields, - trg_event_type event_type, - trg_action_time_type action_time) +bool Trigger::is_fields_updated_in_trigger(MY_BITMAP *used_fields) { Item_trigger_field *trg_field; - sp_head *sp= bodies[event_type][action_time]; - DBUG_ASSERT(used_fields->n_bits == trigger_table->s->fields); + sp_head *sp= body; + DBUG_ASSERT(used_fields->n_bits == base->trigger_table->s->fields); for (trg_field= sp->m_trg_table_fields.first; trg_field; trg_field= trg_field->next_trg_field) @@ -2288,15 +2312,21 @@ void Table_triggers_list::mark_fields_used(trg_event_type event) for (action_time= 0; action_time < (int)TRG_ACTION_MAX; action_time++) { - for (trg_field= trigger_fields[event][action_time]; trg_field; - trg_field= trg_field->next_trg_field) + for (Trigger *trigger= get_trigger(event,action_time); + trigger ; + trigger= trigger->next) { - /* We cannot mark fields which does not present in table. */ - if (trg_field->field_idx != (uint)-1) + for (trg_field= trigger->trigger_fields; + trg_field; + trg_field= trg_field->next_trg_field) { - bitmap_set_bit(trigger_table->read_set, trg_field->field_idx); - if (trg_field->get_settable_routine_parameter()) - bitmap_set_bit(trigger_table->write_set, trg_field->field_idx); + /* We cannot mark fields which does not present in table. */ + if (trg_field->field_idx != (uint)-1) + { + bitmap_set_bit(trigger_table->read_set, trg_field->field_idx); + if (trg_field->get_settable_routine_parameter()) + bitmap_set_bit(trigger_table->write_set, trg_field->field_idx); + } } } } diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index fa858a0582b..f1161cdd967 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -51,22 +51,92 @@ enum trg_action_time_type TRG_ACTION_BEFORE= 0, TRG_ACTION_AFTER= 1, TRG_ACTION_MAX }; +enum trigger_order_type +{ + TRG_ORDER_NONE= 0, + TRG_ORDER_FOLLOWS= 1, + TRG_ORDER_PRECEDES= 2 +}; + + +struct st_trg_execution_order +{ + /** + FOLLOWS or PRECEDES as specified in the CREATE TRIGGER statement. + */ + enum trigger_order_type ordering_clause; + + /** + Trigger name referenced in the FOLLOWS/PRECEDES clause of the + CREATE TRIGGER statement. + */ + LEX_STRING anchor_trigger_name; +}; -/** - This class holds all information about triggers of table. - TODO: Will it be merged into TABLE in the future ? +class Table_triggers_list; + +/** + The trigger object */ -class Table_triggers_list: public Sql_alloc +class Trigger :public Sql_alloc { - /** Triggers as SPs grouped by event, action_time */ - sp_head *bodies[TRG_EVENT_MAX][TRG_ACTION_MAX]; +public: + Trigger(Table_triggers_list *base_arg, sp_head *code): + base(base_arg), body(code), next(0), trigger_fields(0), action_order(0) + { + bzero((char *)&subject_table_grants, sizeof(subject_table_grants)); + } + ~Trigger(); + Table_triggers_list *base; + sp_head *body; + Trigger *next; /* Next trigger of same type */ + /** Heads of the lists linking items for all fields used in triggers grouped by event and action_time. */ - Item_trigger_field *trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX]; + Item_trigger_field *trigger_fields; + LEX_STRING name; + LEX_STRING on_table_name; /* Raw table name */ + LEX_STRING definition; + LEX_STRING definer; + + /* Character sets used */ + LEX_STRING client_cs_name; + LEX_STRING connection_cl_name; + LEX_STRING db_cl_name; + + GRANT_INFO subject_table_grants; + ulonglong sql_mode; + /* Store create time. Can't be mysql_time_t as this holds also sub seconds */ + ulonglong create_time; + trg_event_type event; + trg_action_time_type action_time; + uint action_order; + + bool is_fields_updated_in_trigger(MY_BITMAP *used_fields); + void get_trigger_info(LEX_STRING *stmt, LEX_STRING *body, + LEX_STRING *definer); + /* Functions executed over each active trigger */ + bool change_on_table_name(void* param_arg); + bool change_table_name(void* param_arg); + bool add_to_file_list(void* param_arg); +}; + +typedef bool (Trigger::*Triggers_processor)(void *arg); + +/** + This class holds all information about triggers of table. +*/ + +class Table_triggers_list: public Sql_alloc +{ + friend class Trigger; + + /* Points to first trigger for a certain type */ + Trigger *triggers[TRG_EVENT_MAX][TRG_ACTION_MAX]; /** Copy of TABLE::Field array which all fields made nullable (using extra_null_bitmap, if needed). Used for NEW values in @@ -90,22 +160,6 @@ class Table_triggers_list: public Sql_alloc /* TABLE instance for which this triggers list object was created */ TABLE *trigger_table; - /** - Names of triggers. - Should correspond to order of triggers on definitions_list, - used in CREATE/DROP TRIGGER for looking up trigger by name. - */ - List<LEX_STRING> names_list; - /** - List of "ON table_name" parts in trigger definitions, used for - updating trigger definitions during RENAME TABLE. - */ - List<LEX_STRING> on_table_names_list; - - /** - Grant information for each trigger (pair: subject table, trigger definer). - */ - GRANT_INFO subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX]; /** This flag indicates that one of the triggers was not parsed successfully, @@ -127,6 +181,7 @@ class Table_triggers_list: public Sql_alloc the trigger file. */ char m_parse_error_message[MYSQL_ERRMSG_SIZE]; + uint count; /* Number of triggers */ public: /** @@ -138,6 +193,8 @@ public: List of sql modes for triggers */ List<ulonglong> definition_modes_list; + /** Create times for triggers */ + List<ulonglong> create_times; List<LEX_STRING> definers_list; @@ -152,11 +209,9 @@ public: Table_triggers_list(TABLE *table_arg) :record0_field(0), extra_null_bitmap(0), record1_field(0), trigger_table(table_arg), - m_has_unparseable_trigger(false) + m_has_unparseable_trigger(false), count(0) { - bzero((char *)bodies, sizeof(bodies)); - bzero((char *)trigger_fields, sizeof(trigger_fields)); - bzero((char *)&subject_table_grants, sizeof(subject_table_grants)); + bzero((char *) triggers, sizeof(triggers)); } ~Table_triggers_list(); @@ -165,26 +220,9 @@ public: bool process_triggers(THD *thd, trg_event_type event, trg_action_time_type time_type, bool old_row_is_record1); - - bool get_trigger_info(THD *thd, trg_event_type event, - trg_action_time_type time_type, - LEX_STRING *trigger_name, LEX_STRING *trigger_stmt, - ulong *sql_mode, - LEX_STRING *definer, - LEX_STRING *client_cs_name, - LEX_STRING *connection_cl_name, - LEX_STRING *db_cl_name); - - void get_trigger_info(THD *thd, - int trigger_idx, - LEX_STRING *trigger_name, - ulonglong *sql_mode, - LEX_STRING *sql_original_stmt, - LEX_STRING *client_cs_name, - LEX_STRING *connection_cl_name, - LEX_STRING *db_cl_name); - - int find_trigger_by_name(const LEX_STRING *trigger_name); + void empty_lists(); + bool create_lists_needed_for_files(MEM_ROOT *root); + bool save_trigger_file(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); @@ -194,15 +232,32 @@ public: const char *old_table, const char *new_db, const char *new_table); + void add_trigger(trg_event_type event_type, + trg_action_time_type action_time, + trigger_order_type ordering_clause, + LEX_STRING *anchor_trigger_name, + Trigger *trigger); + Trigger *get_trigger(trg_event_type event_type, + trg_action_time_type action_time) + { + return triggers[event_type][action_time]; + } + /* Simpler version of the above, to avoid casts in the code */ + Trigger *get_trigger(uint event_type, uint action_time) + { + return get_trigger((trg_event_type) event_type, + (trg_action_time_type) action_time); + } + bool has_triggers(trg_event_type event_type, trg_action_time_type action_time) { - return (bodies[event_type][action_time] != NULL); + return get_trigger(event_type,action_time) != 0; } bool has_delete_triggers() { - return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || - bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]); + return (has_triggers(TRG_EVENT_DELETE,TRG_ACTION_BEFORE) || + has_triggers(TRG_EVENT_DELETE,TRG_ACTION_AFTER)); } void mark_fields_used(trg_event_type event); @@ -215,10 +270,6 @@ public: Query_tables_list *prelocking_ctx, TABLE_LIST *table_list); - bool is_fields_updated_in_trigger(MY_BITMAP *used_fields, - trg_event_type event_type, - trg_action_time_type action_time); - Field **nullable_fields() { return record0_field; } void reset_extra_null_bitmap() { @@ -227,12 +278,16 @@ public: bzero(extra_null_bitmap, null_bytes); } + Trigger *find_trigger(const LEX_STRING *name, bool remove_from_list); + + Trigger* for_all_triggers(Triggers_processor func, void *arg); + private: bool prepare_record_accessors(TABLE *table); - LEX_STRING* change_table_name_in_trignames(const char *old_db_name, - const char *new_db_name, - LEX_STRING *new_table_name, - LEX_STRING *stopper); + Trigger *change_table_name_in_trignames(const char *old_db_name, + const char *new_db_name, + LEX_STRING *new_table_name, + Trigger *trigger); bool change_table_name_in_triggers(THD *thd, const char *old_db_name, const char *new_db_name, @@ -257,9 +312,6 @@ inline Field **TABLE::field_to_fill() } -extern const LEX_STRING trg_action_time_type_names[]; -extern const LEX_STRING trg_event_type_names[]; - bool add_table_for_trigger(THD *thd, const sp_name *trg_name, bool continue_if_not_exist, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1865f2e6321..4a88c1f2ddf 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -995,6 +995,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, const char *txt, class Window_frame *window_frame; class Window_frame_bound *window_frame_bound; udf_func *udf; + st_trg_execution_order trg_execution_order; /* enums */ enum Condition_information_item::Name cond_info_item_name; @@ -1022,6 +1023,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, const char *txt, enum Window_frame_bound::Bound_precedence_type bound_precedence_type; enum Window_frame::Frame_units frame_units; enum Window_frame::Frame_exclusion frame_exclusion; + enum trigger_order_type trigger_action_order_type; DDL_options_st object_ddl_options; } @@ -1251,6 +1253,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token FLOAT_NUM %token FLOAT_SYM /* SQL-2003-R */ %token FLUSH_SYM +%token FOLLOWS_SYM /* MYSQL trigger*/ %token FOLLOWING_SYM %token FORCE_SYM %token FOREIGN /* SQL-2003-R */ @@ -1476,6 +1479,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token POLYGON %token PORT_SYM %token POSITION_SYM /* SQL-2003-N */ +%token PRECEDES_SYM /* MYSQL */ %token PRECEDING_SYM %token PRECISION /* SQL-2003-R */ %token PREPARE_SYM /* SQL-2003-R */ @@ -2030,6 +2034,9 @@ END_OF_INPUT %type <NONE> signal_stmt resignal_stmt %type <diag_condition_item_name> signal_condition_information_item_name +%type <trg_execution_order> trigger_follows_precedes_clause; +%type <trigger_action_order_type> trigger_action_order; + %type <diag_area> which_area; %type <diag_info> diagnostics_information; %type <stmt_info_item> statement_information_item; @@ -14537,6 +14544,7 @@ keyword: | EXAMINED_SYM {} | EXECUTE_SYM {} | FLUSH_SYM {} + | FOLLOWS_SYM {} | FORMAT_SYM {} | GET_SYM {} | HANDLER_SYM {} @@ -14551,6 +14559,7 @@ keyword: | OWNER_SYM {} | PARSER_SYM {} | PORT_SYM {} + | PRECEDES_SYM {} | PREPARE_SYM {} | REMOVE_SYM {} | REPAIR {} @@ -16508,10 +16517,12 @@ view_select: { LEX *lex= Lex; uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str; + uint not_used; void *create_view_select= thd->memdup(lex->create_view_select.str, len); lex->create_view_select.length= len; lex->create_view_select.str= (char *) create_view_select; - trim_whitespace(thd->charset(), &lex->create_view_select); + trim_whitespace(thd->charset(), &lex->create_view_select, + ¬_used); lex->parsing_options.allows_variable= TRUE; lex->current_select->set_with_clause($2); } @@ -16545,6 +16556,28 @@ view_check_option: **************************************************************************/ +trigger_action_order: + FOLLOWS_SYM + { $$= TRG_ORDER_FOLLOWS; } + | PRECEDES_SYM + { $$= TRG_ORDER_PRECEDES; } + ; + +trigger_follows_precedes_clause: + /* empty */ + { + $$.ordering_clause= TRG_ORDER_NONE; + $$.anchor_trigger_name.str= NULL; + $$.anchor_trigger_name.length= 0; + } + | + trigger_action_order ident_or_text + { + $$.ordering_clause= $1; + $$.anchor_trigger_name= $2; + } + ; + trigger_tail: TRIGGER_SYM remember_name @@ -16569,7 +16602,11 @@ trigger_tail: } EACH_SYM ROW_SYM - { /* $17 */ + { + Lex->trg_chistics.ordering_clause_begin= YYLIP->get_cpp_ptr(); + } + trigger_follows_precedes_clause /* $18 */ + { /* $19 */ LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; @@ -16580,14 +16617,16 @@ trigger_tail: lex->ident.str= $9; lex->ident.length= $13 - $9; lex->spname= $5; + (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($18); + lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr(); if (!make_sp_head(thd, $5, TYPE_ENUM_TRIGGER)) MYSQL_YYABORT; - lex->sphead->set_body_start(thd, lip->get_cpp_ptr()); + lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_proc_stmt /* $18 */ - { /* $19 */ + sp_proc_stmt /* $20 */ + { /* $21 */ LEX *lex= Lex; sp_head *sp= lex->sphead; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 5cc81585ed5..7f4d988b072 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3088,7 +3088,8 @@ static const char *sql_mode_names[]= "PAD_CHAR_TO_FULL_LENGTH", 0 }; -export bool sql_mode_string_representation(THD *thd, ulonglong sql_mode, + +export bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode, LEX_STRING *ls) { set_to_string(thd, ls, sql_mode, sql_mode_names); diff --git a/sql/table.cc b/sql/table.cc index 9a9dee6e0ca..8d0a40858da 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -23,7 +23,6 @@ #include "key.h" // find_ref_key #include "sql_table.h" // build_table_filename, // primary_key_name -#include "sql_trigger.h" #include "sql_parse.h" // free_items #include "strfunc.h" // unhex_type2 #include "sql_partition.h" // mysql_unpack_partition, @@ -31,6 +30,7 @@ #include "sql_acl.h" // *_ACL, acl_getroot_no_password #include "sql_base.h" #include "create_options.h" +#include "sql_trigger.h" #include <m_ctype.h> #include "my_md5.h" #include "my_bit.h" diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index a8253ddf3ad..d18ee0efff2 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2570,10 +2570,11 @@ static int wsrep_create_trigger_query(THD *thd, uchar** buf, size_t* buf_len) append_definer(thd, &stmt_query, &definer_user, &definer_host); LEX_STRING stmt_definition; + uint not_used; stmt_definition.str= (char*) thd->lex->stmt_definition_begin; stmt_definition.length= thd->lex->stmt_definition_end - thd->lex->stmt_definition_begin; - trim_whitespace(thd->charset(), & stmt_definition); + trim_whitespace(thd->charset(), &stmt_definition, ¬_used); stmt_query.append(stmt_definition.str, stmt_definition.length); |