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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy