Support more commands in event triggers
authorAlvaro Herrera
Mon, 23 Feb 2015 17:22:42 +0000 (14:22 -0300)
committerAlvaro Herrera
Mon, 23 Feb 2015 17:22:42 +0000 (14:22 -0300)
COMMENT, SECURITY LABEL, and GRANT/REVOKE now also fire
ddl_command_start and ddl_command_end event triggers, when they operate
on database-local objects.

Reviewed-By: Michael Paquier, Andres Freund, Stephen Frost
doc/src/sgml/event-trigger.sgml
src/backend/commands/event_trigger.c
src/backend/tcop/utility.c
src/include/commands/event_trigger.h

index 156c4639ab9934fded3e0862c53cabbab8398e9a..04353eac3d76c0ff6e15421f12b652384e557c35 100644 (file)
@@ -36,7 +36,9 @@
 
    
      The ddl_command_start event occurs just before the
-     execution of a CREATE, ALTER, or DROP
+     execution of a CREATE, ALTER, DROP,
+     SECURITY LABEL,
+     COMMENT, GRANT or REVOKE
      command.  No check whether the affected object exists or doesn't exist is
      performed before the event trigger fires.
      As an exception, however, this event does not occur for
 
    
      Event Trigger Support by Command Tag
-     5">
+     6">
       
        
-        command tag
+        Command Tag
         ddl_command_start
         ddl_command_end
         sql_drop
         table_rewrite
+        Notes
        
       
       
         X
         -
         -
+        
        
        
         ALTER COLLATION
         X
         -
         -
+        
        
        
         ALTER CONVERSION
         X
         -
         -
+        
        
        
         ALTER DOMAIN
         X
         -
         -
+        
        
        
         ALTER EXTENSION
         X
         -
         -
+        
        
        
         ALTER FOREIGN DATA WRAPPER
         X
         -
         -
+        
        
        
         ALTER FOREIGN TABLE
         X
         X
         -
+        
        
        
         ALTER FUNCTION
         X
         -
         -
+        
        
        
         ALTER LANGUAGE
         X
         -
         -
+        
        
        
         ALTER OPERATOR
         X
         -
         -
+        
        
        
         ALTER OPERATOR CLASS
         X
         -
         -
+        
        
        
         ALTER OPERATOR FAMILY
         X
         -
         -
+        
        
        
         ALTER POLICY
         X
         -
         -
+        
        
        
         ALTER SCHEMA
         X
         -
         -
+        
        
        
         ALTER SEQUENCE
         X
         -
         -
+        
        
        
         ALTER SERVER
         X
         -
         -
+        
        
        
         ALTER TABLE
         X
         X
         X
+        
        
        
         ALTER TEXT SEARCH CONFIGURATION
         X
         -
         -
+        
        
        
         ALTER TEXT SEARCH DICTIONARY
         X
         -
         -
+        
        
        
         ALTER TEXT SEARCH PARSER
         X
         -
         -
+        
        
        
         ALTER TEXT SEARCH TEMPLATE
         X
         -
         -
+        
        
        
         ALTER TRIGGER
         X
         -
         -
+        
        
        
         ALTER TYPE
         X
         -
         -
+        
        
        
         ALTER USER MAPPING
         X
         -
         -
+        
        
        
         ALTER VIEW
         X
         -
         -
+        
        
        
         CREATE AGGREGATE
         X
         -
         -
+        
+       
+       
+        COMMENT
+        X
+        X
+        -
+        -
+        Only for local objects
        
        
         CREATE CAST
         X
         -
         -
+        
        
        
         CREATE COLLATION
         X
         -
         -
+        
        
        
         CREATE CONVERSION
         X
         -
         -
+        
        
        
         CREATE DOMAIN
         X
         -
         -
+        
        
        
         CREATE EXTENSION
         X
         -
         -
+        
        
        
         CREATE FOREIGN DATA WRAPPER
         X
         -
         -
+        
        
        
         CREATE FOREIGN TABLE
         X
         -
         -
+        
        
        
         CREATE FUNCTION
         X
         -
         -
+        
        
        
         CREATE INDEX
         X
         -
         -
+        
        
        
         CREATE LANGUAGE
         X
         -
         -
+        
        
        
         CREATE OPERATOR
         X
         -
         -
+        
        
        
         CREATE OPERATOR CLASS
         X
         -
         -
+        
        
        
         CREATE OPERATOR FAMILY
         X
         -
         -
+        
        
        
         CREATE POLICY
         X
         -
         -
+        
        
        
         CREATE RULE
         X
         -
         -
+        
        
        
         CREATE SCHEMA
         X
         -
         -
+        
        
        
         CREATE SEQUENCE
         X
         -
         -
+        
        
        
         CREATE SERVER
         X
         -
         -
+        
        
        
         CREATE TABLE
         X
         -
         -
+        
        
        
         CREATE TABLE AS
         X
         -
         -
