diff options
| author | Kevin Grittner | 2017-04-04 23:36:39 +0000 |
|---|---|---|
| committer | Kevin Grittner | 2017-04-04 23:36:39 +0000 |
| commit | 5ebeb579b9b281dba5f8415b2fbda86fdae7b366 (patch) | |
| tree | 66aac432d4acc7300f2b395e4c8282f75d53ef0a /doc | |
| parent | 9a3215026bd6955e88bd8c20542cfe6acffdb1c8 (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.sgml | 10 | ||||
| -rw-r--r-- | doc/src/sgml/spi.sgml | 125 | ||||
| -rw-r--r-- | doc/src/sgml/trigger.sgml | 54 |
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). |
