<!-- doc/src/sgml/event-trigger.sgml -->

 <chapter id="event-triggers">
  <title>Event Triggers</title>

  <indexterm zone="event-triggers">
   <primary>event trigger</primary>
  </indexterm>

  <para>
   To supplement the trigger mechanism discussed in <xref linkend="triggers">,
   <productname>PostgreSQL</> also provides event triggers.  Unlike regular
   triggers, which are attached to a single table and capture only DML events,
   event triggers are global to a particular database and are capable of
   capturing DDL events.
  </para>

  <para>
   Like regular triggers, event triggers can be written in any procedural
   language that includes event trigger support, or in C, but not in plain
   SQL.
  </para>

  <sect1 id="event-trigger-definition">
   <title>Overview of Event Trigger Behavior</title>

   <para>
     An event trigger fires whenever the event with which it is associated
     occurs in the database in which it is defined. Currently, the only
     supported events are
     <literal>ddl_command_start</>,
     <literal>ddl_command_end</>
     and <literal>sql_drop</>.
     Support for additional events may be added in future releases.
   </para>

   <para>
     The <literal>ddl_command_start</> event occurs just before the
     execution of a <literal>CREATE</>, <literal>ALTER</>, or <literal>DROP</>
     command.  As an exception, however, this event does not occur for
     DDL commands targeting shared objects &mdash; databases, roles, and tablespaces
     &mdash; or for command targeting event triggers themselves.  The event trigger
     mechanism does not support these object types.
     <literal>ddl_command_start</> also occurs just before the execution of a
     <literal>SELECT INTO</literal> command, since this is equivalent to
     <literal>CREATE TABLE AS</literal>.  The <literal>ddl_command_end</>
     event occurs just after the execution of this same set of commands.
   </para>

   <para>
    The <literal>sql_drop</> event occurs just before the
    <literal>ddl_command_end</> event trigger for any operation that drops
    database objects.  To list the objects that have been dropped, use the set
    returning function <literal>pg_event_trigger_dropped_objects()</> from your
    <literal>sql_drop</> event trigger code (see
    <xref linkend="functions-event-triggers">). Note that
    the trigger is executed after the objects have been deleted from the
    system catalogs, so it's not possible to look them up anymore.
   </para>

   <para>
     Event triggers (like other functions) cannot be executed in an aborted
     transaction.  Thus, if a DDL command fails with an error, any associated
     <literal>ddl_command_end</> triggers will not be executed.  Conversely,
     if a <literal>ddl_command_start</> trigger fails with an error, no
     further event triggers will fire, and no attempt will be made to execute
     the command itself.  Similarly, if a <literal>ddl_command_end</> trigger
     fails with an error, the effects of the DDL statement will be rolled
     back, just as they would be in any other case where the containing
     transaction aborts.
   </para>

   <para>
     For a complete list of commands supported by the event trigger mechanism,
     see <xref linkend="event-trigger-matrix">.
   </para>

   <para>
     In order to create an event trigger, you must first create a function with
     the special return type <literal>event_trigger</literal>.  This function
     need not (and may not) return a value; the return type serves merely as
     a signal that the function is to be invoked as an event trigger.
   </para>

   <para>
     If more than one event trigger is defined for a particular event, they will
     fire in alphabetical order by trigger name.
   </para>

   <para>
     A trigger definition can also specify a <literal>WHEN</literal>
     condition so that, for example, a <literal>ddl_command_start</literal>
     trigger can be fired only for particular commands which the user wishes
     to intercept. A common use of such triggers is to restrict the range of
     DDL operations which users may perform.
   </para>
  </sect1>

  <sect1 id="event-trigger-matrix">
   <title>Event Trigger Firing Matrix</title>

   <para>
     <xref linkend="event-trigger-by-command-tag"> lists all commands
     for which event triggers are supported.
   </para>

   <table id="event-trigger-by-command-tag">
     <title>Event Trigger Support by Command Tag</title>
     <tgroup cols="4">
      <thead>
       <row>
        <entry>command tag</entry>
        <entry><literal>ddl_command_start</literal></entry>
        <entry><literal>ddl_command_end</literal></entry>
        <entry><literal>sql_drop</literal></entry>
       </row>
      </thead>
      <tbody>
       <row>
        <entry align="left"><literal>ALTER AGGREGATE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER COLLATION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER CONVERSION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER DOMAIN</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER EXTENSION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER FOREIGN DATA WRAPPER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER FOREIGN TABLE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER FUNCTION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER LANGUAGE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER OPERATOR</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER OPERATOR CLASS</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER OPERATOR FAMILY</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER SCHEMA</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER SEQUENCE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER SERVER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TABLE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TEXT SEARCH CONFIGURATION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TEXT SEARCH DICTIONARY</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TEXT SEARCH PARSER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TEXT SEARCH TEMPLATE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TRIGGER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER TYPE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER USER MAPPING</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>ALTER VIEW</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE AGGREGATE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE CAST</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE COLLATION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE CONVERSION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE DOMAIN</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE EXTENSION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE FOREIGN DATA WRAPPER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE FOREIGN TABLE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE FUNCTION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE INDEX</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE LANGUAGE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE OPERATOR</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE OPERATOR CLASS</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE OPERATOR FAMILY</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE RULE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE SCHEMA</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE SEQUENCE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE SERVER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TABLE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TABLE AS</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TEXT SEARCH CONFIGURATION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TEXT SEARCH DICTIONARY</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TEXT SEARCH PARSER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TEXT SEARCH TEMPLATE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TRIGGER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE TYPE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE USER MAPPING</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>CREATE VIEW</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP AGGREGATE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP CAST</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP COLLATION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP CONVERSION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP DOMAIN</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP EXTENSION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP FOREIGN DATA WRAPPER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP FOREIGN TABLE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP FUNCTION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP INDEX</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP LANGUAGE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP OPERATOR</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP OPERATOR CLASS</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP OPERATOR FAMILY</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP OWNED</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP RULE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP SCHEMA</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP SEQUENCE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP SERVER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TABLE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TEXT SEARCH CONFIGURATION</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TEXT SEARCH DICTIONARY</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TEXT SEARCH PARSER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TEXT SEARCH TEMPLATE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TRIGGER</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP TYPE</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP USER MAPPING</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>DROP VIEW</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
       </row>
       <row>
        <entry align="left"><literal>SELECT INTO</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>X</literal></entry>
        <entry align="center"><literal>-</literal></entry>
       </row>
      </tbody>
     </tgroup>
   </table>
  </sect1>

</chapter>
