summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorKevin Grittner2017-04-04 23:36:39 +0000
committerKevin Grittner2017-04-04 23:36:39 +0000
commit5ebeb579b9b281dba5f8415b2fbda86fdae7b366 (patch)
tree66aac432d4acc7300f2b395e4c8282f75d53ef0a /doc
parent9a3215026bd6955e88bd8c20542cfe6acffdb1c8 (diff)
Follow-on cleanup for the transition table patch.
Commit 59702716 added transition table support to PL/pgsql so that SQL queries in trigger functions could access those transient tables. In order to provide the same level of support for PL/perl, PL/python and PL/tcl, refactor the relevant code into a new function SPI_register_trigger_data. Call the new function in the trigger handler of all four PLs, and document it as a public SPI function so that authors of out-of-tree PLs can do the same. Also get rid of a second QueryEnvironment object that was maintained by PL/pgsql. That was previously used to deal with cursors, but the same approach wasn't appropriate for PLs that are less tangled up with core code. Instead, have SPI_cursor_open install the connection's current QueryEnvironment, as already happens for SPI_execute_plan. While in the docs, remove the note that transition tables were only supported in C and PL/pgSQL triggers, and correct some ommissions. Thomas Munro with some work by Kevin Grittner (mostly docs)
Diffstat (limited to 'doc')
-rw-r--r--doc/src/sgml/ref/create_trigger.sgml10
-rw-r--r--doc/src/sgml/spi.sgml125
-rw-r--r--doc/src/sgml/trigger.sgml54
3 files changed, 176 insertions, 13 deletions
diff --git a/doc/src/sgml/ref/create_trigger.sgml b/doc/src/sgml/ref/create_trigger.sgml
index e22e42e7dcf..24195b3849d 100644
--- a/doc/src/sgml/ref/create_trigger.sgml
+++ b/doc/src/sgml/ref/create_trigger.sgml
@@ -8,6 +8,11 @@ PostgreSQL documentation
<primary>CREATE TRIGGER</primary>
</indexterm>
+ <indexterm>
+ <primary>transition tables</primary>
+ <seealso>ephemeral named relation</seealso>
+ </indexterm>
+
<refmeta>
<refentrytitle>CREATE TRIGGER</refentrytitle>
<manvolnum>7</manvolnum>
@@ -322,11 +327,6 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
<para>
The (unqualified) name to be used within the trigger for this relation.
</para>
- <note>
- <para>
- So far only triggers written in C or PL/pgSQL support this.
- </para>
- </note>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml
index af7eada2e1b..86be87c0fdb 100644
--- a/doc/src/sgml/spi.sgml
+++ b/doc/src/sgml/spi.sgml
@@ -2644,6 +2644,11 @@ SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
<refentry id="spi-spi-register-relation">
<indexterm><primary>SPI_register_relation</primary></indexterm>
+ <indexterm>
+ <primary>ephemeral named relation</primary>
+ <secondary>registering with SPI</secondary>
+ </indexterm>
+
<refmeta>
<refentrytitle>SPI_register_relation</refentrytitle>
<manvolnum>3</manvolnum>
@@ -2746,6 +2751,11 @@ int SPI_register_relation(EphemeralNamedRelation <parameter>enr</parameter>)
<refentry id="spi-spi-unregister-relation">
<indexterm><primary>SPI_unregister_relation</primary></indexterm>
+ <indexterm>
+ <primary>ephemeral named relation</primary>
+ <secondary>unregistering from SPI</secondary>
+ </indexterm>
+
<refmeta>
<refentrytitle>SPI_unregister_relation</refentrytitle>
<manvolnum>3</manvolnum>
@@ -2843,6 +2853,121 @@ int SPI_unregister_relation(const char * <parameter>name</parameter>)
<!-- *********************************************** -->
+<refentry id="spi-spi-register-trigger-data">
+ <indexterm><primary>SPI_register_trigger_data</primary></indexterm>
+
+ <indexterm>
+ <primary>ephemeral named relation</primary>
+ <secondary>registering with SPI</secondary>
+ </indexterm>
+
+ <indexterm>
+ <primary>transition tables</primary>
+ <secondary>implementation in PLs</secondary>
+ </indexterm>
+
+ <refmeta>
+ <refentrytitle>SPI_register_trigger_data</refentrytitle>
+ <manvolnum>3</manvolnum>
+ </refmeta>
+
+ <refnamediv>
+ <refname>SPI_register_trigger_data</refname>
+ <refpurpose>make ephemeral trigger data available in SPI queries</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+<synopsis>
+int SPI_register_trigger_data(TriggerData *<parameter>tdata</parameter>)
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <function>SPI_register_trigger_data</function> makes any ephemeral
+ relations captured by a trigger available to queries planned and executed
+ through the current SPI connection. Currently, this means the transition
+ tables captured by an <literal>AFTER</literal> trigger defined with a
+ <literal>REFERENCING OLD/NEW TABLE AS</literal> ... clause. This function
+ should be called by a PL trigger handler function after connecting.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Arguments</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>TriggerData *<parameter>tdata</parameter></literal></term>
+ <listitem>
+ <para>
+ the <structname>TriggerData</structname> object passed to a trigger
+ handler function as <literal>fcinfo->context</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>Return Value</title>
+
+ <para>
+ If the execution of the command was successful then the following
+ (nonnegative) value will be returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_OK_TD_REGISTER</symbol></term>
+ <listitem>
+ <para>
+ if the captured trigger data (if any) has been successfully registered
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+
+ <para>
+ On error, one of the following negative values is returned:
+
+ <variablelist>
+ <varlistentry>
+ <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
+ <listitem>
+ <para>
+ if <parameter>tdata</parameter> is <symbol>NULL</symbol>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
+ <listitem>
+ <para>
+ if called from an unconnected procedure
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><symbol>SPI_ERROR_REL_DUPLICATE</symbol></term>
+ <listitem>
+ <para>
+ if the name of any trigger data transient relation is already
+ registered for this connection
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- *********************************************** -->
+
</sect1>
<sect1 id="spi-interface-support">
diff --git a/doc/src/sgml/trigger.sgml b/doc/src/sgml/trigger.sgml
index 8f724c86648..2a718d7f473 100644
--- a/doc/src/sgml/trigger.sgml
+++ b/doc/src/sgml/trigger.sgml
@@ -395,6 +395,11 @@
<secondary>in C</secondary>
</indexterm>
+ <indexterm>
+ <primary>transition tables</primary>
+ <secondary>referencing from C trigger</secondary>
+ </indexterm>
+
<para>
This section describes the low-level details of the interface to a
trigger function. This information is only needed when writing
@@ -438,14 +443,16 @@ CALLED_AS_TRIGGER(fcinfo)
<programlisting>
typedef struct TriggerData
{
- NodeTag type;
- TriggerEvent tg_event;
- Relation tg_relation;
- HeapTuple tg_trigtuple;
- HeapTuple tg_newtuple;
- Trigger *tg_trigger;
- Buffer tg_trigtuplebuf;
- Buffer tg_newtuplebuf;
+ NodeTag type;
+ TriggerEvent tg_event;
+ Relation tg_relation;
+ HeapTuple tg_trigtuple;
+ HeapTuple tg_newtuple;
+ Trigger *tg_trigger;
+ Buffer tg_trigtuplebuf;
+ Buffer tg_newtuplebuf;
+ Tuplestorestate *tg_oldtable;
+ Tuplestorestate *tg_newtable;
} TriggerData;
</programlisting>
@@ -629,6 +636,8 @@ typedef struct Trigger
int16 *tgattr;
char **tgargs;
char *tgqual;
+ char *tgoldtable;
+ char *tgnewtable;
} Trigger;
</programlisting>
@@ -662,10 +671,39 @@ typedef struct Trigger
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><structfield>tg_oldtable</></term>
+ <listitem>
+ <para>
+ A pointer to a structure of type <structname>Tuplestorestate</structname>
+ containing zero or more rows in the format specified by
+ <structfield>tg_relation</structfield>, or a <symbol>NULL</> pointer
+ if there is no <literal>OLD TABLE</literal> transition relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><structfield>tg_newtable</></term>
+ <listitem>
+ <para>
+ A pointer to a structure of type <structname>Tuplestorestate</structname>
+ containing zero or more rows in the format specified by
+ <structfield>tg_relation</structfield>, or a <symbol>NULL</> pointer
+ if there is no <literal>NEW TABLE</literal> transition relation.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</para>
<para>
+ To allow queries issued through SPI to reference transition tables, see
+ <xref linkend="spi-spi-register-trigger-data">.
+ </para>
+
+ <para>
A trigger function must return either a
<structname>HeapTuple</> pointer or a <symbol>NULL</> pointer
(<emphasis>not</> an SQL null value, that is, do not set <parameter>isNull</parameter> true).