diff options
Diffstat (limited to 'doc/src/sgml/html/spi-spi-execute.html')
-rw-r--r-- | doc/src/sgml/html/spi-spi-execute.html | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/doc/src/sgml/html/spi-spi-execute.html b/doc/src/sgml/html/spi-spi-execute.html new file mode 100644 index 0000000..bd93b62 --- /dev/null +++ b/doc/src/sgml/html/spi-spi-execute.html @@ -0,0 +1,179 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>SPI_execute</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="spi-spi-finish.html" title="SPI_finish" /><link rel="next" href="spi-spi-exec.html" title="SPI_exec" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">SPI_execute</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="spi-spi-finish.html" title="SPI_finish">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><th width="60%" align="center">47.1. Interface Functions</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 15.5 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="spi-spi-exec.html" title="SPI_exec">Next</a></td></tr></table><hr /></div><div class="refentry" id="SPI-SPI-EXECUTE"><div class="titlepage"></div><a id="id-1.8.12.8.4.1" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">SPI_execute</span></h2><p>SPI_execute — execute a command</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis"> +int SPI_execute(const char * <em class="parameter"><code>command</code></em>, bool <em class="parameter"><code>read_only</code></em>, long <em class="parameter"><code>count</code></em>) +</pre></div><div class="refsect1" id="id-1.8.12.8.4.5"><h2>Description</h2><p> + <code class="function">SPI_execute</code> executes the specified SQL command + for <em class="parameter"><code>count</code></em> rows. If <em class="parameter"><code>read_only</code></em> + is <code class="literal">true</code>, the command must be read-only, and execution overhead + is somewhat reduced. + </p><p> + This function can only be called from a connected C function. + </p><p> + If <em class="parameter"><code>count</code></em> is zero then the command is executed + for all rows that it applies to. If <em class="parameter"><code>count</code></em> + is greater than zero, then no more than <em class="parameter"><code>count</code></em> rows + will be retrieved; execution stops when the count is reached, much like + adding a <code class="literal">LIMIT</code> clause to the query. For example, +</p><pre class="programlisting"> +SPI_execute("SELECT * FROM foo", true, 5); +</pre><p> + 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, +</p><pre class="programlisting"> +SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5); +</pre><p> + inserts all rows from <code class="structname">bar</code>, ignoring the + <em class="parameter"><code>count</code></em> parameter. However, with +</p><pre class="programlisting"> +SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5); +</pre><p> + at most 5 rows would be inserted, since execution would stop after the + fifth <code class="literal">RETURNING</code> result row is retrieved. + </p><p> + You can pass multiple commands in one string; + <code class="function">SPI_execute</code> returns the + result for the command executed last. The <em class="parameter"><code>count</code></em> + 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. + </p><p> + When <em class="parameter"><code>read_only</code></em> is <code class="literal">false</code>, + <code class="function">SPI_execute</code> increments the command + counter and computes a new <em class="firstterm">snapshot</em> before executing each + command in the string. The snapshot does not actually change if the + current transaction isolation level is <code class="literal">SERIALIZABLE</code> or <code class="literal">REPEATABLE READ</code>, but in + <code class="literal">READ COMMITTED</code> 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. + </p><p> + When <em class="parameter"><code>read_only</code></em> is <code class="literal">true</code>, + <code class="function">SPI_execute</code> does not update either the snapshot + or the command counter, and it allows only plain <code class="command">SELECT</code> + 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 + <em class="firstterm">stable</em> functions to be built: since successive executions + will all use the same snapshot, there will be no change in the results. + </p><p> + 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. + </p><p> + The actual number of rows for which the (last) command was executed + is returned in the global variable <code class="varname">SPI_processed</code>. + If the return value of the function is <code class="symbol">SPI_OK_SELECT</code>, + <code class="symbol">SPI_OK_INSERT_RETURNING</code>, + <code class="symbol">SPI_OK_DELETE_RETURNING</code>, or + <code class="symbol">SPI_OK_UPDATE_RETURNING</code>, + then you can use the + global pointer <code class="literal">SPITupleTable *SPI_tuptable</code> to + access the result rows. Some utility commands (such as + <code class="command">EXPLAIN</code>) also return row sets, and <code class="literal">SPI_tuptable</code> + will contain the result in these cases too. Some utility commands + (<code class="command">COPY</code>, <code class="command">CREATE TABLE AS</code>) don't return a row set, so + <code class="literal">SPI_tuptable</code> is NULL, but they still return the number of + rows processed in <code class="varname">SPI_processed</code>. + </p><p> + The structure <code class="structname">SPITupleTable</code> is defined + thus: +</p><pre class="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; +</pre><p> + The fields <code class="structfield">tupdesc</code>, + <code class="structfield">vals</code>, and + <code class="structfield">numvals</code> + can be used by SPI callers; the remaining fields are internal. + <code class="structfield">vals</code> is an array of pointers to rows. + The number of rows is given by <code class="structfield">numvals</code> + (for somewhat historical reasons, this count is also returned + in <code class="varname">SPI_processed</code>). + <code class="structfield">tupdesc</code> is a row descriptor which you can pass to + SPI functions dealing with rows. + </p><p> + <code class="function">SPI_finish</code> frees all + <code class="structname">SPITupleTable</code>s allocated during the current + C function. You can free a particular result table earlier, if you + are done with it, by calling <code class="function">SPI_freetuptable</code>. + </p></div><div class="refsect1" id="id-1.8.12.8.4.6"><h2>Arguments</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">const char * <em class="parameter"><code>command</code></em></code></span></dt><dd><p> + string containing command to execute + </p></dd><dt><span class="term"><code class="literal">bool <em class="parameter"><code>read_only</code></em></code></span></dt><dd><p><code class="literal">true</code> for read-only execution</p></dd><dt><span class="term"><code class="literal">long <em class="parameter"><code>count</code></em></code></span></dt><dd><p> + maximum number of rows to return, + or <code class="literal">0</code> for no limit + </p></dd></dl></div></div><div class="refsect1" id="id-1.8.12.8.4.7"><h2>Return Value</h2><p> + If the execution of the command was successful then one of the + following (nonnegative) values will be returned: + + </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_OK_SELECT</code></span></dt><dd><p> + if a <code class="command">SELECT</code> (but not <code class="command">SELECT + INTO</code>) was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_SELINTO</code></span></dt><dd><p> + if a <code class="command">SELECT INTO</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_INSERT</code></span></dt><dd><p> + if an <code class="command">INSERT</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_DELETE</code></span></dt><dd><p> + if a <code class="command">DELETE</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_UPDATE</code></span></dt><dd><p> + if an <code class="command">UPDATE</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_MERGE</code></span></dt><dd><p> + if a <code class="command">MERGE</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_INSERT_RETURNING</code></span></dt><dd><p> + if an <code class="command">INSERT RETURNING</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_DELETE_RETURNING</code></span></dt><dd><p> + if a <code class="command">DELETE RETURNING</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_UPDATE_RETURNING</code></span></dt><dd><p> + if an <code class="command">UPDATE RETURNING</code> was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_UTILITY</code></span></dt><dd><p> + if a utility command (e.g., <code class="command">CREATE TABLE</code>) + was executed + </p></dd><dt><span class="term"><code class="symbol">SPI_OK_REWRITTEN</code></span></dt><dd><p> + if the command was rewritten into another kind of command (e.g., + <code class="command">UPDATE</code> became an <code class="command">INSERT</code>) by a <a class="link" href="rules.html" title="Chapter 41. The Rule System">rule</a>. + </p></dd></dl></div><p> + </p><p> + On error, one of the following negative values is returned: + + </p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="symbol">SPI_ERROR_ARGUMENT</code></span></dt><dd><p> + if <em class="parameter"><code>command</code></em> is <code class="symbol">NULL</code> or + <em class="parameter"><code>count</code></em> is less than 0 + </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_COPY</code></span></dt><dd><p> + if <code class="command">COPY TO stdout</code> or <code class="command">COPY FROM stdin</code> + was attempted + </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_TRANSACTION</code></span></dt><dd><p> + if a transaction manipulation command was attempted + (<code class="command">BEGIN</code>, + <code class="command">COMMIT</code>, + <code class="command">ROLLBACK</code>, + <code class="command">SAVEPOINT</code>, + <code class="command">PREPARE TRANSACTION</code>, + <code class="command">COMMIT PREPARED</code>, + <code class="command">ROLLBACK PREPARED</code>, + or any variant thereof) + </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_OPUNKNOWN</code></span></dt><dd><p> + if the command type is unknown (shouldn't happen) + </p></dd><dt><span class="term"><code class="symbol">SPI_ERROR_UNCONNECTED</code></span></dt><dd><p> + if called from an unconnected C function + </p></dd></dl></div><p> + </p></div><div class="refsect1" id="id-1.8.12.8.4.8"><h2>Notes</h2><p> + All SPI query-execution functions set both + <code class="varname">SPI_processed</code> and + <code class="varname">SPI_tuptable</code> (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 + <code class="function">SPI_execute</code> or another query-execution function + across later calls. + </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="spi-spi-finish.html" title="SPI_finish">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="spi-interface.html" title="47.1. Interface Functions">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="spi-spi-exec.html" title="SPI_exec">Next</a></td></tr><tr><td width="40%" align="left" valign="top">SPI_finish </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 15.5 Documentation">Home</a></td><td width="40%" align="right" valign="top"> SPI_exec</td></tr></table></div></body></html>
\ No newline at end of file |