+        
        
        
         CREATE TEXT SEARCH CONFIGURATION
         X
         -
         -
+        
        
        
         CREATE TEXT SEARCH DICTIONARY
         X
         -
         -
+        
        
        
         CREATE TEXT SEARCH PARSER
         X
         -
         -
+        
        
        
         CREATE TEXT SEARCH TEMPLATE
         X
         -
         -
+        
        
        
         CREATE TRIGGER
         X
         -
         -
+        
        
        
         CREATE TYPE
         X
         -
         -
+        
        
        
         CREATE VIEW
         X
         -
         -
+        
        
        
         DROP AGGREGATE
         X
         X
         -
+        
        
        
         DROP CAST
         X
         X
         -
+        
        
        
         DROP COLLATION
         X
         X
         -
+        
        
        
         DROP CONVERSION
         X
         X
         -
+        
        
        
         DROP DOMAIN
         X
         X
         -
+        
        
        
         DROP EXTENSION
         X
         X
         -
+        
        
        
         DROP FOREIGN DATA WRAPPER
         X
         X
         -
+        
        
        
         DROP FOREIGN TABLE
         X
         X
         -
+        
        
        
         DROP FUNCTION
         X
         X
         -
+        
        
        
         DROP INDEX
         X
         X
         -
+        
        
        
         DROP LANGUAGE
         X
         X
         -
+        
        
        
         DROP OPERATOR
         X
         X
         -
+        
        
        
         DROP OPERATOR CLASS
         X
         X
         -
+        
        
        
         DROP OPERATOR FAMILY
         X
         X
         -
+        
        
        
         DROP OWNED
         X
         X
         -
+        
        
        
         DROP POLICY
         X
         X
         -
+        
        
        
         DROP RULE
         X
         X
         -
+        
        
        
         DROP SCHEMA
         X
         X
         -
+        
        
        
         DROP SEQUENCE
         X
         X
         -
+        
        
        
         DROP SERVER
         X
         X
         -
+        
        
        
         DROP TABLE
         X
         X
         -
+        
        
        
         DROP TEXT SEARCH CONFIGURATION
         X
         X
         -
+        
        
        
         DROP TEXT SEARCH DICTIONARY
         X
         X
         -
+        
        
        
         DROP TEXT SEARCH PARSER
         X
         X
         -
+        
        
        
         DROP TEXT SEARCH TEMPLATE
         X
         X
         -
+        
        
        
         DROP TRIGGER
         X
         X
         -
+        
        
        
         DROP TYPE
         X
         X
         -
+        
        
        
         DROP USER MAPPING
         X
         X
         -
+        
        
        
         DROP VIEW
         X
         X
         -
+        
+       
+       
+        GRANT
+        X
+        X
+        -
+        -
+        Only for local objects
        
        
         IMPORT FOREIGN SCHEMA
         X
         -
         -
+        
+       
+       
+        REVOKE
+        X
+        X
+        -
+        -
+        Only for local objects
+       
+       
+        SECURITY LABEL
+        X
+        X
+        -
+        -
+        Only for local objects
        
        
         SELECT INTO
         X
         -
         -
+        
        
       
      
index a33a5ada1a90519a240815dae08001991085b25b..dcf5b987477a5fafacf2c559fcd7e0e472eb09af 100644 (file)
@@ -267,8 +267,12 @@ check_ddl_tag(const char *tag)
        pg_strcasecmp(tag, "REFRESH MATERIALIZED VIEW") == 0 ||
        pg_strcasecmp(tag, "ALTER DEFAULT PRIVILEGES") == 0 ||
        pg_strcasecmp(tag, "ALTER LARGE OBJECT") == 0 ||
+       pg_strcasecmp(tag, "COMMENT") == 0 ||
+       pg_strcasecmp(tag, "GRANT") == 0 ||
+       pg_strcasecmp(tag, "REVOKE") == 0 ||
        pg_strcasecmp(tag, "DROP OWNED") == 0 ||
