Home Explore Blog CI



postgresql

doc/src/sgml/spi.sgml
c30a92f5f21d17c2f3475a191b9393259c511c96d01786700000000300025761
<!-- doc/src/sgml/spi.sgml -->

<chapter id="spi">
 <title>Server Programming Interface</title>

 <indexterm zone="spi">
  <primary>SPI</primary>
 </indexterm>

 <para>
  The <firstterm>Server Programming Interface</firstterm>
  (<acronym>SPI</acronym>) gives writers of user-defined
  <acronym>C</acronym> functions the ability to run
  <acronym>SQL</acronym> commands inside their functions or procedures.
  <acronym>SPI</acronym> is a set of
  interface functions to simplify access to the parser, planner,
  and executor. <acronym>SPI</acronym> also does some
  memory management.
 </para>

 <note>
  <para>
   The available procedural languages provide various means to
   execute SQL commands from functions.  Most of these facilities are
   based on SPI, so this documentation might be of use for users
   of those languages as well.
  </para>
 </note>

 <para>
  Note that if a command invoked via SPI fails, then control will not be
  returned to your C function.  Rather, the
  transaction or subtransaction in which your C function executes will be
  rolled back.  (This might seem surprising given that the SPI functions mostly
  have documented error-return conventions.  Those conventions only apply
  for errors detected within the SPI functions themselves, however.)
  It is possible to recover control after an error by establishing your own
  subtransaction surrounding SPI calls that might fail.
 </para>

 <para>
  <acronym>SPI</acronym> functions return a nonnegative result on
  success (either via a returned integer value or in the global
  variable <varname>SPI_result</varname>, as described below).  On
  error, a negative result or <symbol>NULL</symbol> will be returned.
 </para>

 <para>
  Source code files that use SPI must include the header file
  <filename>executor/spi.h</filename>.
 </para>


<sect1 id="spi-interface">
 <title>Interface Functions</title>

 <refentry id="spi-spi-connect">
  <indexterm><primary>SPI_connect</primary></indexterm>
  <indexterm><primary>SPI_connect_ext</primary></indexterm>

  <refmeta>
   <refentrytitle>SPI_connect</refentrytitle>
   <manvolnum>3</manvolnum>
  </refmeta>

  <refnamediv>
   <refname>SPI_connect</refname>
   <refname>SPI_connect_ext</refname>
   <refpurpose>connect a C function to the SPI manager</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_connect(void)
</synopsis>

 <synopsis>
