Home Explore Blog CI



postgresql

50th chunk of `doc/src/sgml/spi.sgml`
3277d9bcb5708027988d745f155675e1ef15bd5efb8ff69f0000000100000cfd
   a new transaction automatically.
  </para>
 </refsect1>
</refentry>

 </sect1>

 <sect1 id="spi-visibility">
  <title>Visibility of Data Changes</title>

  <para>
   The following rules govern the visibility of data changes in
   functions that use SPI (or any other C function):

   <itemizedlist>
    <listitem>
     <para>
      During the execution of an SQL command, any data changes made by
      the command are invisible to the command itself.  For
      example, in:
<programlisting>
INSERT INTO a SELECT * FROM a;
</programlisting>
      the inserted rows are invisible to the <command>SELECT</command>
      part.
     </para>
    </listitem>

    <listitem>
     <para>
      Changes made by a command C are visible to all commands that are
      started after C, no matter whether they are started inside C
      (during the execution of C) or after C is done.
     </para>
    </listitem>

    <listitem>
     <para>
      Commands executed via SPI inside a function called by an SQL command
      (either an ordinary function or a trigger) follow one or the
      other of the above rules depending on the read/write flag passed
      to SPI.  Commands executed in read-only mode follow the first
      rule: they cannot see changes of the calling command.  Commands executed
      in read-write mode follow the second rule: they can see all changes made
      so far.
     </para>
    </listitem>

    <listitem>
     <para>
      All standard procedural languages set the SPI read-write mode
      depending on the volatility attribute of the function.  Commands of
      <literal>STABLE</literal> and <literal>IMMUTABLE</literal> functions are done in
      read-only mode, while commands of <literal>VOLATILE</literal> functions are
      done in read-write mode.  While authors of C functions are able to
      violate this convention, it's unlikely to be a good idea to do so.
     </para>
    </listitem>
   </itemizedlist>
  </para>

  <para>
   The next section contains an example that illustrates the
   application of these rules.
  </para>
 </sect1>

 <sect1 id="spi-examples">
  <title>Examples</title>

  <para>
   This section contains a very simple example of SPI usage. The
   C function <function>execq</function> takes an SQL command as its
   first argument and a row count as its second, executes the command
   using <function>SPI_exec</function> and returns the number of rows
   that were processed by the command.  You can find more complex
   examples for SPI in the source tree in
   <filename>src/test/regress/regress.c</filename> and in the
   <xref linkend="contrib-spi"/> module.
  </para>

<programlisting>
#include "postgres.h"

#include "executor/spi.h"
#include "utils/builtins.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(execq);

Datum
execq(PG_FUNCTION_ARGS)
{
    char *command;
    int cnt;
    int ret;
    uint64 proc;

    /* Convert given text object to a C string */
    command = text_to_cstring(PG_GETARG_TEXT_PP(0));
    cnt = PG_GETARG_INT32(1);

    SPI_connect();

    ret = SPI_exec(command, cnt);

    proc = SPI_processed;

    /*
     * If some rows were fetched, print them via elog(INFO).
     */
    if (ret &gt; 0 &amp;&amp; SPI_tuptable != NULL)
    {
        SPITupleTable *tuptable = SPI_tuptable;
        TupleDesc tupdesc = tuptable-&gt;tupdesc;

Title: SPI Data Visibility and Examples
Summary
This section details the visibility rules for data changes within SPI functions, explaining how commands see changes made by other commands based on their execution order and read/write mode. It also describes how procedural languages set the SPI read-write mode based on function volatility. The section concludes with a simple example of SPI usage, showcasing a C function `execq` that executes an SQL command and returns the number of processed rows.