Skip to content

Commit 3a0e4d3

Browse files
committed
Make new event trigger facility actually do something.
Commit 3855968 added syntax, pg_dump, psql support, and documentation, but the triggers didn't actually fire. With this commit, they now do. This is still a pretty basic facility overall because event triggers do not get a whole lot of information about what the user is trying to do unless you write them in C; and there's still no option to fire them anywhere except at the very beginning of the execution sequence, but it's better than nothing, and a good building block for future work. Along the way, add a regression test for ALTER LARGE OBJECT, since testing of event triggers reveals that we haven't got one. Dimitri Fontaine and Robert Haas
1 parent be86e3d commit 3a0e4d3

File tree

28 files changed

+1087
-197
lines changed

28 files changed

+1087
-197
lines changed

contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,9 @@ static void pgss_ExecutorRun(QueryDesc *queryDesc,
240240
static void pgss_ExecutorFinish(QueryDesc *queryDesc);
241241
static void pgss_ExecutorEnd(QueryDesc *queryDesc);
242242
static void pgss_ProcessUtility(Node *parsetree,
243-
const char *queryString, ParamListInfo params, bool isTopLevel,
244-
DestReceiver *dest, char *completionTag);
243+
const char *queryString, ParamListInfo params,
244+
DestReceiver *dest, char *completionTag,
245+
ProcessUtilityContext context);
245246
static uint32 pgss_hash_fn(const void *key, Size keysize);
246247
static int pgss_match_fn(const void *key1, const void *key2, Size keysize);
247248
static uint32 pgss_hash_string(const char *str);
@@ -785,8 +786,8 @@ pgss_ExecutorEnd(QueryDesc *queryDesc)
785786
*/
786787
static void
787788
pgss_ProcessUtility(Node *parsetree, const char *queryString,
788-
ParamListInfo params, bool isTopLevel,
789-
DestReceiver *dest, char *completionTag)
789+
ParamListInfo params, DestReceiver *dest,
790+
char *completionTag, ProcessUtilityContext context)
790791
{
791792
/*
792793
* If it's an EXECUTE statement, we don't track it and don't increment the
@@ -819,10 +820,10 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
819820
{
820821
if (prev_ProcessUtility)
821822
prev_ProcessUtility(parsetree, queryString, params,
822-
isTopLevel, dest, completionTag);
823+
dest, completionTag, context);
823824
else
824825
standard_ProcessUtility(parsetree, queryString, params,
825-
isTopLevel, dest, completionTag);
826+
dest, completionTag, context);
826827
nested_level--;
827828
}
828829
PG_CATCH();
@@ -880,10 +881,10 @@ pgss_ProcessUtility(Node *parsetree, const char *queryString,
880881
{
881882
if (prev_ProcessUtility)
882883
prev_ProcessUtility(parsetree, queryString, params,
883-
isTopLevel, dest, completionTag);
884+
dest, completionTag, context);
884885
else
885886
standard_ProcessUtility(parsetree, queryString, params,
886-
isTopLevel, dest, completionTag);
887+
dest, completionTag, context);
887888
}
888889
}
889890

doc/src/sgml/plpgsql.sgml

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3377,7 +3377,10 @@ RAISE unique_violation USING MESSAGE = 'Duplicate user ID: ' || user_id;
33773377
<secondary>in PL/pgSQL</secondary>
33783378
</indexterm>
33793379

3380-
<para>
3380+
<sect2 id="plpgsql-dml-trigger">
3381+
<title>Triggers on data changes</title>
3382+
3383+
<para>
33813384
<application>PL/pgSQL</application> can be used to define trigger
33823385
procedures. A trigger procedure is created with the
33833386
<command>CREATE FUNCTION</> command, declaring it as a function with
@@ -3924,6 +3927,70 @@ UPDATE sales_fact SET units_sold = units_sold * 2;
39243927
SELECT * FROM sales_summary_bytime;
39253928
</programlisting>
39263929
</example>
3930+
</sect2>
3931+
3932+
<sect2 id="plpgsql-event-trigger">
3933+
<title>Triggers on events</title>
3934+
3935+
<para>
3936+
<application>PL/pgSQL</application> can be used to define event
3937+
triggers. <productname>PostgreSQL</> requires that a procedure that
3938+
is to be called as an event trigger must be declared as a function with
3939+
no arguments and a return type of <literal>event_trigger</>.
3940+
</para>
3941+
3942+
<para>
3943+
When a <application>PL/pgSQL</application> function is called as a
3944+
event trigger, several special variables are created automatically
3945+
in the top-level block. They are:
3946+
3947+
<variablelist>
3948+
<varlistentry>
3949+
<term><varname>TG_EVENT</varname></term>
3950+
<listitem>
3951+
<para>
3952+
Data type <type>text</type>; a string representing the event the
3953+
trigger is fired for.
3954+
</para>
3955+
</listitem>
3956+
</varlistentry>
3957+
3958+
<varlistentry>
3959+
<term><varname>TG_TAG</varname></term>
3960+
<listitem>
3961+
<para>
3962+
Data type <type>text</type>; variable that contains the command tag
3963+
for which the trigger is fired.
3964+
</para>
3965+
</listitem>
3966+
</varlistentry>
3967+
</variablelist>
3968+
</para>
3969+
3970+
<para>
3971+
<xref linkend="plpgsql-event-trigger-example"> shows an example of a
3972+
event trigger procedure in <application>PL/pgSQL</application>.
3973+
</para>
3974+
3975+
<example id="plpgsql-event-trigger-example">
3976+
<title>A <application>PL/pgSQL</application> Event Trigger Procedure</title>
3977+
3978+
<para>
3979+
This example trigger simply raises a <literal>NOTICE</literal> message
3980+
each time a supported command is executed.
3981+
</para>
3982+
3983+
<programlisting>
3984+
CREATE OR REPLACE FUNCTION snitch() RETURNS event_trigger AS $$
3985+
BEGIN
3986+
RAISE NOTICE 'snitch: % %', tg_event, tg_tag;
3987+
END;
3988+
$$ LANGUAGE plpgsql;
3989+
3990+
CREATE EVENT TRIGGER snitch ON ddl_command_start EXECUTE PROCEDURE snitch();
3991+
</programlisting>
3992+
</example>
3993+
</sect2>
39273994

39283995
</sect1>
39293996

doc/src/sgml/ref/create_event_trigger.sgml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,6 @@ CREATE EVENT TRIGGER <replaceable class="PARAMETER">name</replaceable>
9898
A user-supplied function that is declared as taking no argument and
9999
returning type <literal>event_trigger</literal>.
100100
</para>
101-
<para>
102-
If your event trigger is implemented in <literal>C</literal> then it
103-
will be called with an argument, of
104-
type <literal>internal</literal>, which is a pointer to
105-
the <literal>Node *</literal> parse tree.
106-
</para>
107101
</listitem>
108102
</varlistentry>
109103

0 commit comments

Comments
 (0)