]> begriffs open source - ai-pg/blob - full-docs/src/sgml/html/trigger-interface.html
PG 18 docs from https://ftp.postgresql.org/pub/source/v18.0/postgresql-18.0-docs...
[ai-pg] / full-docs / src / sgml / html / trigger-interface.html
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>37.3. Writing Trigger Functions in C</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="trigger-datachanges.html" title="37.2. Visibility of Data Changes" /><link rel="next" href="trigger-example.html" title="37.4. A Complete Trigger Example" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">37.3. Writing Trigger Functions in C</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="trigger-datachanges.html" title="37.2. Visibility of Data Changes">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="triggers.html" title="Chapter 37. Triggers">Up</a></td><th width="60%" align="center">Chapter 37. Triggers</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="trigger-example.html" title="37.4. A Complete Trigger Example">Next</a></td></tr></table><hr /></div><div class="sect1" id="TRIGGER-INTERFACE"><div class="titlepage"><div><div><h2 class="title" style="clear: both">37.3. Writing Trigger Functions in C <a href="#TRIGGER-INTERFACE" class="id_link">#</a></h2></div></div></div><a id="id-1.8.4.7.2" class="indexterm"></a><a id="id-1.8.4.7.3" class="indexterm"></a><p>
3     This section describes the low-level details of the interface to a
4     trigger function.  This information is only needed when writing
5     trigger functions in C.  If you are using a higher-level language then
6     these details are handled for you.  In most cases you should consider
7     using a procedural language before writing your triggers in C.  The
8     documentation of each procedural language explains how to write a
9     trigger in that language.
10    </p><p>
11     Trigger functions must use the <span class="quote">“<span class="quote">version 1</span>”</span> function manager
12     interface.
13    </p><p>
14     When a function is called by the trigger manager, it is not passed
15     any normal arguments, but it is passed a <span class="quote">“<span class="quote">context</span>”</span>
16     pointer pointing to a <code class="structname">TriggerData</code> structure.  C
17     functions can check whether they were called from the trigger
18     manager or not by executing the macro:
19 </p><pre class="programlisting">
20 CALLED_AS_TRIGGER(fcinfo)
21 </pre><p>
22     which expands to:
23 </p><pre class="programlisting">
24 ((fcinfo)-&gt;context != NULL &amp;&amp; IsA((fcinfo)-&gt;context, TriggerData))
25 </pre><p>
26     If this returns true, then it is safe to cast
27     <code class="literal">fcinfo-&gt;context</code> to type <code class="literal">TriggerData
28     *</code> and make use of the pointed-to
29     <code class="structname">TriggerData</code> structure.  The function must
30     <span class="emphasis"><em>not</em></span> alter the <code class="structname">TriggerData</code>
31     structure or any of the data it points to.
32    </p><p>
33     <code class="structname">struct TriggerData</code> is defined in
34     <code class="filename">commands/trigger.h</code>:
35
36 </p><pre class="programlisting">
37 typedef struct TriggerData
38 {
39     NodeTag          type;
40     TriggerEvent     tg_event;
41     Relation         tg_relation;
42     HeapTuple        tg_trigtuple;
43     HeapTuple        tg_newtuple;
44     Trigger         *tg_trigger;
45     TupleTableSlot  *tg_trigslot;
46     TupleTableSlot  *tg_newslot;
47     Tuplestorestate *tg_oldtable;
48     Tuplestorestate *tg_newtable;
49     const Bitmapset *tg_updatedcols;
50 } TriggerData;
51 </pre><p>
52
53     where the members are defined as follows:
54
55     </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="structfield">type</code></span></dt><dd><p>
56         Always <code class="literal">T_TriggerData</code>.
57        </p></dd><dt><span class="term"><code class="structfield">tg_event</code></span></dt><dd><p>
58         Describes the event for which the function is called. You can use the
59         following macros to examine <code class="literal">tg_event</code>:
60
61         </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">TRIGGER_FIRED_BEFORE(tg_event)</code></span></dt><dd><p>
62             Returns true if the trigger fired before the operation.
63            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_AFTER(tg_event)</code></span></dt><dd><p>
64             Returns true if the trigger fired after the operation.
65            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_INSTEAD(tg_event)</code></span></dt><dd><p>
66             Returns true if the trigger fired instead of the operation.
67            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_FOR_ROW(tg_event)</code></span></dt><dd><p>
68             Returns true if the trigger fired for a row-level event.
69            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_FOR_STATEMENT(tg_event)</code></span></dt><dd><p>
70             Returns true if the trigger fired for a statement-level event.
71            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_INSERT(tg_event)</code></span></dt><dd><p>
72             Returns true if the trigger was fired by an <code class="command">INSERT</code> command.
73            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_UPDATE(tg_event)</code></span></dt><dd><p>
74             Returns true if the trigger was fired by an <code class="command">UPDATE</code> command.
75            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_DELETE(tg_event)</code></span></dt><dd><p>
76             Returns true if the trigger was fired by a <code class="command">DELETE</code> command.
77            </p></dd><dt><span class="term"><code class="literal">TRIGGER_FIRED_BY_TRUNCATE(tg_event)</code></span></dt><dd><p>
78             Returns true if the trigger was fired by a <code class="command">TRUNCATE</code> command.
79            </p></dd></dl></div><p>
80        </p></dd><dt><span class="term"><code class="structfield">tg_relation</code></span></dt><dd><p>
81         A pointer to a structure describing the relation that the trigger fired for.
82         Look at <code class="filename">utils/rel.h</code> for details about
83         this structure.  The most interesting things are
84         <code class="literal">tg_relation-&gt;rd_att</code> (descriptor of the relation
85         tuples) and <code class="literal">tg_relation-&gt;rd_rel-&gt;relname</code>
86         (relation name; the type is not <code class="type">char*</code> but
87         <code class="type">NameData</code>; use
88         <code class="literal">SPI_getrelname(tg_relation)</code> to get a <code class="type">char*</code> if you
89         need a copy of the name).
90        </p></dd><dt><span class="term"><code class="structfield">tg_trigtuple</code></span></dt><dd><p>
91         A pointer to the row for which the trigger was fired. This is
92         the row being inserted, updated, or deleted.  If this trigger
93         was fired for an <code class="command">INSERT</code> or
94         <code class="command">DELETE</code> then this is what you should return
95         from the function if you don't want to replace the row with
96         a different one (in the case of <code class="command">INSERT</code>) or
97         skip the operation.  For triggers on foreign tables, values of system
98         columns herein are unspecified.
99        </p></dd><dt><span class="term"><code class="structfield">tg_newtuple</code></span></dt><dd><p>
100         A pointer to the new version of the row, if the trigger was
101         fired for an <code class="command">UPDATE</code>, and <code class="symbol">NULL</code> if
102         it is for an <code class="command">INSERT</code> or a
103         <code class="command">DELETE</code>. This is what you have to return
104         from the function if the event is an <code class="command">UPDATE</code>
105         and you don't want to replace this row by a different one or
106         skip the operation.  For triggers on foreign tables, values of system
107         columns herein are unspecified.
108        </p></dd><dt><span class="term"><code class="structfield">tg_trigger</code></span></dt><dd><p>
109         A pointer to a structure of type <code class="structname">Trigger</code>,
110         defined in <code class="filename">utils/reltrigger.h</code>:
111
112 </p><pre class="programlisting">
113 typedef struct Trigger
114 {
115     Oid         tgoid;
116     char       *tgname;
117     Oid         tgfoid;
118     int16       tgtype;
119     char        tgenabled;
120     bool        tgisinternal;
121     bool        tgisclone;
122     Oid         tgconstrrelid;
123     Oid         tgconstrindid;
124     Oid         tgconstraint;
125     bool        tgdeferrable;
126     bool        tginitdeferred;
127     int16       tgnargs;
128     int16       tgnattr;
129     int16      *tgattr;
130     char      **tgargs;
131     char       *tgqual;
132     char       *tgoldtable;
133     char       *tgnewtable;
134 } Trigger;
135 </pre><p>
136
137        where <code class="structfield">tgname</code> is the trigger's name,
138        <code class="structfield">tgnargs</code> is the number of arguments in
139        <code class="structfield">tgargs</code>, and <code class="structfield">tgargs</code> is an array of
140        pointers to the arguments specified in the <code class="command">CREATE
141        TRIGGER</code> statement. The other members are for internal use
142        only.
143        </p></dd><dt><span class="term"><code class="structfield">tg_trigslot</code></span></dt><dd><p>
144         The slot containing <code class="structfield">tg_trigtuple</code>,
145         or a <code class="symbol">NULL</code> pointer if there is no such tuple.
146        </p></dd><dt><span class="term"><code class="structfield">tg_newslot</code></span></dt><dd><p>
147         The slot containing <code class="structfield">tg_newtuple</code>,
148         or a <code class="symbol">NULL</code> pointer if there is no such tuple.
149        </p></dd><dt><span class="term"><code class="structfield">tg_oldtable</code></span></dt><dd><p>
150         A pointer to a structure of type <code class="structname">Tuplestorestate</code>
151         containing zero or more rows in the format specified by
152         <code class="structfield">tg_relation</code>, or a <code class="symbol">NULL</code> pointer
153         if there is no <code class="literal">OLD TABLE</code> transition relation.
154        </p></dd><dt><span class="term"><code class="structfield">tg_newtable</code></span></dt><dd><p>
155         A pointer to a structure of type <code class="structname">Tuplestorestate</code>
156         containing zero or more rows in the format specified by
157         <code class="structfield">tg_relation</code>, or a <code class="symbol">NULL</code> pointer
158         if there is no <code class="literal">NEW TABLE</code> transition relation.
159        </p></dd><dt><span class="term"><code class="structfield">tg_updatedcols</code></span></dt><dd><p>
160         For <code class="literal">UPDATE</code> triggers, a bitmap set indicating the
161         columns that were updated by the triggering command.  Generic trigger
162         functions can use this to optimize actions by not having to deal with
163         columns that were not changed.
164        </p><p>
165         As an example, to determine whether a column with attribute number
166         <code class="varname">attnum</code> (1-based) is a member of this bitmap set,
167         call <code class="literal">bms_is_member(attnum -
168         FirstLowInvalidHeapAttributeNumber,
169         trigdata-&gt;tg_updatedcols))</code>.
170        </p><p>
171         For triggers other than <code class="literal">UPDATE</code> triggers, this will
172         be <code class="symbol">NULL</code>.
173        </p></dd></dl></div><p>
174    </p><p>
175     To allow queries issued through SPI to reference transition tables, see
176     <a class="xref" href="spi-spi-register-trigger-data.html" title="SPI_register_trigger_data"><span class="refentrytitle">SPI_register_trigger_data</span></a>.
177    </p><p>
178     A trigger function must return either a
179     <code class="structname">HeapTuple</code> pointer or a <code class="symbol">NULL</code> pointer
180     (<span class="emphasis"><em>not</em></span> an SQL null value, that is, do not set <em class="parameter"><code>isNull</code></em> true).
181     Be careful to return either
182     <code class="structfield">tg_trigtuple</code> or <code class="structfield">tg_newtuple</code>,
183     as appropriate, if you don't want to modify the row being operated on.
184    </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="trigger-datachanges.html" title="37.2. Visibility of Data Changes">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="triggers.html" title="Chapter 37. Triggers">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="trigger-example.html" title="37.4. A Complete Trigger Example">Next</a></td></tr><tr><td width="40%" align="left" valign="top">37.2. Visibility of Data Changes </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 37.4. A Complete Trigger Example</td></tr></table></div></body></html>