-       pg_strcasecmp(tag, "IMPORT FOREIGN SCHEMA") == 0)
+       pg_strcasecmp(tag, "IMPORT FOREIGN SCHEMA") == 0 ||
+       pg_strcasecmp(tag, "SECURITY LABEL") == 0)
        return EVENT_TRIGGER_COMMAND_TAG_OK;
 
    /*
@@ -1149,6 +1153,34 @@ EventTriggerSupportsObjectClass(ObjectClass objclass)
    return true;
 }
 
+bool
+EventTriggerSupportsGrantObjectType(GrantObjectType objtype)
+{
+   switch (objtype)
+   {
+       case ACL_OBJECT_DATABASE:
+       case ACL_OBJECT_TABLESPACE:
+           /* no support for global objects */
+           return false;
+
+       case ACL_OBJECT_COLUMN:
+       case ACL_OBJECT_RELATION:
+       case ACL_OBJECT_SEQUENCE:
+       case ACL_OBJECT_DOMAIN:
+       case ACL_OBJECT_FDW:
+       case ACL_OBJECT_FOREIGN_SERVER:
+       case ACL_OBJECT_FUNCTION:
+       case ACL_OBJECT_LANGUAGE:
+       case ACL_OBJECT_LARGEOBJECT:
+       case ACL_OBJECT_NAMESPACE:
+       case ACL_OBJECT_TYPE:
+           return true;
+       default:
+           Assert(false);
+           return true;
+   }
+}
+
 /*
  * Prepare event trigger state for a new complete query to run, if necessary;
  * returns whether this was done.  If it was, EventTriggerEndCompleteQuery must
index 3533cfa22d457e19c7eb8235266d965891058cc7..fcc2ecdbfb465ffc2a10462158132d1590e1857e 100644 (file)
@@ -513,14 +513,6 @@ standard_ProcessUtility(Node *parsetree,
            ExecuteTruncate((TruncateStmt *) parsetree);
            break;
 
-       case T_CommentStmt:
-           CommentObject((CommentStmt *) parsetree);
-           break;
-
-       case T_SecLabelStmt:
-           ExecSecLabelStmt((SecLabelStmt *) parsetree);
-           break;
-
        case T_CopyStmt:
            {
                uint64      processed;
@@ -548,11 +540,6 @@ standard_ProcessUtility(Node *parsetree,
            DeallocateQuery((DeallocateStmt *) parsetree);
            break;
 
-       case T_GrantStmt:
-           /* no event triggers for global objects */
-           ExecuteGrantStmt((GrantStmt *) parsetree);
-           break;
-
        case T_GrantRoleStmt:
            /* no event triggers for global objects */
            GrantRole((GrantRoleStmt *) parsetree);
@@ -783,6 +770,19 @@ standard_ProcessUtility(Node *parsetree,
             * in some cases, so we "fast path" them in the other cases.
             */
 
+       case T_GrantStmt:
+           {
+               GrantStmt  *stmt = (GrantStmt *) parsetree;
+
+               if (EventTriggerSupportsGrantObjectType(stmt->objtype))
+                   ProcessUtilitySlow(parsetree, queryString,
+                                      context, params,
+                                      dest, completionTag);
+               else
+                   ExecuteGrantStmt((GrantStmt *) parsetree);
+           }
+           break;
+
        case T_DropStmt:
            {
                DropStmt   *stmt = (DropStmt *) parsetree;
@@ -835,6 +835,32 @@ standard_ProcessUtility(Node *parsetree,
            }
            break;
 
+       case T_CommentStmt:
+           {
+               CommentStmt *stmt = (CommentStmt *) parsetree;
+
+               if (EventTriggerSupportsObjectType(stmt->objtype))
+                   ProcessUtilitySlow(parsetree, queryString,
+                                      context, params,
+                                      dest, completionTag);
+               else
+                   CommentObject((CommentStmt *) parsetree);
+               break;
+           }
+
+       case T_SecLabelStmt:
+           {
+               SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
+
+               if (EventTriggerSupportsObjectType(stmt->objtype))
+                   ProcessUtilitySlow(parsetree, queryString,
+                                      context, params,
+                                      dest, completionTag);
+               else
+                   ExecSecLabelStmt(stmt);
+               break;
+           }
+
        default:
            /* All other statement types have event trigger support */
            ProcessUtilitySlow(parsetree, queryString,
@@ -1315,6 +1341,14 @@ ProcessUtilitySlow(Node *parsetree,
                ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
                break;
 
+           case T_CommentStmt:
+               CommentObject((CommentStmt *) parsetree, NULL);
+               break;
+
+           case T_GrantStmt:
+               ExecuteGrantStmt((GrantStmt *) parsetree);
+               break;
+
            case T_DropOwnedStmt:
                DropOwnedObjects((DropOwnedStmt *) parsetree);
                break;
@@ -1331,6 +1365,10 @@ ProcessUtilitySlow(Node *parsetree,
                AlterPolicy((AlterPolicyStmt *) parsetree);
                break;
 
+           case T_SecLabelStmt:
+               ExecSecLabelStmt((SecLabelStmt *) parsetree;
+               break;
+
            default:
                elog(ERROR, "unrecognized node type: %d",
                     (int) nodeTag(parsetree));
index e807e658e4963e9b8031c2542086b0b70d89080e..9ac9fc37356d05d270821d52fb4402379703f393 100644 (file)
@@ -48,6 +48,7 @@ extern void AlterEventTriggerOwner_oid(Oid, Oid newOwnerId);
 
 extern bool EventTriggerSupportsObjectType(ObjectType obtype);
 extern bool EventTriggerSupportsObjectClass(ObjectClass objclass);
+extern bool EventTriggerSupportsGrantObjectType(GrantObjectType objtype);
 extern void EventTriggerDDLCommandStart(Node *parsetree);
 extern void EventTriggerDDLCommandEnd(Node *parsetree);
 extern void EventTriggerSQLDrop(Node *parsetree);