Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0fe21ad

Browse files
committed
doc: Add event trigger C API documentation
From: Dimitri Fontaine <dimitri@2ndQuadrant.fr>
1 parent82b0102 commit0fe21ad

File tree

1 file changed

+218
-6
lines changed

1 file changed

+218
-6
lines changed

‎doc/src/sgml/event-trigger.sgml

Lines changed: 218 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,27 @@
3737
<para>
3838
The <literal>ddl_command_start</> event occurs just before the
3939
execution of a <literal>CREATE</>, <literal>ALTER</>, or <literal>DROP</>
40-
command. As an exception, however, this event does not occur for
40+
command. No check whether the affected object exists or doesn't exist is
41+
performed before the event trigger fires.
42+
As an exception, however, this event does not occur for
4143
DDL commands targeting shared objects &mdash; databases, roles, and tablespaces
42-
&mdash; or forcommand targeting event triggers themselves. The event trigger
44+
&mdash; or forcommands targeting event triggers themselves. The event trigger
4345
mechanism does not support these object types.
4446
<literal>ddl_command_start</> also occurs just before the execution of a
4547
<literal>SELECT INTO</literal> command, since this is equivalent to
46-
<literal>CREATE TABLE AS</literal>. The <literal>ddl_command_end</>
47-
event occurs just after the execution of this same set of commands.
48+
<literal>CREATE TABLE AS</literal>.
49+
</para>
50+
51+
<para>
52+
The <literal>ddl_command_end</> event occurs just after the execution of
53+
this same set of commands.
4854
</para>
4955

5056
<para>
5157
The <literal>sql_drop</> event occurs just before the
5258
<literal>ddl_command_end</> event trigger for any operation that drops
53-
database objects. To list the objects that have been dropped, use the set
54-
returning function <literal>pg_event_trigger_dropped_objects()</> fromyour
59+
database objects. To list the objects that have been dropped, use the
60+
set-returning function <literal>pg_event_trigger_dropped_objects()</> fromthe
5561
<literal>sql_drop</> event trigger code (see
5662
<xref linkend="functions-event-triggers">). Note that
5763
the trigger is executed after the objects have been deleted from the
@@ -76,6 +82,7 @@
7682
</para>
7783

7884
<para>
85+
Event triggers are created using the command <xref linkend="sql-createeventtrigger">.
7986
In order to create an event trigger, you must first create a function with
8087
the special return type <literal>event_trigger</literal>. This function
8188
need not (and may not) return a value; the return type serves merely as
@@ -607,4 +614,209 @@
607614
</table>
608615
</sect1>
609616

