| Bug #58476 | A trigger with a non-existent definer can be created but not executed | ||
|---|---|---|---|
| Submitted: | 24 Nov 2010 23:13 | Modified: | 25 Nov 2010 0:47 |
| Reporter: | Sasha Pachev | Email Updates: | |
| Status: | Not a Bug | Impact on me: | |
| Category: | MySQL Server: Stored Routines | Severity: | S3 (Non-critical) |
| Version: | 5.1.50 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | triggers | ||
[24 Nov 2010 23:38]
MySQL Verification Team
Thank you for the bug report.
C:\DBS>c:\dbs\5.1\bin\mysql -uroot --port=3306 --prompt="mysql 5.1 >"
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.1.54-Win X64-debug Source distribution
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql 5.1 >USE test;
Database changed
mysql 5.1 >DROP TRIGGER IF EXISTS test_trigger;
Query OK, 0 rows affected (0.01 sec)
mysql 5.1 >DROP TABLE IF EXISTS test1,test2;
Query OK, 0 rows affected (0.01 sec)
mysql 5.1 >CREATE TABLE test1(n int);
Query OK, 0 rows affected (0.06 sec)
mysql 5.1 >CREATE TABLE test2(n int);
Query OK, 0 rows affected (0.05 sec)
mysql 5.1 >
mysql 5.1 >delimiter |
mysql 5.1 >
mysql 5.1 >CREATE DEFINER=foo@bar TRIGGER test_trigger AFTER INSERT ON test1
-> FOR EACH ROW BEGIN
-> INSERT INTO test2 VALUES(NEW.n) ;
-> END;
-> |
Query OK, 0 rows affected, 1 warning (0.08 sec)
mysql 5.1 >SHOW WARNINGS|
+-------+------+--------------------------------------------------------------+
| Level | Code | Message |
+-------+------+--------------------------------------------------------------+
| Note | 1449 | The user specified as a definer ('foo'@'bar') does not exist |
+-------+------+--------------------------------------------------------------+
1 row in set (0.00 sec)
mysql 5.1 >DELIMITER ;
mysql 5.1 >SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='test_trigger'\G
*************************** 1. row ***************************
TRIGGER_CATALOG: NULL
TRIGGER_SCHEMA: test
TRIGGER_NAME: test_trigger
EVENT_MANIPULATION: INSERT
EVENT_OBJECT_CATALOG: NULL
EVENT_OBJECT_SCHEMA: test
EVENT_OBJECT_TABLE: test1
ACTION_ORDER: 0
ACTION_CONDITION: NULL
ACTION_STATEMENT: BEGIN
INSERT INTO test2 VALUES(NEW.n) ;
END
ACTION_ORIENTATION: ROW
ACTION_TIMING: AFTER
ACTION_REFERENCE_OLD_TABLE: NULL
ACTION_REFERENCE_NEW_TABLE: NULL
ACTION_REFERENCE_OLD_ROW: OLD
ACTION_REFERENCE_NEW_ROW: NEW
CREATED: NULL
SQL_MODE:
DEFINER: foo@bar
CHARACTER_SET_CLIENT: latin1
COLLATION_CONNECTION: latin1_swedish_ci
DATABASE_COLLATION: latin1_swedish_ci
1 row in set (0.13 sec)
mysql 5.1 >INSERT INTO test1 VALUES(1);
ERROR 1449 (HY000): The user specified as a definer ('foo'@'bar') does not exist
mysql 5.1 >
[25 Nov 2010 0:47]
Davi Arnaut
This is not a bug, it work as documented in the manual: "If you have the SUPER privilege, you can specify any syntactically legal account name. If the account does not actually exist, a warning is generated." Furthermore, even if a user exists at the time when the trigger is created, it does not imply it will exist at the time of its execution. Hence, if the user is dropped later, the "DBA" will see the same error.

Description: A trigger with a non-existent definer can be created with no error. A query that triggers its execution results in an error thoroughly confusing a DBA. How to repeat: USE test; DROP TRIGGER IF EXISTS test_trigger; DROP TABLE IF EXISTS test1,test2; CREATE TABLE test1(n int); CREATE TABLE test2(n int); delimiter | CREATE DEFINER=foo@bar TRIGGER test_trigger AFTER INSERT ON test1 FOR EACH ROW BEGIN INSERT INTO test2 VALUES(NEW.n) ; END; | SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='test_trigger'; INSERT INTO test1 VALUES(1); Suggested fix: For the DBA: SELECT a.* FROM (SELECT definer,trigger_name,trigger_schema,event_object_table FROM INFORMATION_SCHEMA.TRIGGERS) a LEFT JOIN mysql.user ON definer = CONCAT(user,'@',host) WHERE user IS NULL; this will list all triggers that will execute with an error. Fix them either by adding their users, or by dropping and re-creating them. From the shell using the replace utility that comes with MySQL distribution: replace bad_user good_user -- /path/to/datadir/*/*.TRG followed by MySQL FLUSH PRIVILEGES should do the trick as well. Any danger in that aside from this not being applicable when the internal trigger format changes? For the developers of MySQL - check if the user exists before proceeding with trigger creation.