Home Explore Blog CI



postgresql

5th chunk of `doc/src/sgml/event-trigger.sgml`
a97f0038713f1b04876b579419996a2db8119c2b5072a7060000000100000de6
 without notice.
       </para>
      </listitem>
     </varlistentry>

     <varlistentry>
      <term><structfield>tag</structfield></term>
      <listitem>
       <para>
        The command tag associated with the event for which the event trigger
        is run, for example <literal>"CREATE FUNCTION"</literal>.
       </para>
      </listitem>
     </varlistentry>
    </variablelist>
   </para>

   <para>
    An event trigger function must return a <symbol>NULL</symbol> pointer
    (<emphasis>not</emphasis> an SQL null value, that is, do not
    set <parameter>isNull</parameter> true).
   </para>
  </sect1>

  <sect1 id="event-trigger-example">
   <title>A Complete Event Trigger Example</title>

   <para>
    Here is a very simple example of an event trigger function written in C.
    (Examples of triggers written in procedural languages can be found in
    the documentation of the procedural languages.)
   </para>

   <para>
    The function <function>noddl</function> raises an exception each time it is called.
    The event trigger definition associated the function with
    the <literal>ddl_command_start</literal> event.  The effect is that all DDL
    commands (with the exceptions mentioned
    in <xref linkend="event-trigger-definition"/>) are prevented from running.
   </para>

   <para>
    This is the source code of the trigger function:
<programlisting><![CDATA[
#include "postgres.h"

#include "commands/event_trigger.h"
#include "fmgr.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(noddl);

Datum
noddl(PG_FUNCTION_ARGS)
{
    EventTriggerData *trigdata;

    if (!CALLED_AS_EVENT_TRIGGER(fcinfo))  /* internal error */
        elog(ERROR, "not fired by event trigger manager");

    trigdata = (EventTriggerData *) fcinfo->context;

    ereport(ERROR,
            (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
             errmsg("command \"%s\" denied",
                    GetCommandTagName(trigdata->tag))));

    PG_RETURN_NULL();
}
]]></programlisting>
   </para>

   <para>
    After you have compiled the source code (see <xref linkend="dfunc"/>),
    declare the function and the triggers:
<programlisting>
CREATE FUNCTION noddl() RETURNS event_trigger
    AS 'noddl' LANGUAGE C;

CREATE EVENT TRIGGER noddl ON ddl_command_start
    EXECUTE FUNCTION noddl();
</programlisting>
   </para>

   <para>
    Now you can test the operation of the trigger:
<screen>
=# \dy
                     List of event triggers
 Name  |       Event       | Owner | Enabled | Function | Tags
-------+-------------------+-------+---------+----------+------
 noddl | ddl_command_start | dim   | enabled | noddl    |
(1 row)

=# CREATE TABLE foo(id serial);
ERROR:  command "CREATE TABLE" denied
</screen>
   </para>

   <para>
    In this situation, in order to be able to run some DDL commands when you
    need to do so, you have to either drop the event trigger or disable it.  It
    can be convenient to disable the trigger for only the duration of a
    transaction:
<programlisting>
BEGIN;
ALTER EVENT TRIGGER noddl DISABLE;
CREATE TABLE foo (id serial);
ALTER EVENT TRIGGER noddl ENABLE;
COMMIT;
</programlisting>
    (Recall that DDL commands on event triggers themselves are not affected by
    event triggers.)
   </para>
  </sect1>

  <sect1 id="event-trigger-table-rewrite-example">
   <title>A Table Rewrite Event Trigger Example</title>

   <para>
    Thanks to the <literal>table_rewrite</literal> event, it is possible to implement
    a table rewriting policy only allowing the rewrite in maintenance windows.
   </para>

  

Title: A Complete Event Trigger Example in C
Summary
This section provides a C example of an event trigger function named 'noddl' that raises an exception upon every call, effectively preventing all DDL commands (with exceptions). The code demonstrates how to check if the function is triggered by the event manager, access 'EventTriggerData', and raise an error to deny a command. It includes instructions on compiling the code, declaring the function, creating the event trigger, and testing its operation. It also shows how to temporarily disable the trigger for specific transactions.