int SPI_connect_ext(int <parameter>options</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_connect</function> opens a connection from a
   C function invocation to the SPI manager.  You must call this
   function if you want to execute commands through SPI.  Some utility
   SPI functions can be called from unconnected C functions.
  </para>

  <para>
   <function>SPI_connect_ext</function> does the same but has an argument that
   allows passing option flags.  Currently, the following option values are
   available:
   <variablelist>
    <varlistentry>
     <term><symbol>SPI_OPT_NONATOMIC</symbol></term>
     <listitem>
      <para>
       Sets the SPI connection to be <firstterm>nonatomic</firstterm>, which
       means that transaction control calls (<function>SPI_commit</function>,
       <function>SPI_rollback</function>) are allowed.  Otherwise,
       calling those functions will result in an immediate error.
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>

  <para>
   <literal>SPI_connect()</literal> is equivalent to
   <literal>SPI_connect_ext(0)</literal>.
  </para>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <variablelist>
   <varlistentry>
    <term><symbol>SPI_OK_CONNECT</symbol></term>
    <listitem>
     <para>
      on success
     </para>
    </listitem>
   </varlistentry>
  </variablelist>

  <para>
   The fact that these functions return <type>int</type>
   not <type>void</type> is historical.  All failure cases are reported
   via <function>ereport</function> or <function>elog</function>.
   (In versions before <productname>PostgreSQL</productname> v10,
   some but not all failures would be reported with a result value
   of <symbol>SPI_ERROR_CONNECT</symbol>.)
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-finish">
 <indexterm><primary>SPI_finish</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_finish</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_finish</refname>
  <refpurpose>disconnect a C function from the SPI manager</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_finish(void)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_finish</function> closes an existing connection to
   the SPI manager.  You must call this function after completing the
   SPI operations needed during your C function's current invocation.
   You do not need to worry about making this happen, however, if you
   abort the transaction via <literal>elog(ERROR)</literal>.  In that
   case SPI will clean itself up automatically.
  </para>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <variablelist>
   <varlistentry>
    <term><symbol>SPI_OK_FINISH</symbol></term>
    <listitem>
     <para>
      if properly disconnected
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
    <listitem>
     <para>
      if called from an unconnected C function
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execute">
 <indexterm><primary>SPI_execute</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execute</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execute</refname>
  <refpurpose>execute a command</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execute(const char * <parameter>command</parameter>, bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execute</function> executes the specified SQL command
   for <parameter>count</parameter> rows.  If <parameter>read_only</parameter>
   is <literal>true</literal>, the command must be read-only, and execution overhead
   is somewhat reduced.
  </para>

  <para>
   This function can only be called from a connected C function.
  </para>

  <para>
   If <parameter>count</parameter> is zero then the command is executed
   for all rows that it applies to.  If <parameter>count</parameter>
   is greater than zero, then no more than <parameter>count</parameter> rows
   will be retrieved; execution stops when the count is reached, much like
   adding a <literal>LIMIT</literal> clause to the query. For example,
<programlisting>
SPI_execute("SELECT * FROM foo", true, 5);
</programlisting>
   will retrieve at most 5 rows from the table.  Note that such a limit
   is only effective when the command actually returns rows.  For example,
<programlisting>
SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
</programlisting>
   inserts all rows from <structname>bar</structname>, ignoring the
   <parameter>count</parameter> parameter.  However, with
<programlisting>
SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);
</programlisting>
   at most 5 rows would be inserted, since execution would stop after the
   fifth <literal>RETURNING</literal> result row is retrieved.
  </para>

  <para>
   You can pass multiple commands in one string;
   <function>SPI_execute</function> returns the
   result for the command executed last.  The <parameter>count</parameter>
   limit applies to each command separately (even though only the last
   result will actually be returned).  The limit is not applied to any
   hidden commands generated by rules.
  </para>

  <para>
   When <parameter>read_only</parameter> is <literal>false</literal>,
   <function>SPI_execute</function> increments the command
   counter and computes a new <firstterm>snapshot</firstterm> before executing each
   command in the string.  The snapshot does not actually change if the
   current transaction isolation level is <literal>SERIALIZABLE</literal> or <literal>REPEATABLE READ</literal>, but in
   <literal>READ COMMITTED</literal> mode the snapshot update allows each command to
   see the results of newly committed transactions from other sessions.
   This is essential for consistent behavior when the commands are modifying
   the database.
  </para>

  <para>
   When <parameter>read_only</parameter> is <literal>true</literal>,
   <function>SPI_execute</function> does not update either the snapshot
   or the command counter, and it allows only plain <command>SELECT</command>
   commands to appear in the command string.  The commands are executed
   using the snapshot previously established for the surrounding query.
   This execution mode is somewhat faster than the read/write mode due
   to eliminating per-command overhead.  It also allows genuinely
   <firstterm>stable</firstterm> functions to be built: since successive executions
   will all use the same snapshot, there will be no change in the results.
  </para>

  <para>
   It is generally unwise to mix read-only and read-write commands within
   a single function using SPI; that could result in very confusing behavior,
   since the read-only queries would not see the results of any database
   updates done by the read-write queries.
  </para>

  <para>
   The actual number of rows for which the (last) command was executed
   is returned in the global variable <varname>SPI_processed</varname>.
   If the return value of the function is <symbol>SPI_OK_SELECT</symbol>,
   <symbol>SPI_OK_INSERT_RETURNING</symbol>,
   <symbol>SPI_OK_DELETE_RETURNING</symbol>,
   <symbol>SPI_OK_UPDATE_RETURNING</symbol>, or
   <symbol>SPI_OK_MERGE_RETURNING</symbol>,
   then you can use the
   global pointer <literal>SPITupleTable *SPI_tuptable</literal> to
   access the result rows.  Some utility commands (such as
   <command>EXPLAIN</command>) also return row sets, and <literal>SPI_tuptable</literal>
   will contain the result in these cases too. Some utility commands
   (<command>COPY</command>, <command>CREATE TABLE AS</command>) don't return a row set, so
   <literal>SPI_tuptable</literal> is NULL, but they still return the number of
   rows processed in <varname>SPI_processed</varname>.
  </para>

  <para>
   The structure <structname>SPITupleTable</structname> is defined
   thus:
<programlisting>
typedef struct SPITupleTable
{
    /* Public members */
    TupleDesc   tupdesc;        /* tuple descriptor */
    HeapTuple  *vals;           /* array of tuples */
    uint64      numvals;        /* number of valid tuples */

    /* Private members, not intended for external callers */
    uint64      alloced;        /* allocated length of vals array */
    MemoryContext tuptabcxt;    /* memory context of result table */
    slist_node  next;           /* link for internal bookkeeping */
    SubTransactionId subid;     /* subxact in which tuptable was created */
} SPITupleTable;
</programlisting>
   The fields <structfield>tupdesc</structfield>,
   <structfield>vals</structfield>, and
   <structfield>numvals</structfield>
   can be used by SPI callers; the remaining fields are internal.
   <structfield>vals</structfield> is an array of pointers to rows.
   The number of rows is given by <structfield>numvals</structfield>
   (for somewhat historical reasons, this count is also returned
   in <varname>SPI_processed</varname>).
   <structfield>tupdesc</structfield> is a row descriptor which you can pass to
   SPI functions dealing with rows.
  </para>

  <para>
   <function>SPI_finish</function> frees all
   <structname>SPITupleTable</structname>s allocated during the current
   C function.  You can free a particular result table earlier, if you
   are done with it, by calling <function>SPI_freetuptable</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      string containing command to execute
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   If the execution of the command was successful then one of the
   following (nonnegative) values will be returned:

   <variablelist>
    <varlistentry>
     <term><symbol>SPI_OK_SELECT</symbol></term>
     <listitem>
      <para>
       if a <command>SELECT</command> (but not <command>SELECT
       INTO</command>) was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_SELINTO</symbol></term>
     <listitem>
      <para>
       if a <command>SELECT INTO</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_INSERT</symbol></term>
     <listitem>
      <para>
       if an <command>INSERT</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_DELETE</symbol></term>
     <listitem>
      <para>
       if a <command>DELETE</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_UPDATE</symbol></term>
     <listitem>
      <para>
       if an <command>UPDATE</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_MERGE</symbol></term>
     <listitem>
      <para>
       if a <command>MERGE</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_INSERT_RETURNING</symbol></term>
     <listitem>
      <para>
       if an <command>INSERT RETURNING</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_DELETE_RETURNING</symbol></term>
     <listitem>
      <para>
       if a <command>DELETE RETURNING</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_UPDATE_RETURNING</symbol></term>
     <listitem>
      <para>
       if an <command>UPDATE RETURNING</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_MERGE_RETURNING</symbol></term>
     <listitem>
      <para>
       if a <command>MERGE RETURNING</command> was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_UTILITY</symbol></term>
     <listitem>
      <para>
       if a utility command (e.g., <command>CREATE TABLE</command>)
       was executed
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_OK_REWRITTEN</symbol></term>
     <listitem>
      <para>
       if the command was rewritten into another kind of command (e.g.,
       <command>UPDATE</command> became an <command>INSERT</command>) by a <link linkend="rules">rule</link>.
      </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>command</parameter> is <symbol>NULL</symbol> or
       <parameter>count</parameter> is less than 0
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_COPY</symbol></term>
     <listitem>
      <para>
       if <command>COPY TO stdout</command> or <command>COPY FROM stdin</command>
       was attempted
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_TRANSACTION</symbol></term>
     <listitem>
      <para>
       if a transaction manipulation command was attempted
       (<command>BEGIN</command>,
       <command>COMMIT</command>,
       <command>ROLLBACK</command>,
       <command>SAVEPOINT</command>,
       <command>PREPARE TRANSACTION</command>,
       <command>COMMIT PREPARED</command>,
       <command>ROLLBACK PREPARED</command>,
       or any variant thereof)
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_OPUNKNOWN</symbol></term>
     <listitem>
      <para>
       if the command type is unknown (shouldn't happen)
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
     <listitem>
      <para>
       if called from an unconnected C function
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   All SPI query-execution functions set both
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> (just the pointer, not the contents
   of the structure).  Save these two global variables into local
   C function variables if you need to access the result table of
   <function>SPI_execute</function> or another query-execution function
   across later calls.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-exec">
 <indexterm><primary>SPI_exec</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_exec</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_exec</refname>
  <refpurpose>execute a read/write command</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_exec(const char * <parameter>command</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_exec</function> is the same as
   <function>SPI_execute</function>, with the latter's
   <parameter>read_only</parameter> parameter always taken as
   <literal>false</literal>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      string containing command to execute
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   See <function>SPI_execute</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execute-extended">
 <indexterm><primary>SPI_execute_extended</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execute_extended</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execute_extended</refname>
  <refpurpose>execute a command with out-of-line parameters</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execute_extended(const char *<parameter>command</parameter>,
                         const SPIExecuteOptions * <parameter>options</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execute_extended</function> executes a command that might
   include references to externally supplied parameters.  The command text
   refers to a parameter as <literal>$<replaceable>n</replaceable></literal>,
   and the <parameter>options-&amp;gt;params</parameter> object (if supplied)
   provides values and type information for each such symbol.
   Various execution options can be specified
   in the <parameter>options</parameter> struct, too.
  </para>

  <para>
   The <parameter>options-&amp;gt;params</parameter> object should normally
   mark each parameter with the <literal>PARAM_FLAG_CONST</literal> flag,
   since a one-shot plan is always used for the query.
  </para>

  <para>
   If <parameter>options-&amp;gt;dest</parameter> is not NULL, then result
   tuples are passed to that object as they are generated by the executor,
   instead of being accumulated in <varname>SPI_tuptable</varname>.  Using
   a caller-supplied <literal>DestReceiver</literal> object is particularly
   helpful for queries that might generate many tuples, since the data can
   be processed on-the-fly instead of being accumulated in memory.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const SPIExecuteOptions * <parameter>options</parameter></literal></term>
    <listitem>
     <para>
      struct containing optional arguments
     </para>
    </listitem>
   </varlistentry>
  </variablelist>

  <para>
   Callers should always zero out the entire <parameter>options</parameter>
   struct, then fill whichever fields they want to set.  This ensures forward
   compatibility of code, since any fields that are added to the struct in
   future will be defined to behave backwards-compatibly if they are zero.
   The currently available <parameter>options</parameter> fields are:
  </para>

  <variablelist>
   <varlistentry>
    <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
    <listitem>
     <para>
      data structure containing query parameter types and values; NULL if none
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>allow_nonatomic</parameter></literal></term>
    <listitem>
     <para>
      <literal>true</literal> allows non-atomic execution of CALL and DO
      statements (but this field is ignored unless
      the <symbol>SPI_OPT_NONATOMIC</symbol> flag was passed
      to <function>SPI_connect_ext</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>must_return_tuples</parameter></literal></term>
    <listitem>
     <para>
      if <literal>true</literal>, raise error if the query is not of a kind
      that returns tuples (this does not forbid the case where it happens to
      return zero tuples)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>uint64 <parameter>tcount</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>DestReceiver * <parameter>dest</parameter></literal></term>
    <listitem>
     <para>
      <literal>DestReceiver</literal> object that will receive any tuples
      emitted by the query; if NULL, result tuples are accumulated into
      a <varname>SPI_tuptable</varname> structure, as
      in <function>SPI_execute</function>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>ResourceOwner <parameter>owner</parameter></literal></term>
    <listitem>
     <para>
      This field is present for consistency
      with <function>SPI_execute_plan_extended</function>, but it is
      ignored, since the plan used
      by <function>SPI_execute_extended</function> is never saved.
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The return value is the same as for <function>SPI_execute</function>.
  </para>

  <para>
   When <parameter>options-&amp;gt;dest</parameter> is NULL,
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute</function>.
   When <parameter>options-&amp;gt;dest</parameter> is not NULL,
   <varname>SPI_processed</varname> is set to zero and
   <varname>SPI_tuptable</varname> is set to NULL.  If a tuple count
   is required, the caller's <literal>DestReceiver</literal> object must
   calculate it.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execute-with-args">
 <indexterm><primary>SPI_execute_with_args</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execute_with_args</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execute_with_args</refname>
  <refpurpose>execute a command with out-of-line parameters</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execute_with_args(const char *<parameter>command</parameter>,
                          int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>,
                          Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>,
                          bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execute_with_args</function> executes a command that might
   include references to externally supplied parameters.  The command text
   refers to a parameter as <literal>$<replaceable>n</replaceable></literal>, and
   the call specifies data types and values for each such symbol.
   <parameter>read_only</parameter> and <parameter>count</parameter> have
   the same interpretation as in <function>SPI_execute</function>.
  </para>

  <para>
   The main advantage of this routine compared to
   <function>SPI_execute</function> is that data values can be inserted
   into the command without tedious quoting/escaping, and thus with much
   less risk of SQL-injection attacks.
  </para>

  <para>
   Similar results can be achieved with <function>SPI_prepare</function> followed by
   <function>SPI_execute_plan</function>; however, when using this function
   the query plan is always customized to the specific parameter values
   provided.
   For one-time query execution, this function should be preferred.
   If the same command is to be executed with many different parameters,
   either method might be faster, depending on the cost of re-planning
   versus the benefit of custom plans.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>nargs</parameter></literal></term>
    <listitem>
     <para>
      number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>nargs</parameter>, containing the
      <acronym>OID</acronym>s of the data types of the parameters
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Datum * <parameter>values</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>nargs</parameter>, containing the actual
      parameter values
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>nulls</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>nargs</parameter>, describing which
      parameters are null
     </para>

     <para>
      If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
      <function>SPI_execute_with_args</function> assumes that no parameters
      are null.  Otherwise, each entry of the <parameter>nulls</parameter>
      array should be <literal>'&amp;nbsp;'</literal> if the corresponding parameter
      value is non-null, or <literal>'n'</literal> if the corresponding parameter
      value is null.  (In the latter case, the actual value in the
      corresponding <parameter>values</parameter> entry doesn't matter.)  Note
      that <parameter>nulls</parameter> is not a text string, just an array:
      it does not need a <literal>'\0'</literal> terminator.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The return value is the same as for <function>SPI_execute</function>.
  </para>

  <para>
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute</function> if successful.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-prepare">
 <indexterm><primary>SPI_prepare</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_prepare</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_prepare</refname>
  <refpurpose>prepare a statement, without executing it yet</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
SPIPlanPtr SPI_prepare(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>, Oid * <parameter>argtypes</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_prepare</function> creates and returns a prepared
   statement for the specified command, but doesn't execute the command.
   The prepared statement can later be executed repeatedly using
   <function>SPI_execute_plan</function>.
  </para>

  <para>
   When the same or a similar command is to be executed repeatedly, it
   is generally advantageous to perform parse analysis only once, and
   might furthermore be advantageous to re-use an execution plan for the
   command.
   <function>SPI_prepare</function> converts a command string into a
   prepared statement that encapsulates the results of parse analysis.
   The prepared statement also provides a place for caching an execution plan
   if it is found that generating a custom plan for each execution is not
   helpful.
  </para>

  <para>
   A prepared command can be generalized by writing parameters
   (<literal>$1</literal>, <literal>$2</literal>, etc.) in place of what would be
   constants in a normal command.  The actual values of the parameters
   are then specified when <function>SPI_execute_plan</function> is called.
   This allows the prepared command to be used over a wider range of
   situations than would be possible without parameters.
  </para>

  <para>
   The statement returned by <function>SPI_prepare</function> can be used
   only in the current invocation of the C function, since
   <function>SPI_finish</function> frees memory allocated for such a
   statement.  But the statement can be saved for longer using the functions
   <function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>nargs</parameter></literal></term>
    <listitem>
     <para>
      number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
    <listitem>
     <para>
      pointer to an array containing the <acronym>OID</acronym>s of
      the data types of the parameters
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <function>SPI_prepare</function> returns a non-null pointer to an
   <type>SPIPlan</type>, which is an opaque struct representing a prepared
   statement.  On error, <symbol>NULL</symbol> will be returned,
   and <varname>SPI_result</varname> will be set to one of the same
   error codes used by <function>SPI_execute</function>, except that
   it is set to <symbol>SPI_ERROR_ARGUMENT</symbol> if
   <parameter>command</parameter> is <symbol>NULL</symbol>, or if
   <parameter>nargs</parameter> is less than 0, or if <parameter>nargs</parameter> is
   greater than 0 and <parameter>argtypes</parameter> is <symbol>NULL</symbol>.
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   If no parameters are defined, a generic plan will be created at the
   first use of <function>SPI_execute_plan</function>, and used for all
   subsequent executions as well.  If there are parameters, the first few uses
   of <function>SPI_execute_plan</function> will generate custom plans
   that are specific to the supplied parameter values.  After enough uses
   of the same prepared statement, <function>SPI_execute_plan</function> will
   build a generic plan, and if that is not too much more expensive than the
   custom plans, it will start using the generic plan instead of re-planning
   each time.  If this default behavior is unsuitable, you can alter it by
   passing the <literal>CURSOR_OPT_GENERIC_PLAN</literal> or
   <literal>CURSOR_OPT_CUSTOM_PLAN</literal> flag to
   <function>SPI_prepare_cursor</function>, to force use of generic or custom
   plans respectively.
  </para>

  <para>
   Although the main point of a prepared statement is to avoid repeated parse
   analysis and planning of the statement, <productname>PostgreSQL</productname> will
   force re-analysis and re-planning of the statement before using it
   whenever database objects used in the statement have undergone
   definitional (DDL) changes since the previous use of the prepared
   statement.  Also, if the value of <xref linkend="guc-search-path"/> changes
   from one use to the next, the statement will be re-parsed using the new
   <varname>search_path</varname>.  (This latter behavior is new as of
   <productname>PostgreSQL</productname> 9.3.)  See <xref
   linkend="sql-prepare"/> for more information about the behavior of prepared
   statements.
  </para>

  <para>
   This function should only be called from a connected C function.
  </para>

  <para>
   <type>SPIPlanPtr</type> is declared as a pointer to an opaque struct type in
   <filename>spi.h</filename>.  It is unwise to try to access its contents
   directly, as that makes your code much more likely to break in
   future revisions of <productname>PostgreSQL</productname>.
  </para>

  <para>
   The name <type>SPIPlanPtr</type> is somewhat historical, since the data
   structure no longer necessarily contains an execution plan.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-prepare-cursor">
 <indexterm><primary>SPI_prepare_cursor</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_prepare_cursor</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_prepare_cursor</refname>
  <refpurpose>prepare a statement, without executing it yet</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
SPIPlanPtr SPI_prepare_cursor(const char * <parameter>command</parameter>, int <parameter>nargs</parameter>,
                              Oid * <parameter>argtypes</parameter>, int <parameter>cursorOptions</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_prepare_cursor</function> is identical to
   <function>SPI_prepare</function>, except that it also allows specification
   of the planner's <quote>cursor options</quote> parameter.  This is a bit mask
   having the values shown in <filename>nodes/parsenodes.h</filename>
   for the <structfield>options</structfield> field of <structname>DeclareCursorStmt</structname>.
   <function>SPI_prepare</function> always takes the cursor options as zero.
  </para>

  <para>
   This function is now deprecated in favor
   of <function>SPI_prepare_extended</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>nargs</parameter></literal></term>
    <listitem>
     <para>
      number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
    <listitem>
     <para>
      pointer to an array containing the <acronym>OID</acronym>s of
      the data types of the parameters
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>cursorOptions</parameter></literal></term>
    <listitem>
     <para>
      integer bit mask of cursor options; zero produces default behavior
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <function>SPI_prepare_cursor</function> has the same return conventions as
   <function>SPI_prepare</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   Useful bits to set in <parameter>cursorOptions</parameter> include
   <symbol>CURSOR_OPT_SCROLL</symbol>,
   <symbol>CURSOR_OPT_NO_SCROLL</symbol>,
   <symbol>CURSOR_OPT_FAST_PLAN</symbol>,
   <symbol>CURSOR_OPT_GENERIC_PLAN</symbol>, and
   <symbol>CURSOR_OPT_CUSTOM_PLAN</symbol>.  Note in particular that
   <symbol>CURSOR_OPT_HOLD</symbol> is ignored.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-prepare-extended">
 <indexterm><primary>SPI_prepare_extended</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_prepare_extended</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_prepare_extended</refname>
  <refpurpose>prepare a statement, without executing it yet</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
SPIPlanPtr SPI_prepare_extended(const char * <parameter>command</parameter>,
                                const SPIPrepareOptions * <parameter>options</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_prepare_extended</function> creates and returns a prepared
   statement for the specified command, but doesn't execute the command.
   This function is equivalent to <function>SPI_prepare</function>,
   with the addition that the caller can specify options to control
   the parsing of external parameter references, as well as other facets
   of query parsing and planning.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const SPIPrepareOptions * <parameter>options</parameter></literal></term>
    <listitem>
     <para>
      struct containing optional arguments
     </para>
    </listitem>
   </varlistentry>
  </variablelist>

  <para>
   Callers should always zero out the entire <parameter>options</parameter>
   struct, then fill whichever fields they want to set.  This ensures forward
   compatibility of code, since any fields that are added to the struct in
   future will be defined to behave backwards-compatibly if they are zero.
   The currently available <parameter>options</parameter> fields are:
  </para>

  <variablelist>
   <varlistentry>
    <term><literal>ParserSetupHook <parameter>parserSetup</parameter></literal></term>
    <listitem>
     <para>
      Parser hook setup function
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>void * <parameter>parserSetupArg</parameter></literal></term>
    <listitem>
     <para>
      pass-through argument for <parameter>parserSetup</parameter>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>RawParseMode <parameter>parseMode</parameter></literal></term>
    <listitem>
     <para>
      mode for raw parsing; <literal>RAW_PARSE_DEFAULT</literal> (zero)
      produces default behavior
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>cursorOptions</parameter></literal></term>
    <listitem>
     <para>
      integer bit mask of cursor options; zero produces default behavior
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <function>SPI_prepare_extended</function> has the same return conventions as
   <function>SPI_prepare</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-prepare-params">
 <indexterm><primary>SPI_prepare_params</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_prepare_params</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_prepare_params</refname>
  <refpurpose>prepare a statement, without executing it yet</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
SPIPlanPtr SPI_prepare_params(const char * <parameter>command</parameter>,
                              ParserSetupHook <parameter>parserSetup</parameter>,
                              void * <parameter>parserSetupArg</parameter>,
                              int <parameter>cursorOptions</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_prepare_params</function> creates and returns a prepared
   statement for the specified command, but doesn't execute the command.
   This function is equivalent to <function>SPI_prepare_cursor</function>,
   with the addition that the caller can specify parser hook functions
   to control the parsing of external parameter references.
  </para>

  <para>
   This function is now deprecated in favor
   of <function>SPI_prepare_extended</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>ParserSetupHook <parameter>parserSetup</parameter></literal></term>
    <listitem>
     <para>
      Parser hook setup function
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>void * <parameter>parserSetupArg</parameter></literal></term>
    <listitem>
     <para>
      pass-through argument for <parameter>parserSetup</parameter>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>cursorOptions</parameter></literal></term>
    <listitem>
     <para>
      integer bit mask of cursor options; zero produces default behavior
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <function>SPI_prepare_params</function> has the same return conventions as
   <function>SPI_prepare</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-getargcount">
 <indexterm><primary>SPI_getargcount</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_getargcount</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_getargcount</refname>
  <refpurpose>return the number of arguments needed by a statement
  prepared by <function>SPI_prepare</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_getargcount(SPIPlanPtr <parameter>plan</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_getargcount</function> returns the number of arguments needed
   to execute a statement prepared by <function>SPI_prepare</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>
  <para>
    The count of expected arguments for the <parameter>plan</parameter>.
    If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
    <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
    and -1 is returned.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-getargtypeid">
 <indexterm><primary>SPI_getargtypeid</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_getargtypeid</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_getargtypeid</refname>
  <refpurpose>return the data type OID for an argument of
  a statement prepared by <function>SPI_prepare</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Oid SPI_getargtypeid(SPIPlanPtr <parameter>plan</parameter>, int <parameter>argIndex</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_getargtypeid</function> returns the OID representing the type
   for the <parameter>argIndex</parameter>'th argument of a statement prepared by
   <function>SPI_prepare</function>. First argument is at index zero.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>argIndex</parameter></literal></term>
    <listitem>
     <para>
      zero based index of the argument
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>
  <para>
    The type OID of the argument at the given index.
    If the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
    or <parameter>argIndex</parameter> is less than 0 or
    not less than the number of arguments declared for the
    <parameter>plan</parameter>,
    <varname>SPI_result</varname> is set to <symbol>SPI_ERROR_ARGUMENT</symbol>
    and <symbol>InvalidOid</symbol> is returned.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-is-cursor-plan">
 <indexterm><primary>SPI_is_cursor_plan</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_is_cursor_plan</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_is_cursor_plan</refname>
  <refpurpose>return <symbol>true</symbol> if a statement
  prepared by <function>SPI_prepare</function> can be used with
  <function>SPI_cursor_open</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
bool SPI_is_cursor_plan(SPIPlanPtr <parameter>plan</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_is_cursor_plan</function> returns <symbol>true</symbol>
   if a statement prepared by <function>SPI_prepare</function> can be passed
   as an argument to <function>SPI_cursor_open</function>, or
   <symbol>false</symbol> if that is not the case. The criteria are that the
   <parameter>plan</parameter> represents one single command and that this
   command returns tuples to the caller; for example, <command>SELECT</command>
   is allowed unless it contains an <literal>INTO</literal> clause, and
   <command>UPDATE</command> is allowed only if it contains a <literal>RETURNING</literal>
   clause.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>
  <para>
    <symbol>true</symbol> or <symbol>false</symbol> to indicate if the
    <parameter>plan</parameter> can produce a cursor or not, with
    <varname>SPI_result</varname> set to zero.
    If it is not possible to determine the answer (for example,
    if the <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
    or if called when not connected to SPI), then
    <varname>SPI_result</varname> is set to a suitable error code
    and <symbol>false</symbol> is returned.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execute-plan">
 <indexterm><primary>SPI_execute_plan</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execute_plan</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execute_plan</refname>
  <refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execute_plan(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
                     bool <parameter>read_only</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execute_plan</function> executes a statement prepared by
   <function>SPI_prepare</function> or one of its siblings.
   <parameter>read_only</parameter> and
   <parameter>count</parameter> have the same interpretation as in
   <function>SPI_execute</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Datum * <parameter>values</parameter></literal></term>
    <listitem>
     <para>
      An array of actual parameter values.  Must have same length as the
      statement's number of arguments.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>nulls</parameter></literal></term>
    <listitem>
     <para>
      An array describing which parameters are null.  Must have same length as
      the statement's number of arguments.
     </para>

     <para>
      If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
      <function>SPI_execute_plan</function> assumes that no parameters
      are null.  Otherwise, each entry of the <parameter>nulls</parameter>
      array should be <literal>'&amp;nbsp;'</literal> if the corresponding parameter
      value is non-null, or <literal>'n'</literal> if the corresponding parameter
      value is null.  (In the latter case, the actual value in the
      corresponding <parameter>values</parameter> entry doesn't matter.)  Note
      that <parameter>nulls</parameter> is not a text string, just an array:
      it does not need a <literal>'\0'</literal> terminator.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The return value is the same as for <function>SPI_execute</function>,
   with the following additional possible error (negative) results:

   <variablelist>
    <varlistentry>
     <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
     <listitem>
      <para>
       if <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid,
       or <parameter>count</parameter> is less than 0
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_PARAM</symbol></term>
     <listitem>
      <para>
       if <parameter>values</parameter> is <symbol>NULL</symbol> and
       <parameter>plan</parameter> was prepared with some parameters
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>

  <para>
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute</function> if successful.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execute-plan-extended">
 <indexterm><primary>SPI_execute_plan_extended</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execute_plan_extended</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execute_plan_extended</refname>
  <refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execute_plan_extended(SPIPlanPtr <parameter>plan</parameter>,
                              const SPIExecuteOptions * <parameter>options</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execute_plan_extended</function> executes a statement
   prepared by <function>SPI_prepare</function> or one of its siblings.
   This function is equivalent to <function>SPI_execute_plan</function>,
   except that information about the parameter values to be passed to the
   query is presented differently, and additional execution-controlling
   options can be passed.
  </para>

  <para>
   Query parameter values are represented by
   a <literal>ParamListInfo</literal> struct, which is convenient for passing
   down values that are already available in that format.  Dynamic parameter
   sets can also be used, via hook functions specified
   in <literal>ParamListInfo</literal>.
  </para>

  <para>
   Also, instead of always accumulating the result tuples into a
   <varname>SPI_tuptable</varname> structure, tuples can be passed to a
   caller-supplied <literal>DestReceiver</literal> object as they are
   generated by the executor.  This is particularly helpful for queries
   that might generate many tuples, since the data can be processed
   on-the-fly instead of being accumulated in memory.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const SPIExecuteOptions * <parameter>options</parameter></literal></term>
    <listitem>
     <para>
      struct containing optional arguments
     </para>
    </listitem>
   </varlistentry>
  </variablelist>

  <para>
   Callers should always zero out the entire <parameter>options</parameter>
   struct, then fill whichever fields they want to set.  This ensures forward
   compatibility of code, since any fields that are added to the struct in
   future will be defined to behave backwards-compatibly if they are zero.
   The currently available <parameter>options</parameter> fields are:
  </para>

  <variablelist>
   <varlistentry>
    <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
    <listitem>
     <para>
      data structure containing query parameter types and values; NULL if none
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>allow_nonatomic</parameter></literal></term>
    <listitem>
     <para>
      <literal>true</literal> allows non-atomic execution of CALL and DO
      statements (but this field is ignored unless
      the <symbol>SPI_OPT_NONATOMIC</symbol> flag was passed
      to <function>SPI_connect_ext</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>must_return_tuples</parameter></literal></term>
    <listitem>
     <para>
      if <literal>true</literal>, raise error if the query is not of a kind
      that returns tuples (this does not forbid the case where it happens to
      return zero tuples)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>uint64 <parameter>tcount</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>DestReceiver * <parameter>dest</parameter></literal></term>
    <listitem>
     <para>
      <literal>DestReceiver</literal> object that will receive any tuples
      emitted by the query; if NULL, result tuples are accumulated into
      a <varname>SPI_tuptable</varname> structure, as
      in <function>SPI_execute_plan</function>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>ResourceOwner <parameter>owner</parameter></literal></term>
    <listitem>
     <para>
      The resource owner that will hold a reference count on the plan while
      it is executed.  If NULL, CurrentResourceOwner is used.  Ignored for
      non-saved plans, as SPI does not acquire reference counts on those.
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The return value is the same as for <function>SPI_execute_plan</function>.
  </para>

  <para>
   When <parameter>options-&amp;gt;dest</parameter> is NULL,
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute_plan</function>.
   When <parameter>options-&amp;gt;dest</parameter> is not NULL,
   <varname>SPI_processed</varname> is set to zero and
   <varname>SPI_tuptable</varname> is set to NULL.  If a tuple count
   is required, the caller's <literal>DestReceiver</literal> object must
   calculate it.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execute-plan-with-paramlist">
 <indexterm><primary>SPI_execute_plan_with_paramlist</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execute_plan_with_paramlist</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execute_plan_with_paramlist</refname>
  <refpurpose>execute a statement prepared by <function>SPI_prepare</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execute_plan_with_paramlist(SPIPlanPtr <parameter>plan</parameter>,
                                    ParamListInfo <parameter>params</parameter>,
                                    bool <parameter>read_only</parameter>,
                                    long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execute_plan_with_paramlist</function> executes a statement
   prepared by <function>SPI_prepare</function>.
   This function is equivalent to <function>SPI_execute_plan</function>
   except that information about the parameter values to be passed to the
   query is presented differently.  The <literal>ParamListInfo</literal>
   representation can be convenient for passing down values that are
   already available in that format.  It also supports use of dynamic
   parameter sets via hook functions specified in <literal>ParamListInfo</literal>.
  </para>

  <para>
   This function is now deprecated in favor
   of <function>SPI_execute_plan_extended</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
    <listitem>
     <para>
      data structure containing parameter types and values; NULL if none
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The return value is the same as for <function>SPI_execute_plan</function>.
  </para>

  <para>
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute_plan</function> if successful.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-execp">
 <indexterm><primary>SPI_execp</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_execp</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_execp</refname>
  <refpurpose>execute a statement in read/write mode</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_execp(SPIPlanPtr <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_execp</function> is the same as
   <function>SPI_execute_plan</function>, with the latter's
   <parameter>read_only</parameter> parameter always taken as
   <literal>false</literal>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Datum * <parameter>values</parameter></literal></term>
    <listitem>
     <para>
      An array of actual parameter values.  Must have same length as the
      statement's number of arguments.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>nulls</parameter></literal></term>
    <listitem>
     <para>
      An array describing which parameters are null.  Must have same length as
      the statement's number of arguments.
     </para>

     <para>
      If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
      <function>SPI_execp</function> assumes that no parameters
      are null.  Otherwise, each entry of the <parameter>nulls</parameter>
      array should be <literal>'&amp;nbsp;'</literal> if the corresponding parameter
      value is non-null, or <literal>'n'</literal> if the corresponding parameter
      value is null.  (In the latter case, the actual value in the
      corresponding <parameter>values</parameter> entry doesn't matter.)  Note
      that <parameter>nulls</parameter> is not a text string, just an array:
      it does not need a <literal>'\0'</literal> terminator.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to return,
      or <literal>0</literal> for no limit
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   See <function>SPI_execute_plan</function>.
  </para>

  <para>
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute</function> if successful.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-open">
 <indexterm><primary>SPI_cursor_open</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_open</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_open</refname>
  <refpurpose>set up a cursor using a statement created with <function>SPI_prepare</function></refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Portal SPI_cursor_open(const char * <parameter>name</parameter>, SPIPlanPtr <parameter>plan</parameter>,
                       Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>,
                       bool <parameter>read_only</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_open</function> sets up a cursor (internally,
   a portal) that will execute a statement prepared by
   <function>SPI_prepare</function>.  The parameters have the same
   meanings as the corresponding parameters to
   <function>SPI_execute_plan</function>.
  </para>

  <para>
   Using a cursor instead of executing the statement directly has two
   benefits.  First, the result rows can be retrieved a few at a time,
   avoiding memory overrun for queries that return many rows.  Second,
   a portal can outlive the current C function (it can, in fact, live
   to the end of the current transaction).  Returning the portal name
   to the C function's caller provides a way of returning a row set as
   result.
  </para>

  <para>
   The passed-in parameter data will be copied into the cursor's portal, so it
   can be freed while the cursor still exists.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>name</parameter></literal></term>
    <listitem>
     <para>
      name for portal, or <symbol>NULL</symbol> to let the system
      select a name
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Datum * <parameter>values</parameter></literal></term>
    <listitem>
     <para>
      An array of actual parameter values.  Must have same length as the
      statement's number of arguments.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>nulls</parameter></literal></term>
    <listitem>
     <para>
      An array describing which parameters are null.  Must have same length as
      the statement's number of arguments.
     </para>

     <para>
      If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
      <function>SPI_cursor_open</function> assumes that no parameters
      are null.  Otherwise, each entry of the <parameter>nulls</parameter>
      array should be <literal>'&amp;nbsp;'</literal> if the corresponding parameter
      value is non-null, or <literal>'n'</literal> if the corresponding parameter
      value is null.  (In the latter case, the actual value in the
      corresponding <parameter>values</parameter> entry doesn't matter.)  Note
      that <parameter>nulls</parameter> is not a text string, just an array:
      it does not need a <literal>'\0'</literal> terminator.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Pointer to portal containing the cursor.  Note there is no error
   return convention; any error will be reported via <function>elog</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-open-with-args">
 <indexterm><primary>SPI_cursor_open_with_args</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_open_with_args</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_open_with_args</refname>
  <refpurpose>set up a cursor using a query and parameters</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Portal SPI_cursor_open_with_args(const char *<parameter>name</parameter>,
                                 const char *<parameter>command</parameter>,
                                 int <parameter>nargs</parameter>, Oid *<parameter>argtypes</parameter>,
                                 Datum *<parameter>values</parameter>, const char *<parameter>nulls</parameter>,
                                 bool <parameter>read_only</parameter>, int <parameter>cursorOptions</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_open_with_args</function> sets up a cursor
   (internally, a portal) that will execute the specified query.
   Most of the parameters have the same meanings as the corresponding
   parameters to <function>SPI_prepare_cursor</function>
   and <function>SPI_cursor_open</function>.
  </para>

  <para>
   For one-time query execution, this function should be preferred
   over <function>SPI_prepare_cursor</function> followed by
   <function>SPI_cursor_open</function>.
   If the same command is to be executed with many different parameters,
   either method might be faster, depending on the cost of re-planning
   versus the benefit of custom plans.
  </para>

  <para>
   The passed-in parameter data will be copied into the cursor's portal, so it
   can be freed while the cursor still exists.
  </para>

  <para>
   This function is now deprecated in favor
   of <function>SPI_cursor_parse_open</function>, which provides equivalent
   functionality using a more modern API for handling query parameters.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>name</parameter></literal></term>
    <listitem>
     <para>
      name for portal, or <symbol>NULL</symbol> to let the system
      select a name
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>nargs</parameter></literal></term>
    <listitem>
     <para>
      number of input parameters (<literal>$1</literal>, <literal>$2</literal>, etc.)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Oid * <parameter>argtypes</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>nargs</parameter>, containing the
      <acronym>OID</acronym>s of the data types of the parameters
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Datum * <parameter>values</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>nargs</parameter>, containing the actual
      parameter values
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>nulls</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>nargs</parameter>, describing which
      parameters are null
     </para>

     <para>
      If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
      <function>SPI_cursor_open_with_args</function> assumes that no parameters
      are null.  Otherwise, each entry of the <parameter>nulls</parameter>
      array should be <literal>'&amp;nbsp;'</literal> if the corresponding parameter
      value is non-null, or <literal>'n'</literal> if the corresponding parameter
      value is null.  (In the latter case, the actual value in the
      corresponding <parameter>values</parameter> entry doesn't matter.)  Note
      that <parameter>nulls</parameter> is not a text string, just an array:
      it does not need a <literal>'\0'</literal> terminator.
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>cursorOptions</parameter></literal></term>
    <listitem>
     <para>
      integer bit mask of cursor options; zero produces default behavior
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Pointer to portal containing the cursor.  Note there is no error
   return convention; any error will be reported via <function>elog</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-open-with-paramlist">
 <indexterm><primary>SPI_cursor_open_with_paramlist</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_open_with_paramlist</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_open_with_paramlist</refname>
  <refpurpose>set up a cursor using parameters</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Portal SPI_cursor_open_with_paramlist(const char *<parameter>name</parameter>,
                                      SPIPlanPtr <parameter>plan</parameter>,
                                      ParamListInfo <parameter>params</parameter>,
                                      bool <parameter>read_only</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_open_with_paramlist</function> sets up a cursor
   (internally, a portal) that will execute a statement prepared by
   <function>SPI_prepare</function>.
   This function is equivalent to <function>SPI_cursor_open</function>
   except that information about the parameter values to be passed to the
   query is presented differently.  The <literal>ParamListInfo</literal>
   representation can be convenient for passing down values that are
   already available in that format.  It also supports use of dynamic
   parameter sets via hook functions specified in <literal>ParamListInfo</literal>.
  </para>

  <para>
   The passed-in parameter data will be copied into the cursor's portal, so it
   can be freed while the cursor still exists.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>name</parameter></literal></term>
    <listitem>
     <para>
      name for portal, or <symbol>NULL</symbol> to let the system
      select a name
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      prepared statement (returned by <function>SPI_prepare</function>)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
    <listitem>
     <para>
      data structure containing parameter types and values; NULL if none
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Pointer to portal containing the cursor.  Note there is no error
   return convention; any error will be reported via <function>elog</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-parse-open">
 <indexterm><primary>SPI_cursor_parse_open</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_parse_open</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_parse_open</refname>
  <refpurpose>set up a cursor using a query string and parameters</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Portal SPI_cursor_parse_open(const char *<parameter>name</parameter>,
                             const char *<parameter>command</parameter>,
                             const SPIParseOpenOptions * <parameter>options</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_parse_open</function> sets up a cursor
   (internally, a portal) that will execute the specified query string.
   This is comparable to <function>SPI_prepare_cursor</function> followed
   by <function>SPI_cursor_open_with_paramlist</function>, except that
   parameter references within the query string are handled entirely by
   supplying a <literal>ParamListInfo</literal> object.
  </para>

  <para>
   For one-time query execution, this function should be preferred
   over <function>SPI_prepare_cursor</function> followed by
   <function>SPI_cursor_open_with_paramlist</function>.
   If the same command is to be executed with many different parameters,
   either method might be faster, depending on the cost of re-planning
   versus the benefit of custom plans.
  </para>

  <para>
   The <parameter>options-&amp;gt;params</parameter> object should normally
   mark each parameter with the <literal>PARAM_FLAG_CONST</literal> flag,
   since a one-shot plan is always used for the query.
  </para>

  <para>
   The passed-in parameter data will be copied into the cursor's portal, so it
   can be freed while the cursor still exists.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>name</parameter></literal></term>
    <listitem>
     <para>
      name for portal, or <symbol>NULL</symbol> to let the system
      select a name
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>command</parameter></literal></term>
    <listitem>
     <para>
      command string
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const SPIParseOpenOptions * <parameter>options</parameter></literal></term>
    <listitem>
     <para>
      struct containing optional arguments
     </para>
    </listitem>
   </varlistentry>
  </variablelist>

  <para>
   Callers should always zero out the entire <parameter>options</parameter>
   struct, then fill whichever fields they want to set.  This ensures forward
   compatibility of code, since any fields that are added to the struct in
   future will be defined to behave backwards-compatibly if they are zero.
   The currently available <parameter>options</parameter> fields are:
  </para>

  <variablelist>
   <varlistentry>
    <term><literal>ParamListInfo <parameter>params</parameter></literal></term>
    <listitem>
     <para>
      data structure containing query parameter types and values; NULL if none
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>cursorOptions</parameter></literal></term>
    <listitem>
     <para>
      integer bit mask of cursor options; zero produces default behavior
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>read_only</parameter></literal></term>
    <listitem>
     <para><literal>true</literal> for read-only execution</para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Pointer to portal containing the cursor.  Note there is no error
   return convention; any error will be reported via <function>elog</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-find">
 <indexterm><primary>SPI_cursor_find</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_find</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_find</refname>
  <refpurpose>find an existing cursor by name</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Portal SPI_cursor_find(const char * <parameter>name</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_find</function> finds an existing portal by
   name.  This is primarily useful to resolve a cursor name returned
   as text by some other function.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>name</parameter></literal></term>
    <listitem>
     <para>
      name of the portal
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   pointer to the portal with the specified name, or
   <symbol>NULL</symbol> if none was found
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   Beware that this function can return a <type>Portal</type> object
   that does not have cursor-like properties; for example it might not
   return tuples.  If you simply pass the <type>Portal</type> pointer
   to other SPI functions, they can defend themselves against such
   cases, but caution is appropriate when directly inspecting
   the <type>Portal</type>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-fetch">
 <indexterm><primary>SPI_cursor_fetch</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_fetch</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_fetch</refname>
  <refpurpose>fetch some rows from a cursor</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_cursor_fetch(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_fetch</function> fetches some rows from a
   cursor.  This is equivalent to a subset of the SQL command
   <command>FETCH</command> (see <function>SPI_scroll_cursor_fetch</function>
   for more functionality).
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Portal <parameter>portal</parameter></literal></term>
    <listitem>
     <para>
      portal containing the cursor
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>forward</parameter></literal></term>
    <listitem>
     <para>
      true for fetch forward, false for fetch backward
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to fetch
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute</function> if successful.
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   Fetching backward may fail if the cursor's plan was not created
   with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-move">
 <indexterm><primary>SPI_cursor_move</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_move</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_move</refname>
  <refpurpose>move a cursor</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_cursor_move(Portal <parameter>portal</parameter>, bool <parameter>forward</parameter>, long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_move</function> skips over some number of rows
   in a cursor.  This is equivalent to a subset of the SQL command
   <command>MOVE</command> (see <function>SPI_scroll_cursor_move</function>
   for more functionality).
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Portal <parameter>portal</parameter></literal></term>
    <listitem>
     <para>
      portal containing the cursor
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool <parameter>forward</parameter></literal></term>
    <listitem>
     <para>
      true for move forward, false for move backward
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      maximum number of rows to move
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   Moving backward may fail if the cursor's plan was not created
   with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-scroll-cursor-fetch">
 <indexterm><primary>SPI_scroll_cursor_fetch</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_scroll_cursor_fetch</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_scroll_cursor_fetch</refname>
  <refpurpose>fetch some rows from a cursor</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_scroll_cursor_fetch(Portal <parameter>portal</parameter>, FetchDirection <parameter>direction</parameter>,
                             long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_scroll_cursor_fetch</function> fetches some rows from a
   cursor.  This is equivalent to the SQL command <command>FETCH</command>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Portal <parameter>portal</parameter></literal></term>
    <listitem>
     <para>
      portal containing the cursor
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>FetchDirection <parameter>direction</parameter></literal></term>
    <listitem>
     <para>
      one of <symbol>FETCH_FORWARD</symbol>,
      <symbol>FETCH_BACKWARD</symbol>,
      <symbol>FETCH_ABSOLUTE</symbol> or
      <symbol>FETCH_RELATIVE</symbol>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      number of rows to fetch for
      <symbol>FETCH_FORWARD</symbol> or
      <symbol>FETCH_BACKWARD</symbol>; absolute row number to fetch for
      <symbol>FETCH_ABSOLUTE</symbol>; or relative row number to fetch for
      <symbol>FETCH_RELATIVE</symbol>
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <varname>SPI_processed</varname> and
   <varname>SPI_tuptable</varname> are set as in
   <function>SPI_execute</function> if successful.
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   See the SQL <xref linkend="sql-fetch"/> command
   for details of the interpretation of the
   <parameter>direction</parameter> and
   <parameter>count</parameter> parameters.
  </para>

  <para>
   Direction values other than <symbol>FETCH_FORWARD</symbol>
   may fail if the cursor's plan was not created
   with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-scroll-cursor-move">
 <indexterm><primary>SPI_scroll_cursor_move</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_scroll_cursor_move</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_scroll_cursor_move</refname>
  <refpurpose>move a cursor</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_scroll_cursor_move(Portal <parameter>portal</parameter>, FetchDirection <parameter>direction</parameter>,
                            long <parameter>count</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_scroll_cursor_move</function> skips over some number of rows
   in a cursor.  This is equivalent to the SQL command
   <command>MOVE</command>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Portal <parameter>portal</parameter></literal></term>
    <listitem>
     <para>
      portal containing the cursor
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>FetchDirection <parameter>direction</parameter></literal></term>
    <listitem>
     <para>
      one of <symbol>FETCH_FORWARD</symbol>,
      <symbol>FETCH_BACKWARD</symbol>,
      <symbol>FETCH_ABSOLUTE</symbol> or
      <symbol>FETCH_RELATIVE</symbol>
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>long <parameter>count</parameter></literal></term>
    <listitem>
     <para>
      number of rows to move for
      <symbol>FETCH_FORWARD</symbol> or
      <symbol>FETCH_BACKWARD</symbol>; absolute row number to move to for
      <symbol>FETCH_ABSOLUTE</symbol>; or relative row number to move to for
      <symbol>FETCH_RELATIVE</symbol>
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <varname>SPI_processed</varname> is set as in
   <function>SPI_execute</function> if successful.
   <varname>SPI_tuptable</varname> is set to <symbol>NULL</symbol>, since
   no rows are returned by this function.
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   See the SQL <xref linkend="sql-fetch"/> command
   for details of the interpretation of the
   <parameter>direction</parameter> and
   <parameter>count</parameter> parameters.
  </para>

  <para>
   Direction values other than <symbol>FETCH_FORWARD</symbol>
   may fail if the cursor's plan was not created
   with the <symbol>CURSOR_OPT_SCROLL</symbol> option.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-cursor-close">
 <indexterm><primary>SPI_cursor_close</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_cursor_close</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_cursor_close</refname>
  <refpurpose>close a cursor</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_cursor_close(Portal <parameter>portal</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_cursor_close</function> closes a previously created
   cursor and releases its portal storage.
  </para>

  <para>
   All open cursors are closed automatically at the end of a
   transaction.  <function>SPI_cursor_close</function> need only be
   invoked if it is desirable to release resources sooner.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Portal <parameter>portal</parameter></literal></term>
    <listitem>
     <para>
      portal containing the cursor
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-keepplan">
 <indexterm><primary>SPI_keepplan</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_keepplan</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_keepplan</refname>
  <refpurpose>save a prepared statement</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_keepplan(SPIPlanPtr <parameter>plan</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_keepplan</function> saves a passed statement (prepared by
   <function>SPI_prepare</function>) so that it will not be freed
   by <function>SPI_finish</function> nor by the transaction manager.
   This gives you the ability to reuse prepared statements in the subsequent
   invocations of your C function in the current session.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      the prepared statement to be saved
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   0 on success;
   <symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
   is <symbol>NULL</symbol> or invalid
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   The passed-in statement is relocated to permanent storage by means
   of pointer adjustment (no data copying is required).  If you later
   wish to delete it, use <function>SPI_freeplan</function> on it.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-saveplan">
 <indexterm><primary>SPI_saveplan</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_saveplan</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_saveplan</refname>
  <refpurpose>save a prepared statement</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
SPIPlanPtr SPI_saveplan(SPIPlanPtr <parameter>plan</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_saveplan</function> copies a passed statement (prepared by
   <function>SPI_prepare</function>) into memory that will not be freed
   by <function>SPI_finish</function> nor by the transaction manager,
   and returns a pointer to the copied statement.  This gives you the
   ability to reuse prepared statements in the subsequent invocations of
   your C function in the current session.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      the prepared statement to be saved
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Pointer to the copied statement; or <symbol>NULL</symbol> if unsuccessful.
   On error, <varname>SPI_result</varname> is set thus:

   <variablelist>
    <varlistentry>
     <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
     <listitem>
      <para>
       if <parameter>plan</parameter> is <symbol>NULL</symbol> or invalid
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
     <listitem>
      <para>
       if called from an unconnected C function
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>

 <refsect1>
  <title>Notes</title>

  <para>
   The originally passed-in statement is not freed, so you might wish to do
   <function>SPI_freeplan</function> on it to avoid leaking memory
   until <function>SPI_finish</function>.
  </para>

  <para>
   In most cases, <function>SPI_keepplan</function> is preferred to this
   function, since it accomplishes largely the same result without needing
   to physically copy the prepared statement's data structures.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<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>
 </refmeta>

 <refnamediv>
  <refname>SPI_register_relation</refname>
  <refpurpose>make an ephemeral named relation available by name in SPI queries</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_register_relation(EphemeralNamedRelation <parameter>enr</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_register_relation</function> makes an ephemeral named
   relation, with associated information, available to queries planned and
   executed through the current SPI connection.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>EphemeralNamedRelation <parameter>enr</parameter></literal></term>
    <listitem>
     <para>
      the ephemeral named relation registry entry
     </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_REL_REGISTER</symbol></term>
     <listitem>
      <para>
       if the relation has been successfully registered by name
      </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>enr</parameter> is <symbol>NULL</symbol> or its
       <varname>name</varname> field is <symbol>NULL</symbol>
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
     <listitem>
      <para>
       if called from an unconnected C function
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_REL_DUPLICATE</symbol></term>
     <listitem>
      <para>
       if the name specified in the <varname>name</varname> field of
       <parameter>enr</parameter> is already registered for this connection
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<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>
 </refmeta>

 <refnamediv>
  <refname>SPI_unregister_relation</refname>
  <refpurpose>remove an ephemeral named relation from the registry</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_unregister_relation(const char * <parameter>name</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_unregister_relation</function> removes an ephemeral named
   relation from the registry for the current connection.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>const char * <parameter>name</parameter></literal></term>
    <listitem>
     <para>
      the relation registry entry name
     </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_REL_UNREGISTER</symbol></term>
     <listitem>
      <para>
       if the tuplestore has been successfully removed from the registry
      </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>name</parameter> is <symbol>NULL</symbol>
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
     <listitem>
      <para>
       if called from an unconnected C function
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_REL_NOT_FOUND</symbol></term>
     <listitem>
      <para>
       if <parameter>name</parameter> is not found in the registry for the
       current connection
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<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 C function
      </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">
 <title>Interface Support Functions</title>

 <para>
  The functions described here provide an interface for extracting
  information from result sets returned by <function>SPI_execute</function> and
  other SPI functions.
 </para>

 <para>
  All functions described in this section can be used by both
  connected and unconnected C functions.
 </para>

<!-- *********************************************** -->

<refentry id="spi-spi-fname">
 <indexterm><primary>SPI_fname</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_fname</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_fname</refname>
  <refpurpose>determine the column name for the specified column number</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
char * SPI_fname(TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_fname</function> returns a copy of the column name of the
   specified column.  (You can use <function>pfree</function> to
   release the copy of the name when you don't need it anymore.)
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      input row description
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>colnumber</parameter></literal></term>
    <listitem>
     <para>
      column number (count starts at 1)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The column name; <symbol>NULL</symbol> if
   <parameter>colnumber</parameter> is out of range.
   <varname>SPI_result</varname> set to
   <symbol>SPI_ERROR_NOATTRIBUTE</symbol> on error.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-fnumber">
 <indexterm><primary>SPI_fnumber</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_fnumber</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_fnumber</refname>
  <refpurpose>determine the column number for the specified column name</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_fnumber(TupleDesc <parameter>rowdesc</parameter>, const char * <parameter>colname</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_fnumber</function> returns the column number for the
   column with the specified name.
  </para>

  <para>
   If <parameter>colname</parameter> refers to a system column (e.g.,
   <literal>ctid</literal>) then the appropriate negative column number will
   be returned.  The caller should be careful to test the return value
   for exact equality to <symbol>SPI_ERROR_NOATTRIBUTE</symbol> to
   detect an error; testing the result for less than or equal to 0 is
   not correct unless system columns should be rejected.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      input row description
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>colname</parameter></literal></term>
    <listitem>
     <para>
      column name
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Column number (count starts at 1 for user-defined columns), or
   <symbol>SPI_ERROR_NOATTRIBUTE</symbol> if the named column was not
   found.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-getvalue">
 <indexterm><primary>SPI_getvalue</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_getvalue</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_getvalue</refname>
  <refpurpose>return the string value of the specified column</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
char * SPI_getvalue(HeapTuple <parameter>row</parameter>, TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_getvalue</function> returns the string representation
   of the value of the specified column.
  </para>

  <para>
   The result is returned in memory allocated using
   <function>palloc</function>.  (You can use
   <function>pfree</function> to release the memory when you don't
   need it anymore.)
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>HeapTuple <parameter>row</parameter></literal></term>
    <listitem>
     <para>
      input row to be examined
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      input row description
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>colnumber</parameter></literal></term>
    <listitem>
     <para>
      column number (count starts at 1)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   Column value, or <symbol>NULL</symbol> if the column is null,
   <parameter>colnumber</parameter> is out of range
   (<varname>SPI_result</varname> is set to
   <symbol>SPI_ERROR_NOATTRIBUTE</symbol>), or no output function is
   available (<varname>SPI_result</varname> is set to
   <symbol>SPI_ERROR_NOOUTFUNC</symbol>).
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-getbinval">
 <indexterm><primary>SPI_getbinval</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_getbinval</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_getbinval</refname>
  <refpurpose>return the binary value of the specified column</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Datum SPI_getbinval(HeapTuple <parameter>row</parameter>, TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>,
                    bool * <parameter>isnull</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_getbinval</function> returns the value of the
   specified column in the internal form (as type <type>Datum</type>).
  </para>

  <para>
   This function does not allocate new space for the datum.  In the
   case of a pass-by-reference data type, the return value will be a
   pointer into the passed row.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>HeapTuple <parameter>row</parameter></literal></term>
    <listitem>
     <para>
      input row to be examined
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      input row description
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>colnumber</parameter></literal></term>
    <listitem>
     <para>
      column number (count starts at 1)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>bool * <parameter>isnull</parameter></literal></term>
    <listitem>
     <para>
      flag for a null value in the column
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The binary value of the column is returned.  The variable pointed
   to by <parameter>isnull</parameter> is set to true if the column is
   null, else to false.
  </para>

  <para>
   <varname>SPI_result</varname> is set to
   <symbol>SPI_ERROR_NOATTRIBUTE</symbol> on error.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-gettype">
 <indexterm><primary>SPI_gettype</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_gettype</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_gettype</refname>
  <refpurpose>return the data type name of the specified column</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
char * SPI_gettype(TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_gettype</function> returns a copy of the data type name of the
   specified column.  (You can use <function>pfree</function> to
   release the copy of the name when you don't need it anymore.)
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      input row description
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>colnumber</parameter></literal></term>
    <listitem>
     <para>
      column number (count starts at 1)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The data type name of the specified column, or
   <symbol>NULL</symbol> on error.  <varname>SPI_result</varname> is
   set to <symbol>SPI_ERROR_NOATTRIBUTE</symbol> on error.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-gettypeid">
 <indexterm><primary>SPI_gettypeid</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_gettypeid</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_gettypeid</refname>
  <refpurpose>return the data type <acronym>OID</acronym> of the specified column</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
Oid SPI_gettypeid(TupleDesc <parameter>rowdesc</parameter>, int <parameter>colnumber</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_gettypeid</function> returns the
   <acronym>OID</acronym> of the data type of the specified column.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      input row description
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>colnumber</parameter></literal></term>
    <listitem>
     <para>
      column number (count starts at 1)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The <acronym>OID</acronym> of the data type of the specified column
   or <symbol>InvalidOid</symbol> on error.  On error,
   <varname>SPI_result</varname> is set to
   <symbol>SPI_ERROR_NOATTRIBUTE</symbol>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-getrelname">
 <indexterm><primary>SPI_getrelname</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_getrelname</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_getrelname</refname>
  <refpurpose>return the name of the specified relation</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
char * SPI_getrelname(Relation <parameter>rel</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_getrelname</function> returns a copy of the name of the
   specified relation.  (You can use <function>pfree</function> to
   release the copy of the name when you don't need it anymore.)
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Relation <parameter>rel</parameter></literal></term>
    <listitem>
     <para>
      input relation
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The name of the specified relation.
  </para>
 </refsect1>
</refentry>

<refentry id="spi-spi-getnspname">
 <indexterm><primary>SPI_getnspname</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_getnspname</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_getnspname</refname>
  <refpurpose>return the namespace of the specified relation</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
char * SPI_getnspname(Relation <parameter>rel</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_getnspname</function> returns a copy of the name of
   the namespace that the specified <structname>Relation</structname>
   belongs to. This is equivalent to the relation's schema. You should
   <function>pfree</function> the return value of this function when
   you are finished with it.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Relation <parameter>rel</parameter></literal></term>
    <listitem>
     <para>
      input relation
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   The name of the specified relation's namespace.
  </para>
 </refsect1>
</refentry>

<refentry id="spi-spi-result-code-string">
 <indexterm><primary>SPI_result_code_string</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_result_code_string</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_result_code_string</refname>
  <refpurpose>return error code as string</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
const char * SPI_result_code_string(int <parameter>code</parameter>);
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_result_code_string</function> returns a string representation
   of the result code returned by various SPI functions or stored
   in <varname>SPI_result</varname>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>int <parameter>code</parameter></literal></term>
    <listitem>
     <para>
      result code
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   A string representation of the result code.
  </para>
 </refsect1>
</refentry>

 </sect1>

 <sect1 id="spi-memory">
  <title>Memory Management</title>

  <para>
    <indexterm>
     <primary>memory context</primary>
     <secondary>in SPI</secondary>
    </indexterm>
   <productname>PostgreSQL</productname> allocates memory within
   <firstterm>memory contexts</firstterm>, which provide a convenient method of
   managing allocations made in many different places that need to
   live for differing amounts of time.  Destroying a context releases
   all the memory that was allocated in it.  Thus, it is not necessary
   to keep track of individual objects to avoid memory leaks; instead
   only a relatively small number of contexts have to be managed.
   <function>palloc</function> and related functions allocate memory
   from the <quote>current</quote> context.
  </para>

  <para>
   <function>SPI_connect</function> creates a new memory context and
   makes it current.  <function>SPI_finish</function> restores the
   previous current memory context and destroys the context created by
   <function>SPI_connect</function>.  These actions ensure that
   transient memory allocations made inside your C function are
   reclaimed at C function exit, avoiding memory leakage.
  </para>

  <para>
   However, if your C function needs to return an object in allocated
   memory (such as a value of a pass-by-reference data type), you
   cannot allocate that memory using <function>palloc</function>, at
   least not while you are connected to SPI.  If you try, the object
   will be deallocated by <function>SPI_finish</function>, and your
   C function will not work reliably.  To solve this problem, use
   <function>SPI_palloc</function> to allocate memory for your return
   object.  <function>SPI_palloc</function> allocates memory in the
   <quote>upper executor context</quote>, that is, the memory context
   that was current when <function>SPI_connect</function> was called,
   which is precisely the right context for a value returned from your
   C function.  Several of the other utility functions described in
   this section also return objects created in the upper executor context.
  </para>

  <para>
   When <function>SPI_connect</function> is called, the private
   context of the C function, which is created by
   <function>SPI_connect</function>, is made the current context.  All
   allocations made by <function>palloc</function>,
   <function>repalloc</function>, or SPI utility functions (except as
   described in this section) are made in this context.  When a
   C function disconnects from the SPI manager (via
   <function>SPI_finish</function>) the current context is restored to
   the upper executor context, and all allocations made in the
   C function memory context are freed and cannot be used any more.
  </para>

<!-- *********************************************** -->

<refentry id="spi-spi-palloc">
 <indexterm><primary>SPI_palloc</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_palloc</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_palloc</refname>
  <refpurpose>allocate memory in the upper executor context</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void * SPI_palloc(Size <parameter>size</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_palloc</function> allocates memory in the upper
   executor context.
  </para>

  <para>
   This function can only be used while connected to SPI.
   Otherwise, it throws an error.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Size <parameter>size</parameter></literal></term>
    <listitem>
     <para>
      size in bytes of storage to allocate
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   pointer to new storage space of the specified size
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-realloc">
 <indexterm><primary>SPI_repalloc</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_repalloc</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_repalloc</refname>
  <refpurpose>reallocate memory in the upper executor context</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void * SPI_repalloc(void * <parameter>pointer</parameter>, Size <parameter>size</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_repalloc</function> changes the size of a memory
   segment previously allocated using <function>SPI_palloc</function>.
  </para>

  <para>
   This function is no longer different from plain
   <function>repalloc</function>.  It's kept just for backward
   compatibility of existing code.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>void * <parameter>pointer</parameter></literal></term>
    <listitem>
     <para>
      pointer to existing storage to change
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Size <parameter>size</parameter></literal></term>
    <listitem>
     <para>
      size in bytes of storage to allocate
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   pointer to new storage space of specified size with the contents
   copied from the existing area
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-pfree">
 <indexterm><primary>SPI_pfree</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_pfree</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_pfree</refname>
  <refpurpose>free memory in the upper executor context</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_pfree(void * <parameter>pointer</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_pfree</function> frees memory previously allocated
   using <function>SPI_palloc</function> or
   <function>SPI_repalloc</function>.
  </para>

  <para>
   This function is no longer different from plain
   <function>pfree</function>.  It's kept just for backward
   compatibility of existing code.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>void * <parameter>pointer</parameter></literal></term>
    <listitem>
     <para>
      pointer to existing storage to free
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-copytuple">
 <indexterm><primary>SPI_copytuple</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_copytuple</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_copytuple</refname>
  <refpurpose>make a copy of a row in the upper executor context</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
HeapTuple SPI_copytuple(HeapTuple <parameter>row</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_copytuple</function> makes a copy of a row in the
   upper executor context.  This is normally used to return a modified
   row from a trigger.  In a function declared to return a composite
   type, use <function>SPI_returntuple</function> instead.
  </para>

  <para>
   This function can only be used while connected to SPI.
   Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
   <symbol>SPI_ERROR_UNCONNECTED</symbol>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>HeapTuple <parameter>row</parameter></literal></term>
    <listitem>
     <para>
      row to be copied
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   the copied row, or <symbol>NULL</symbol> on error
   (see <varname>SPI_result</varname> for an error indication)
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-returntuple">
 <indexterm><primary>SPI_returntuple</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_returntuple</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_returntuple</refname>
  <refpurpose>prepare to return a tuple as a Datum</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
HeapTupleHeader SPI_returntuple(HeapTuple <parameter>row</parameter>, TupleDesc <parameter>rowdesc</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_returntuple</function> makes a copy of a row in
   the upper executor context, returning it in the form of a row type <type>Datum</type>.
   The returned pointer need only be converted to <type>Datum</type> via <function>PointerGetDatum</function>
   before returning.
  </para>

  <para>
   This function can only be used while connected to SPI.
   Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
   <symbol>SPI_ERROR_UNCONNECTED</symbol>.
  </para>

  <para>
   Note that this should be used for functions that are declared to return
   composite types.  It is not used for triggers; use
   <function>SPI_copytuple</function> for returning a modified row in a trigger.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>HeapTuple <parameter>row</parameter></literal></term>
    <listitem>
     <para>
      row to be copied
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>TupleDesc <parameter>rowdesc</parameter></literal></term>
    <listitem>
     <para>
      descriptor for row (pass the same descriptor each time for most
      effective caching)
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   <type>HeapTupleHeader</type> pointing to copied row,
   or <symbol>NULL</symbol> on error
   (see <varname>SPI_result</varname> for an error indication)
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-modifytuple">
 <indexterm><primary>SPI_modifytuple</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_modifytuple</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_modifytuple</refname>
  <refpurpose>create a row by replacing selected fields of a given row</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
HeapTuple SPI_modifytuple(Relation <parameter>rel</parameter>, HeapTuple <parameter>row</parameter>, int <parameter>ncols</parameter>,
                          int * <parameter>colnum</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_modifytuple</function> creates a new row by
   substituting new values for selected columns, copying the original
   row's columns at other positions.  The input row is not modified.
   The new row is returned in the upper executor context.
  </para>

  <para>
   This function can only be used while connected to SPI.
   Otherwise, it returns NULL and sets <varname>SPI_result</varname> to
   <symbol>SPI_ERROR_UNCONNECTED</symbol>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>Relation <parameter>rel</parameter></literal></term>
    <listitem>
     <para>
      Used only as the source of the row descriptor for the row.
      (Passing a relation rather than a row descriptor is a
      misfeature.)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>HeapTuple <parameter>row</parameter></literal></term>
    <listitem>
     <para>
      row to be modified
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int <parameter>ncols</parameter></literal></term>
    <listitem>
     <para>
      number of columns to be changed
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>int * <parameter>colnum</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>ncols</parameter>, containing the numbers
      of the columns that are to be changed (column numbers start at 1)
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>Datum * <parameter>values</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>ncols</parameter>, containing the
      new values for the specified columns
     </para>
    </listitem>
   </varlistentry>

   <varlistentry>
    <term><literal>const char * <parameter>nulls</parameter></literal></term>
    <listitem>
     <para>
      an array of length <parameter>ncols</parameter>, describing which
      new values are null
     </para>

     <para>
      If <parameter>nulls</parameter> is <symbol>NULL</symbol> then
      <function>SPI_modifytuple</function> assumes that no new values
      are null.  Otherwise, each entry of the <parameter>nulls</parameter>
      array should be <literal>'&amp;nbsp;'</literal> if the corresponding new value is
      non-null, or <literal>'n'</literal> if the corresponding new value is
      null.  (In the latter case, the actual value in the corresponding
      <parameter>values</parameter> entry doesn't matter.)  Note that
      <parameter>nulls</parameter> is not a text string, just an array: it
      does not need a <literal>'\0'</literal> terminator.
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   new row with modifications, allocated in the upper executor
   context, or <symbol>NULL</symbol> on error
   (see <varname>SPI_result</varname> for an error indication)
  </para>

  <para>
   On error, <varname>SPI_result</varname> is set as follows:
   <variablelist>
    <varlistentry>
     <term><symbol>SPI_ERROR_ARGUMENT</symbol></term>
     <listitem>
      <para>
       if <parameter>rel</parameter> is <symbol>NULL</symbol>, or if
       <parameter>row</parameter> is <symbol>NULL</symbol>, or if <parameter>ncols</parameter>
       is less than or equal to 0, or if <parameter>colnum</parameter> is
       <symbol>NULL</symbol>, or if <parameter>values</parameter> is <symbol>NULL</symbol>.
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_NOATTRIBUTE</symbol></term>
     <listitem>
      <para>
       if <parameter>colnum</parameter> contains an invalid column number (less
       than or equal to 0 or greater than the number of columns in
       <parameter>row</parameter>)
      </para>
     </listitem>
    </varlistentry>

    <varlistentry>
     <term><symbol>SPI_ERROR_UNCONNECTED</symbol></term>
     <listitem>
      <para>
       if SPI is not active
      </para>
     </listitem>
    </varlistentry>
   </variablelist>
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-freetuple">
 <indexterm><primary>SPI_freetuple</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_freetuple</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_freetuple</refname>
  <refpurpose>free a row allocated in the upper executor context</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_freetuple(HeapTuple <parameter>row</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_freetuple</function> frees a row previously allocated
   in the upper executor context.
  </para>

  <para>
   This function is no longer different from plain
   <function>heap_freetuple</function>.  It's kept just for backward
   compatibility of existing code.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>HeapTuple <parameter>row</parameter></literal></term>
    <listitem>
     <para>
      row to free
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-freetupletable">
 <indexterm><primary>SPI_freetuptable</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_freetuptable</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_freetuptable</refname>
  <refpurpose>free a row set created by <function>SPI_execute</function> or a similar
  function</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_freetuptable(SPITupleTable * <parameter>tuptable</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_freetuptable</function> frees a row set created by a
   prior SPI command execution function, such as
   <function>SPI_execute</function>.  Therefore, this function is often called
   with the global variable <varname>SPI_tuptable</varname> as
   argument.
  </para>

  <para>
   This function is useful if an SPI-using C function needs to execute
   multiple commands and does not want to keep the results of earlier
   commands around until it ends.  Note that any unfreed row sets will
   be freed anyway at <function>SPI_finish</function>.
   Also, if a subtransaction is started and then aborted within execution
   of an SPI-using C function, SPI automatically frees any row sets created while
   the subtransaction was running.
  </para>

  <para>
   Beginning in <productname>PostgreSQL</productname> 9.3,
   <function>SPI_freetuptable</function> contains guard logic to protect
   against duplicate deletion requests for the same row set.  In previous
   releases, duplicate deletions would lead to crashes.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPITupleTable * <parameter>tuptable</parameter></literal></term>
    <listitem>
     <para>
      pointer to row set to free, or NULL to do nothing
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-freeplan">
 <indexterm><primary>SPI_freeplan</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_freeplan</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_freeplan</refname>
  <refpurpose>free a previously saved prepared statement</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
int SPI_freeplan(SPIPlanPtr <parameter>plan</parameter>)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_freeplan</function> releases a prepared statement
   previously returned by <function>SPI_prepare</function> or saved by
   <function>SPI_keepplan</function> or <function>SPI_saveplan</function>.
  </para>
 </refsect1>

 <refsect1>
  <title>Arguments</title>

  <variablelist>
   <varlistentry>
    <term><literal>SPIPlanPtr <parameter>plan</parameter></literal></term>
    <listitem>
     <para>
      pointer to statement to free
     </para>
    </listitem>
   </varlistentry>
  </variablelist>
 </refsect1>

 <refsect1>
  <title>Return Value</title>

  <para>
   0 on success;
   <symbol>SPI_ERROR_ARGUMENT</symbol> if <parameter>plan</parameter>
   is <symbol>NULL</symbol> or invalid
  </para>
 </refsect1>
</refentry>

 </sect1>

 <sect1 id="spi-transaction">
  <title>Transaction Management</title>

  <para>
   It is not possible to run transaction control commands such
   as <command>COMMIT</command> and <command>ROLLBACK</command> through SPI
   functions such as <function>SPI_execute</function>.  There are, however,
   separate interface functions that allow transaction control through SPI.
  </para>

  <para>
   It is not generally safe and sensible to start and end transactions in
   arbitrary user-defined SQL-callable functions without taking into account
   the context in which they are called.  For example, a transaction boundary
   in the middle of a function that is part of a complex SQL expression that
   is part of some SQL command will probably result in obscure internal errors
   or crashes.  The interface functions presented here are primarily intended
   to be used by procedural language implementations to support transaction
   management in SQL-level procedures that are invoked by the <command>CALL</command>
   command, taking the context of the <command>CALL</command> invocation into
   account.  SPI-using procedures implemented in C can implement the same logic, but
   the details of that are beyond the scope of this documentation.
  </para>

<!-- *********************************************** -->

<refentry id="spi-spi-commit">
 <indexterm><primary>SPI_commit</primary></indexterm>
 <indexterm><primary>SPI_commit_and_chain</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_commit</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_commit</refname>
  <refname>SPI_commit_and_chain</refname>
  <refpurpose>commit the current transaction</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_commit(void)
</synopsis>

<synopsis>
void SPI_commit_and_chain(void)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_commit</function> commits the current transaction.  It is
   approximately equivalent to running the SQL
   command <command>COMMIT</command>.  After the transaction is committed, a
   new transaction is automatically started using default transaction
   characteristics, so that the caller can continue using SPI facilities.
   If there is a failure during commit, the current transaction is instead
   rolled back and a new transaction is started, after which the error is
   thrown in the usual way.
  </para>

  <para>
   <function>SPI_commit_and_chain</function> is the same, but the new
   transaction is started with the same transaction
   characteristics as the just finished one, like with the SQL command
   <command>COMMIT AND CHAIN</command>.
  </para>

  <para>
   These functions can only be executed if the SPI connection has been set as
   nonatomic in the call to <function>SPI_connect_ext</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-rollback">
 <indexterm><primary>SPI_rollback</primary></indexterm>
 <indexterm><primary>SPI_rollback_and_chain</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_rollback</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_rollback</refname>
  <refname>SPI_rollback_and_chain</refname>
  <refpurpose>abort the current transaction</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_rollback(void)
</synopsis>

<synopsis>
void SPI_rollback_and_chain(void)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_rollback</function> rolls back the current transaction.  It
   is approximately equivalent to running the SQL
   command <command>ROLLBACK</command>.  After the transaction is rolled back,
   a new transaction is automatically started using default transaction
   characteristics, so that the caller can continue using SPI facilities.
  </para>
  <para>
   <function>SPI_rollback_and_chain</function> is the same, but the new
   transaction is started with the same transaction
   characteristics as the just finished one, like with the SQL command
   <command>ROLLBACK AND CHAIN</command>.
  </para>

  <para>
   These functions can only be executed if the SPI connection has been set as
   nonatomic in the call to <function>SPI_connect_ext</function>.
  </para>
 </refsect1>
</refentry>

<!-- *********************************************** -->

<refentry id="spi-spi-start-transaction">
 <indexterm><primary>SPI_start_transaction</primary></indexterm>

 <refmeta>
  <refentrytitle>SPI_start_transaction</refentrytitle>
  <manvolnum>3</manvolnum>
 </refmeta>

 <refnamediv>
  <refname>SPI_start_transaction</refname>
  <refpurpose>obsolete function</refpurpose>
 </refnamediv>

 <refsynopsisdiv>
<synopsis>
void SPI_start_transaction(void)
</synopsis>
 </refsynopsisdiv>

 <refsect1>
  <title>Description</title>

  <para>
   <function>SPI_start_transaction</function> does nothing, and exists
   only for code compatibility with
   earlier <productname>PostgreSQL</productname> releases.  It used to
   be required after calling <function>SPI_commit</function>
   or <function>SPI_rollback</function>, but now those functions start
   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 &amp;gt; 0 &amp;amp;&amp;amp; SPI_tuptable != NULL)
    {
        SPITupleTable *tuptable = SPI_tuptable;
        TupleDesc tupdesc = tuptable-&amp;gt;tupdesc;
        char buf[8192];
        uint64 j;

        for (j = 0; j &amp;lt; tuptable-&amp;gt;numvals; j++)
        {
            HeapTuple tuple = tuptable-&amp;gt;vals[j];
            int i;

            for (i = 1, buf[0] = 0; i &amp;lt;= tupdesc-&amp;gt;natts; i++)
                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %s%s",
                        SPI_getvalue(tuple, tupdesc, i),
                        (i == tupdesc-&amp;gt;natts) ? " " : " |");
            elog(INFO, "EXECQ: %s", buf);
        }
    }

    SPI_finish();
    pfree(command);

    PG_RETURN_INT64(proc);
}
</programlisting>

  <para>
   This is how you declare the function after having compiled it into
   a shared library (details are in <xref linkend="dfunc"/>.):

<programlisting>
CREATE FUNCTION execq(text, integer) RETURNS int8
    AS '<replaceable>filename</replaceable>'
    LANGUAGE C STRICT;
</programlisting>
  </para>

  <para>
   Here is a sample session:

<programlisting>
=&amp;gt; SELECT execq('CREATE TABLE a (x integer)', 0);
 execq
-------
     0
(1 row)

=&amp;gt; INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
INSERT 0 1
=&amp;gt; SELECT execq('SELECT * FROM a', 0);
INFO:  EXECQ:  0    <lineannotation>-- inserted by execq</lineannotation>
INFO:  EXECQ:  1    <lineannotation>-- returned by execq and inserted by upper INSERT</lineannotation>

 execq
-------
     2
(1 row)

=&amp;gt; SELECT execq('INSERT INTO a SELECT x + 2 FROM a RETURNING *', 1);
INFO:  EXECQ:  2    <lineannotation>-- 0 + 2, then execution was stopped by count</lineannotation>
 execq
-------
     1
(1 row)

=&amp;gt; SELECT execq('SELECT * FROM a', 10);
INFO:  EXECQ:  0
INFO:  EXECQ:  1
INFO:  EXECQ:  2

 execq
-------
     3              <lineannotation>-- 10 is the max value only, 3 is the real number of rows</lineannotation>
(1 row)

=&amp;gt; SELECT execq('INSERT INTO a SELECT x + 10 FROM a', 1);
 execq
-------
     3              <lineannotation>-- all rows processed; count does not stop it, because nothing is returned</lineannotation>
(1 row)

=&amp;gt; SELECT * FROM a;
 x
----
  0
  1
  2
 10
 11
 12
(6 rows)

=&amp;gt; DELETE FROM a;
DELETE 6
=&amp;gt; INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INSERT 0 1
=&amp;gt; SELECT * FROM a;
 x
---
 1                  <lineannotation>-- 0 (no rows in a) + 1</lineannotation>
(1 row)

=&amp;gt; INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INFO:  EXECQ:  1
INSERT 0 1
=&amp;gt; SELECT * FROM a;
 x
---
 1
 2                  <lineannotation>-- 1 (there was one row in a) + 1</lineannotation>
(2 rows)

<lineannotation>-- This demonstrates the data changes visibility rule.</lineannotation>
<lineannotation>-- execq is called twice and sees different numbers of rows each time:</lineannotation>

=&amp;gt; INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
INFO:  EXECQ:  1    <lineannotation>-- results from first execq</lineannotation>
INFO:  EXECQ:  2
INFO:  EXECQ:  1    <lineannotation>-- results from second execq</lineannotation>
INFO:  EXECQ:  2
INFO:  EXECQ:  2
INSERT 0 2
=&amp;gt; SELECT * FROM a;
 x
---
 1
 2
 2                  <lineannotation>-- 2 rows * 1 (x in first row)</lineannotation>
 6                  <lineannotation>-- 3 rows (2 + 1 just inserted) * 2 (x in second row)</lineannotation>
(4 rows)
</programlisting>
  </para>
 </sect1>
</chapter>

Chunks
98c38827 (1st chunk of `doc/src/sgml/spi.sgml`)
0c778c53 (2nd chunk of `doc/src/sgml/spi.sgml`)
5ce7dc37 (3rd chunk of `doc/src/sgml/spi.sgml`)
204bd0c0 (4th chunk of `doc/src/sgml/spi.sgml`)
92c20d91 (5th chunk of `doc/src/sgml/spi.sgml`)
5661533e (6th chunk of `doc/src/sgml/spi.sgml`)
e16ca9e6 (7th chunk of `doc/src/sgml/spi.sgml`)
3bc0bcc7 (8th chunk of `doc/src/sgml/spi.sgml`)
a57f1b59 (9th chunk of `doc/src/sgml/spi.sgml`)
aa1b7ffc (10th chunk of `doc/src/sgml/spi.sgml`)
4a192062 (11th chunk of `doc/src/sgml/spi.sgml`)
04566d8d (12th chunk of `doc/src/sgml/spi.sgml`)
ff12fb1b (13th chunk of `doc/src/sgml/spi.sgml`)
208b3f1e (14th chunk of `doc/src/sgml/spi.sgml`)
0743804b (15th chunk of `doc/src/sgml/spi.sgml`)
90f37d58 (16th chunk of `doc/src/sgml/spi.sgml`)
05a95439 (17th chunk of `doc/src/sgml/spi.sgml`)
e8097685 (18th chunk of `doc/src/sgml/spi.sgml`)
ed080c61 (19th chunk of `doc/src/sgml/spi.sgml`)
98c9f0b3 (20th chunk of `doc/src/sgml/spi.sgml`)
9d29ca03 (21th chunk of `doc/src/sgml/spi.sgml`)
e6f5fda6 (22th chunk of `doc/src/sgml/spi.sgml`)
ac9566ce (23th chunk of `doc/src/sgml/spi.sgml`)
e5b582e6 (24th chunk of `doc/src/sgml/spi.sgml`)
1e957c5b (25th chunk of `doc/src/sgml/spi.sgml`)
266e8fec (26th chunk of `doc/src/sgml/spi.sgml`)
5fda0098 (27th chunk of `doc/src/sgml/spi.sgml`)
28bd0e48 (28th chunk of `doc/src/sgml/spi.sgml`)
690dde81 (29th chunk of `doc/src/sgml/spi.sgml`)
65050546 (30th chunk of `doc/src/sgml/spi.sgml`)
e3389772 (31th chunk of `doc/src/sgml/spi.sgml`)
3d842340 (32th chunk of `doc/src/sgml/spi.sgml`)
2464a2bc (33th chunk of `doc/src/sgml/spi.sgml`)
54a2cd82 (34th chunk of `doc/src/sgml/spi.sgml`)
0f7d07ab (35th chunk of `doc/src/sgml/spi.sgml`)
d3cfd1c2 (36th chunk of `doc/src/sgml/spi.sgml`)
10410ebb (37th chunk of `doc/src/sgml/spi.sgml`)
978be48f (38th chunk of `doc/src/sgml/spi.sgml`)
87f26f74 (39th chunk of `doc/src/sgml/spi.sgml`)
1483f87c (40th chunk of `doc/src/sgml/spi.sgml`)
94e25546 (41th chunk of `doc/src/sgml/spi.sgml`)
c1178529 (42th chunk of `doc/src/sgml/spi.sgml`)
66c4541a (43th chunk of `doc/src/sgml/spi.sgml`)
5f7f7630 (44th chunk of `doc/src/sgml/spi.sgml`)
046cf36e (45th chunk of `doc/src/sgml/spi.sgml`)
9d4fef50 (46th chunk of `doc/src/sgml/spi.sgml`)
b91c1e80 (47th chunk of `doc/src/sgml/spi.sgml`)
5c3c3f76 (48th chunk of `doc/src/sgml/spi.sgml`)
bda42e9a (49th chunk of `doc/src/sgml/spi.sgml`)
3277d9bc (50th chunk of `doc/src/sgml/spi.sgml`)
0eaf5936 (51th chunk of `doc/src/sgml/spi.sgml`)
a0e9bbf4 (52th chunk of `doc/src/sgml/spi.sgml`)