617+
<sect1 id="event-trigger-interface">
618+
<title>Writing Event Trigger Functions in C</title>
619+
620+
<indexterm zone="event-trigger-interface">
621+
<primary>event trigger</primary>
622+
<secondary>in C</secondary>
623+
</indexterm>
624+
625+
<para>
626+
This section describes the low-level details of the interface to an
627+
event trigger function. This information is only needed when writing
628+
event trigger functions in C. If you are using a higher-level language
629+
then these details are handled for you. In most cases you should
630+
consider using a procedural language before writing your event triggers
631+
in C. The documentation of each procedural language explains how to
632+
write an event trigger in that language.
633+
</para>
634+
635+
<para>
636+
Event trigger functions must use the <quote>version 1</> function
637+
manager interface.
638+
</para>
639+
640+
<para>
641+
When a function is called by the event trigger manager, it is not passed
642+
any normal arguments, but it is passed a <quote>context</> pointer
643+
pointing to a <structname>EventTriggerData</> structure. C functions can
644+
check whether they were called from the event trigger manager or not by
645+
executing the macro:
646+
<programlisting>
647+
CALLED_AS_EVENT_TRIGGER(fcinfo)
648+
</programlisting>
649+
which expands to:
650+
<programlisting>
651+
((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, EventTriggerData))
652+
</programlisting>
653+
If this returns true, then it is safe to cast
654+
<literal>fcinfo-&gt;context</> to type <literal>EventTriggerData
655+
*</literal> and make use of the pointed-to
656+
<structname>EventTriggerData</> structure. The function must
657+
<emphasis>not</emphasis> alter the <structname>EventTriggerData</>
658+
structure or any of the data it points to.
659+
</para>
660+
661+
<para>
662+
<structname>struct EventTriggerData</structname> is defined in
663+
<filename>commands/event_trigger.h</filename>:
664+
665+
<programlisting>
666+
typedef struct EventTriggerData
667+
{
668+
NodeTag type;
669+
const char *event; /* event name */
670+
Node *parsetree; /* parse tree */
671+
const char *tag; /* command tag */
672+
} EventTriggerData;
673+
</programlisting>
674+
675+
where the members are defined as follows:
676+
677+
<variablelist>
678+
<varlistentry>
679+
<term><structfield>type</></term>
680+
<listitem>
681+
<para>
682+
Always <literal>T_EventTriggerData</literal>.
683+
</para>
684+
</listitem>
685+
</varlistentry>
686+
687+
<varlistentry>
688+
<term><structfield>tg_event</></term>
689+
<listitem>
690+
<para>
691+
Describes the event for which the function is called, one of
692+
<literal>"ddl_command_start"</literal>, <literal>"ddl_command_end"</literal>,
693+
<literal>"sql_drop"</literal>.
694+
See <xref linkend="event-trigger-definition"> for the meaning of these
695+
events.
696+
</para>
697+
</listitem>
698+
</varlistentry>
699+
700+
<varlistentry>
701+
<term><structfield>parsetree</></term>
702+
<listitem>
703+
<para>
704+
A pointer to the parse tree of the command. Check the PostgreSQL
705+
source code for details. The parse tree structure is subject to change
706+
without notice.
707+
</para>
708+
</listitem>
709+
</varlistentry>
710+
711+
<varlistentry>
712+
<term><structfield>tag</></term>
713+
<listitem>
714+
<para>
715+
The command tag associated with the event for which the event trigger
716+
is run, for example <literal>"CREATE FUNCTION"</literal>.
717+
</para>
718+
</listitem>
719+
</varlistentry>
720+
</variablelist>
721+
</para>
722+
723+
<para>
724+
An event trigger function must return a <symbol>NULL</> pointer
725+
(<emphasis>not</> an SQL null value, that is, do not
726+
set <parameter>isNull</parameter> true).
727+
</para>
728+
</sect1>
729+
730+
<sect1 id="event-trigger-example">
731+
<title>A Complete Event Trigger Example</title>
732+
733+
<para>
734+
Here is a very simple example of an event trigger function written in C.
735+
(Examples of triggers written in procedural languages can be found in
736+
the documentation of the procedural languages.)
737+
</para>
738+
739+
<para>
740+
The function <function>noddl</> raises an exception each time it is called.
741+
The event trigger definition associated the function with
742+
the <literal>ddl_command_start</literal> event. The effect is that all DDL
743+
commands (with the exceptions mentioned
744+
in <xref linkend="event-trigger-definition">) are prevented from running.
745+
</para>
746+
747+
<para>
748+
This is the source code of the trigger function:
749+
<programlisting><![CDATA[
750+
#include "postgres.h"
751+
#include "commands/event_trigger.h"
752+
753+
754+
PG_MODULE_MAGIC;
755+
756+
Datum noddl(PG_FUNCTION_ARGS);
757+
758+
PG_FUNCTION_INFO_V1(noddl);
759+
760+
Datum
761+
noddl(PG_FUNCTION_ARGS)
762+
{
763+
EventTriggerData *trigdata;
764+
765+
if (!CALLED_AS_EVENT_TRIGGER(fcinfo)) /* internal error */
766+
elog(ERROR, "not fired by event trigger manager");
767+
768+
trigdata = (EventTriggerData *) fcinfo->context;
769+
770+
ereport(ERROR,
771+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
772+
errmsg("command \"%s\" denied", trigdata->tag)));
773+
774+
PG_RETURN_NULL();
775+
}
776+
]]></programlisting>
777+
</para>
778+
779+
<para>
780+
After you have compiled the source code (see <xref linkend="dfunc">),
781+
declare the function and the triggers:
782+
<programlisting>
783+
CREATE FUNCTION noddl() RETURNS event_trigger
784+
AS 'noddl' LANGUAGE C;
785+
786+
CREATE EVENT TRIGGER noddl ON ddl_command_start
787+
EXECUTE PROCEDURE noddl();
788+
</programlisting>
789+
</para>
790+
791+
<para>
792+
Now you can test the operation of the trigger:
793+
<screen>
794+
=# \dy
795+
List of event triggers
796+
Name | Event | Owner | Enabled | Procedure | Tags
797+
-------+-------------------+-------+---------+-----------+------
798+
noddl | ddl_command_start | dim | enabled | noddl |
799+
(1 row)
800+
801+
=# CREATE TABLE foo(id serial);
802+
ERROR: command "CREATE TABLE" denied
803+
</screen>
804+
</para>
805+
806+
<para>
807+
In this situation, in order to be able to run some DDL commands when you
808+
need to do so, you have to either drop the event trigger or disable it. It
809+
can be convenient to disable the trigger for only the duration of a
810+
transaction:
811+
<programlisting>
812+
BEGIN;
813+
ALTER EVENT TRIGGER noddl DISABLE;
814+
CREATE TABLE foo (id serial);
815+
ALTER EVENT TRIGGER noddl ENABLE;
816+
COMMIT;
817+
</programlisting>
818+
(Recall that DDL commands on event triggers themselves are not affected by
819+
event triggers.)
820+
</para>
821+
</sect1>
610822
</chapter>

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp