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>