diff options
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/plpython.sgml | 4 | ||||
-rw-r--r-- | doc/src/sgml/ref/create_function.sgml | 8 | ||||
-rw-r--r-- | doc/src/sgml/release.sgml | 42 | ||||
-rw-r--r-- | doc/src/sgml/spi.sgml | 416 | ||||
-rw-r--r-- | doc/src/sgml/xfunc.sgml | 146 |
5 files changed, 523 insertions, 93 deletions
diff --git a/doc/src/sgml/plpython.sgml b/doc/src/sgml/plpython.sgml index a19b4a3585d..6655219d3e6 100644 --- a/doc/src/sgml/plpython.sgml +++ b/doc/src/sgml/plpython.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.23 2004/05/16 23:22:07 neilc Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/plpython.sgml,v 1.24 2004/09/13 20:05:18 tgl Exp $ --> <chapter id="plpython"> <title>PL/Python - Python Procedural Language</title> @@ -175,7 +175,7 @@ def __plpython_procedure_myfunc_23456(): row number and column name. It has these additional methods: <function>nrows</function> which returns the number of rows returned by the query, and <function>status</function> which is the - <function>SPI_exec()</function> return value. The result object + <function>SPI_execute()</function> return value. The result object can be modified. </para> diff --git a/doc/src/sgml/ref/create_function.sgml b/doc/src/sgml/ref/create_function.sgml index 2c43fe9b460..1a8f5e41d8e 100644 --- a/doc/src/sgml/ref/create_function.sgml +++ b/doc/src/sgml/ref/create_function.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.58 2004/07/11 23:23:43 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/create_function.sgml,v 1.59 2004/09/13 20:05:38 tgl Exp $ --> <refentry id="SQL-CREATEFUNCTION"> @@ -172,7 +172,7 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable> These attributes inform the system whether it is safe to replace multiple evaluations of the function with a single evaluation, for run-time optimization. At most one choice - should be specified. If none of these appear, + may be specified. If none of these appear, <literal>VOLATILE</literal> is the default assumption. </para> @@ -206,6 +206,10 @@ CREATE [ OR REPLACE ] FUNCTION <replaceable class="parameter">name</replaceable> to prevent calls from being optimized away; an example is <literal>setval()</>. </para> + + <para> + For additional details see <xref linkend="xfunc-volatility">. + </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/release.sgml b/doc/src/sgml/release.sgml index ddf93a04ff9..1d91953a0aa 100644 --- a/doc/src/sgml/release.sgml +++ b/doc/src/sgml/release.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.295 2004/09/10 18:39:54 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.296 2004/09/13 20:05:18 tgl Exp $ --> <appendix id="release"> @@ -339,6 +339,26 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.295 2004/09/10 18:39:54 tgl Exp <listitem> <para> + In <literal>READ COMMITTED</> serialization mode, volatile functions + now see the results of concurrent transactions committed up to the + beginning of each statement within the function, rather than up to the + beginning of the interactive command that called the function. + </para> + </listitem> + + <listitem> + <para> + Functions declared <literal>STABLE</> or <literal>IMMUTABLE</> always + use the snapshot of the calling query, and therefore do not see the + effects of actions taken after the calling query starts, whether in + their own transaction or other transactions. Such a function must be + read-only, too, meaning that it cannot use any SQL commands other than + <command>SELECT</>. + </para> + </listitem> + + <listitem> + <para> Non-deferred AFTER triggers are now fired immediately after completion of the triggering query, rather than upon finishing the current interactive command. This makes a difference when the triggering query @@ -1436,6 +1456,26 @@ $PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.295 2004/09/10 18:39:54 tgl Exp <listitem> <para> + In <literal>READ COMMITTED</> serialization mode, volatile functions + now see the results of concurrent transactions committed up to the + beginning of each statement within the function, rather than up to the + beginning of the interactive command that called the function. + </para> + </listitem> + + <listitem> + <para> + Functions declared <literal>STABLE</> or <literal>IMMUTABLE</> always + use the snapshot of the calling query, and therefore do not see the + effects of actions taken after the calling query starts, whether in + their own transaction or other transactions. Such a function must be + read-only, too, meaning that it cannot use any SQL commands other than + <command>SELECT</>. + </para> + </listitem> + + <listitem> + <para> Non-deferred AFTER triggers are now fired immediately after completion of the triggering query, rather than upon finishing the current interactive command. This makes a difference when the triggering query diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index 4018c2e3e1b..a5a832d2e73 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.34 2004/04/01 21:28:43 tgl Exp $ +$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.35 2004/09/13 20:05:25 tgl Exp $ --> <chapter id="spi"> @@ -206,7 +206,7 @@ int SPI_finish(void) <refnamediv> <refname>SPI_push</refname> - <refpurpose>pushes SPI stack to allow recursive SPI calls</refpurpose> + <refpurpose>pushes SPI stack to allow recursive SPI usage</refpurpose> </refnamediv> <indexterm><primary>SPI_push</primary></indexterm> @@ -221,8 +221,24 @@ void SPI_push(void) <title>Description</title> <para> - <function>SPI_push</function> pushes a new environment on to the - SPI call stack, allowing recursive calls to use a new environment. + <function>SPI_push</function> should be called before executing another + procedure that might itself wish to use SPI. + After <function>SPI_push</function>, SPI is no longer in a + <quote>connected</> state, and SPI function calls will be rejected unless + a fresh <function>SPI_connect</function> is done. This ensures a clean + separation between your procedure's SPI state and that of another procedure + you call. After the other procedure returns, call + <function>SPI_pop</function> to restore access to your own SPI state. + </para> + + <para> + Note that <function>SPI_execute</function> and related functions + automatically do the equivalent of <function>SPI_push</function> before + passing control back to the SQL execution engine, so it is not necessary + for you to worry about this when using those functions. + Only when you are directly calling arbitrary code that might contain + <function>SPI_connect</function> calls do you need to issue + <function>SPI_push</function> and <function>SPI_pop</function>. </para> </refsect1> @@ -237,7 +253,7 @@ void SPI_push(void) <refnamediv> <refname>SPI_pop</refname> - <refpurpose>pops SPI stack to allow recursive SPI calls</refpurpose> + <refpurpose>pops SPI stack to return from recursive SPI usage</refpurpose> </refnamediv> <indexterm><primary>SPI_pop</primary></indexterm> @@ -253,7 +269,7 @@ void SPI_pop(void) <para> <function>SPI_pop</function> pops the previous environment from the - SPI call stack. For use when returning from recursive SPI calls. + SPI call stack. See <function>SPI_push</function>. </para> </refsect1> @@ -261,21 +277,21 @@ void SPI_pop(void) <!-- *********************************************** --> -<refentry id="spi-spi-exec"> +<refentry id="spi-spi-execute"> <refmeta> - <refentrytitle>SPI_exec</refentrytitle> + <refentrytitle>SPI_execute</refentrytitle> </refmeta> <refnamediv> - <refname>SPI_exec</refname> + <refname>SPI_execute</refname> <refpurpose>execute a command</refpurpose> </refnamediv> - <indexterm><primary>SPI_exec</primary></indexterm> + <indexterm><primary>SPI_execute</primary></indexterm> <refsynopsisdiv> <synopsis> -int SPI_exec(const char * <parameter>command</parameter>, int <parameter>count</parameter>) +int SPI_execute(const char * <parameter>command</parameter>, bool <parameter>read_only</parameter>, int <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -283,27 +299,65 @@ int SPI_exec(const char * <parameter>command</parameter>, int <parameter>count</ <title>Description</title> <para> - <function>SPI_exec</function> executes the specified SQL command - for <parameter>count</parameter> rows. + <function>SPI_execute</function> executes the specified SQL command + for <parameter>count</parameter> rows. If <parameter>read_only</parameter> + is <literal>true</>, the command must be read-only, and execution overhead + is somewhat reduced. + </para> + + <para> + This function may only be called from a connected procedure. </para> <para> - This function should only be called from a connected procedure. If - <parameter>count</parameter> is zero then it executes the command + 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 0, then the number of rows for which the command will be executed is restricted (much like a <literal>LIMIT</literal> clause). For example, <programlisting> -SPI_exec("INSERT INTO tab SELECT * FROM tab", 5); +SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5); </programlisting> will allow at most 5 rows to be inserted into the table. </para> <para> - You may pass multiple commands in one string, and the command may - be rewritten by rules. <function>SPI_exec</function> returns the - result for the command executed last. + You may pass multiple commands in one string, and the commands may + be rewritten by rules. <function>SPI_execute</function> returns the + result for the command executed last. The <parameter>count</parameter> + limit applies to each command separately, but it is not applied to + hidden commands generated by rules. + </para> + + <para> + When <parameter>read_only</parameter> is <literal>false</>, + <function>SPI_execute</function> increments the command + counter and computes a new <firstterm>snapshot</> before executing each + command in the string. The snapshot does not actually change if the + current transaction isolation level is <literal>SERIALIZABLE</>, but in + <literal>READ COMMITTED</> 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</>, + <function>SPI_execute</function> does not update either the snapshot + or the command counter, and it allows only plain <command>SELECT</> + 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</> 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> @@ -311,7 +365,7 @@ SPI_exec("INSERT INTO tab SELECT * FROM tab", 5); is returned in the global variable <varname>SPI_processed</varname> (unless the return value of the function is <symbol>SPI_OK_UTILITY</symbol>). If the return value of the - function is <symbol>SPI_OK_SELECT</symbol> then you may the use + function is <symbol>SPI_OK_SELECT</symbol> then you may use the global pointer <literal>SPITupleTable *SPI_tuptable</literal> to access the result rows. </para> @@ -330,7 +384,7 @@ typedef struct } SPITupleTable; </programlisting> <structfield>vals</> is an array of pointers to rows. (The number - of valid entries is given by <varname>SPI_processed</varname>). + of valid entries is given by <varname>SPI_processed</varname>.) <structfield>tupdesc</> is a row descriptor which you may pass to SPI functions dealing with rows. <structfield>tuptabcxt</>, <structfield>alloced</>, and <structfield>free</> are internal @@ -359,6 +413,15 @@ typedef struct </varlistentry> <varlistentry> + <term><literal>bool <parameter>read_only</parameter></literal></term> + <listitem> + <para> + <literal>true</> for read-only execution + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><literal>int <parameter>count</parameter></literal></term> <listitem> <para> @@ -504,14 +567,15 @@ typedef struct <title>Notes</title> <para> - The functions <function>SPI_exec</function>, - <function>SPI_execp</function>, and - <function>SPI_prepare</function> change both + The functions <function>SPI_execute</function>, + <function>SPI_exec</function>, + <function>SPI_execute_plan</function>, and + <function>SPI_execp</function> change 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 - procedure variables if you need to access the result of - <function>SPI_exec</function> or <function>SPI_execp</function> + procedure variables if you need to access the result table of + <function>SPI_execute</function> or a related function across later calls. </para> </refsect1> @@ -519,6 +583,70 @@ typedef struct <!-- *********************************************** --> +<refentry id="spi-spi-exec"> + <refmeta> + <refentrytitle>SPI_exec</refentrytitle> + </refmeta> + + <refnamediv> + <refname>SPI_exec</refname> + <refpurpose>execute a read/write command</refpurpose> + </refnamediv> + + <indexterm><primary>SPI_exec</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +int SPI_exec(const char * <parameter>command</parameter>, int <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</>. + </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>int <parameter>count</parameter></literal></term> + <listitem> + <para> + maximum number of rows to process or return + </para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + + <refsect1> + <title>Return Value</title> + + <para> + See <function>SPI_execute</function>. + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + <refentry id="spi-spi-prepare"> <refmeta> <refentrytitle>SPI_prepare</refentrytitle> @@ -551,14 +679,14 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n may be advantageous to perform the planning only once. <function>SPI_prepare</function> converts a command string into an execution plan that can be executed repeatedly using - <function>SPI_execp</function>. + <function>SPI_execute_plan</function>. </para> <para> A prepared command can be generalized by writing parameters (<literal>$1</>, <literal>$2</>, etc.) in place of what would be constants in a normal command. The actual values of the parameters - are then specified when <function>SPI_execp</function> is called. + 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> @@ -610,10 +738,10 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n <title>Return Value</title> <para> - <function>SPI_prepare</function> returns non-null pointer to an - execution plan. On error, <symbol>NULL</symbol> will be returned. - In both cases, <varname>SPI_result</varname> will be set analogous - to the value returned by <function>SPI_exec</function>, except that + <function>SPI_prepare</function> returns a non-null pointer to an + execution plan. 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</> is less than 0, or if <parameter>nargs</> is @@ -642,7 +770,7 @@ void * SPI_prepare(const char * <parameter>command</parameter>, int <parameter>n <refnamediv> <refname>SPI_getargcount</refname> - <refpurpose>returns the number of arguments needed when executing a plan + <refpurpose>returns the number of arguments needed by a plan prepared by <function>SPI_prepare</function></refpurpose> </refnamediv> @@ -659,7 +787,7 @@ int SPI_getargcount(void * <parameter>plan</parameter>) <para> <function>SPI_getargcount</function> returns the number of arguments needed - when executing a plan prepared by <function>SPI_prepare</function>. + to execute a plan prepared by <function>SPI_prepare</function>. </para> </refsect1> @@ -681,7 +809,7 @@ int SPI_getargcount(void * <parameter>plan</parameter>) <refsect1> <title>Return Value</title> <para> - The expected argument count for the <parameter>plan</parameter> or + The expected argument count for the <parameter>plan</parameter>, or <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan </parameter> is <symbol>NULL</symbol> </para> @@ -697,8 +825,8 @@ int SPI_getargcount(void * <parameter>plan</parameter>) <refnamediv> <refname>SPI_getargtypeid</refname> - <refpurpose>returns the expected typeid for the specified argument when - executing a plan prepared by <function>SPI_prepare</function></refpurpose> + <refpurpose>returns the expected typeid for the specified argument of + a plan prepared by <function>SPI_prepare</function></refpurpose> </refnamediv> <indexterm><primary>SPI_getargtypeid</primary></indexterm> @@ -714,7 +842,7 @@ Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex <para> <function>SPI_getargtypeid</function> returns the Oid representing the type - id for argument at <parameter>argIndex</parameter> in a plan prepared by + id for the <parameter>argIndex</parameter>'th argument of a plan prepared by <function>SPI_prepare</function>. First argument is at index zero. </para> </refsect1> @@ -746,11 +874,11 @@ Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex <refsect1> <title>Return Value</title> <para> - The type id of the argument at the given index or <symbol> - SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter> is + The type id of the argument at the given index, or + <symbol>SPI_ERROR_ARGUMENT</symbol> if the <parameter>plan</parameter> is <symbol>NULL</symbol> or <parameter>argIndex</parameter> is less than 0 or - not less than the number of arguments declared for the <parameter>plan - </parameter> + not less than the number of arguments declared for the + <parameter>plan</parameter> </para> </refsect1> </refentry> @@ -765,8 +893,8 @@ Oid SPI_getargtypeid(void * <parameter>plan</parameter>, int <parameter>argIndex <refnamediv> <refname>SPI_is_cursor_plan</refname> <refpurpose>returns <symbol>true</symbol> if a plan - prepared by <function>SPI_prepare</function> can be passed - as an argument to <function>SPI_cursor_open</function></refpurpose> + prepared by <function>SPI_prepare</function> can be used with + <function>SPI_cursor_open</function></refpurpose> </refnamediv> <indexterm><primary>SPI_is_cursor_plan</primary></indexterm> @@ -784,7 +912,7 @@ bool SPI_is_cursor_plan(void * <parameter>plan</parameter>) <function>SPI_is_cursor_plan</function> returns <symbol>true</symbol> if a plan prepared by <function>SPI_prepare</function> can be passed as an argument to <function>SPI_cursor_open</function> and <symbol> - false</symbol> if that is not the case. The criteria is that the + false</symbol> if that is not the case. The criteria are that the <parameter>plan</parameter> represents one single command and that this command is a <command>SELECT</command> without an <command>INTO</command> clause. @@ -819,21 +947,22 @@ bool SPI_is_cursor_plan(void * <parameter>plan</parameter>) <!-- *********************************************** --> -<refentry id="spi-spi-execp"> +<refentry id="spi-spi-execute-plan"> <refmeta> - <refentrytitle>SPI_execp</refentrytitle> + <refentrytitle>SPI_execute_plan</refentrytitle> </refmeta> <refnamediv> - <refname>SPI_execp</refname> + <refname>SPI_execute_plan</refname> <refpurpose>executes a plan prepared by <function>SPI_prepare</function></refpurpose> </refnamediv> - <indexterm><primary>SPI_execp</primary></indexterm> + <indexterm><primary>SPI_execute_plan</primary></indexterm> <refsynopsisdiv> <synopsis> -int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, int <parameter>count</parameter>) +int SPI_execute_plan(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + bool <parameter>read_only</parameter>, int <parameter>count</parameter>) </synopsis> </refsynopsisdiv> @@ -841,9 +970,10 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <title>Description</title> <para> - <function>SPI_execp</function> executes a plan prepared by - <function>SPI_prepare</function>. <parameter>tcount</parameter> - has the same interpretation as in <function>SPI_exec</function>. + <function>SPI_execute_plan</function> executes a plan prepared by + <function>SPI_prepare</function>. <parameter>read_only</parameter> and + <parameter>count</parameter> have the same interpretation as in + <function>SPI_execute</function>. </para> </refsect1> @@ -861,10 +991,11 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par </varlistentry> <varlistentry> - <term><literal>Datum *<parameter>values</parameter></literal></term> + <term><literal>Datum * <parameter>values</parameter></literal></term> <listitem> <para> - actual parameter values + An array of actual parameter values. Must have same length as the + plan's number of arguments. </para> </listitem> </varlistentry> @@ -873,7 +1004,8 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <term><literal>const char * <parameter>nulls</parameter></literal></term> <listitem> <para> - An array describing which parameters are null. + An array describing which parameters are null. Must have same length as + the plan's number of arguments. <literal>n</literal> indicates a null value (entry in <parameter>values</> will be ignored); a space indicates a nonnull value (entry in <parameter>values</> is valid). @@ -881,17 +1013,26 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <para> If <parameter>nulls</parameter> is <symbol>NULL</symbol> then - <function>SPI_execp</function> assumes that no parameters are + <function>SPI_execute_plan</function> assumes that no parameters are null. </para> </listitem> </varlistentry> <varlistentry> + <term><literal>bool <parameter>read_only</parameter></literal></term> + <listitem> + <para> + <literal>true</> for read-only execution + </para> + </listitem> + </varlistentry> + + <varlistentry> <term><literal>int <parameter>count</parameter></literal></term> <listitem> <para> - number of row for which plan is to be executed + maximum number of rows to process or return </para> </listitem> </varlistentry> @@ -902,8 +1043,8 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <title>Return Value</title> <para> - The return value is the same as for <function>SPI_exec</function> - or one of the following: + The return value is the same as for <function>SPI_execute</function>, + with the following additional possible error (negative) results: <variablelist> <varlistentry> @@ -931,7 +1072,7 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <para> <varname>SPI_processed</varname> and <varname>SPI_tuptable</varname> are set as in - <function>SPI_exec</function> if successful. + <function>SPI_execute</function> if successful. </para> </refsect1> @@ -941,7 +1082,106 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <para> If one of the objects (a table, function, etc.) referenced by the prepared plan is dropped during the session then the result of - <function>SPI_execp</function> for this plan will be unpredictable. + <function>SPI_execute_plan</function> for this plan will be unpredictable. + </para> + </refsect1> +</refentry> + +<!-- *********************************************** --> + +<refentry id="spi-spi-execp"> + <refmeta> + <refentrytitle>SPI_execp</refentrytitle> + </refmeta> + + <refnamediv> + <refname>SPI_execp</refname> + <refpurpose>executes a plan in read/write mode</refpurpose> + </refnamediv> + + <indexterm><primary>SPI_execp</primary></indexterm> + + <refsynopsisdiv> +<synopsis> +int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, int <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</>. + </para> + </refsect1> + + <refsect1> + <title>Arguments</title> + + <variablelist> + <varlistentry> + <term><literal>void * <parameter>plan</parameter></literal></term> + <listitem> + <para> + execution plan (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 + plan'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 plan's number of arguments. + <literal>n</literal> indicates a null value (entry in + <parameter>values</> will be ignored); a space indicates a + nonnull value (entry in <parameter>values</> is valid). + </para> + + <para> + If <parameter>nulls</parameter> is <symbol>NULL</symbol> then + <function>SPI_execp</function> assumes that no parameters are + null. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>int <parameter>count</parameter></literal></term> + <listitem> + <para> + maximum number of rows to process or return + </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> @@ -962,7 +1202,9 @@ int SPI_execp(void * <parameter>plan</parameter>, Datum * <parameter>values</par <refsynopsisdiv> <synopsis> -Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <parameter>plan</parameter>, Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>) +Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <parameter>plan</parameter>, + Datum * <parameter>values</parameter>, const char * <parameter>nulls</parameter>, + bool <parameter>read_only</parameter>) </synopsis> </refsynopsisdiv> @@ -972,7 +1214,9 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <paramet <para> <function>SPI_cursor_open</function> sets up a cursor (internally, a portal) that will execute a plan prepared by - <function>SPI_prepare</function>. + <function>SPI_prepare</function>. The parameters have the same + meanings as the corresponding parameters to + <function>SPI_execute_plan</function>. </para> <para> @@ -1013,22 +1257,36 @@ Portal SPI_cursor_open(const char * <parameter>name</parameter>, void * <paramet <term><literal>Datum * <parameter>values</parameter></literal></term> <listitem> <para> - actual parameter values + An array of actual parameter values. Must have same length as the + plan's number of arguments. </para> </listitem> </varlistentry> <varlistentry> - <term><literal>const char *<parameter>nulls</parameter></literal></term> + <term><literal>const char * <parameter>nulls</parameter></literal></term> <listitem> <para> - An array describing which parameters are null values. + An array describing which parameters are null. Must have same length as + the plan's number of arguments. <literal>n</literal> indicates a null value (entry in <parameter>values</> will be ignored); a space indicates a - nonnull value (entry in <parameter>values</> is valid). If - <parameter>nulls</parameter> is <symbol>NULL</> then - <function>SPI_cursor_open</function> assumes that no parameters - are null. + nonnull value (entry in <parameter>values</> is valid). + </para> + + <para> + If <parameter>nulls</parameter> is <symbol>NULL</symbol> then + <function>SPI_cursor_open</function> assumes that no parameters are + null. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>bool <parameter>read_only</parameter></literal></term> + <listitem> + <para> + <literal>true</> for read-only execution </para> </listitem> </varlistentry> @@ -1168,7 +1426,7 @@ void SPI_cursor_fetch(Portal <parameter>portal</parameter>, bool <parameter>forw <para> <varname>SPI_processed</varname> and <varname>SPI_tuptable</varname> are set as in - <function>SPI_exec</function> if successful. + <function>SPI_execute</function> if successful. </para> </refsect1> </refentry> @@ -1320,7 +1578,7 @@ void * SPI_saveplan(void * <parameter>plan</parameter>) your procedure in the current session. You may save the pointer returned in a local variable. Always check if this pointer is <symbol>NULL</symbol> or not either when preparing a plan or using - an already prepared plan in <function>SPI_execp</function>. + an already prepared plan in <function>SPI_execute_plan</function>. </para> </refsect1> @@ -1374,7 +1632,7 @@ void * SPI_saveplan(void * <parameter>plan</parameter>) <para> If one of the objects (a table, function, etc.) referenced by the prepared plan is dropped during the session then the results of - <function>SPI_execp</function> for this plan will be unpredictable. + <function>SPI_execute_plan</function> for this plan will be unpredictable. </para> </refsect1> </refentry> @@ -1386,7 +1644,7 @@ void * SPI_saveplan(void * <parameter>plan</parameter>) <para> The functions described here provide an interface for extracting - information from result sets returned by <function>SPI_exec</> and + information from result sets returned by <function>SPI_execute</> and other SPI functions. </para> @@ -2360,7 +2618,8 @@ HeapTuple SPI_modifytuple(Relation <parameter>rel</parameter>, HeapTuple <parame <term><literal>const char * <parameter>Nulls</parameter></literal></term> <listitem> <para> - which new values are null, if any (see <function>SPI_execp</function> for the format) + which new values are null, if any (see + <function>SPI_execute_plan</function> for the format) </para> </listitem> </varlistentry> @@ -2466,7 +2725,8 @@ void SPI_freetuple(HeapTuple <parameter>row</parameter>) <refnamediv> <refname>SPI_freetuptable</refname> - <refpurpose>free a row set created by <function>SPI_exec</> or a similar function</refpurpose> + <refpurpose>free a row set created by <function>SPI_execute</> or a similar + function</refpurpose> </refnamediv> <indexterm><primary>SPI_freetuptable</primary></indexterm> @@ -2483,7 +2743,7 @@ void SPI_freetuptable(SPITupleTable * <parameter>tuptable</parameter>) <para> <function>SPI_freetuptable</function> frees a row set created by a prior SPI command execution function, such as - <function>SPI_exec</>. Therefore, this function is usually called + <function>SPI_execute</>. Therefore, this function is usually called with the global variable <varname>SPI_tupletable</varname> as argument. </para> diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 684da2a3749..70a00ae032a 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.86 2004/08/24 00:06:50 neilc Exp $ +$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.87 2004/09/13 20:05:25 tgl Exp $ --> <sect1 id="xfunc"> @@ -2405,14 +2405,6 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray </para> <para> - A function may also have the same name as an attribute. (Recall - that <literal>attribute(table)</literal> is equivalent to - <literal>table.attribute</literal>.) In the case that there is an - ambiguity between a function on a complex type and an attribute of - the complex type, the attribute will always be used. - </para> - - <para> When creating a family of overloaded functions, one should be careful not to create ambiguities. For instance, given the functions @@ -2428,6 +2420,18 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... </para> <para> + A function that takes a single argument of a composite type should + generally not have the same name as any attribute (field) of that type. + Recall that <literal>attribute(table)</literal> is considered equivalent + to <literal>table.attribute</literal>. In the case that there is an + ambiguity between a function on a composite type and an attribute of + the composite type, the attribute will always be used. It is possible + to override that choice by schema-qualifying the function name + (that is, <literal>schema.func(table)</literal>) but it's better to + avoid the problem by not choosing conflicting names. + </para> + + <para> When overloading C-language functions, there is an additional constraint: The C name of each function in the family of overloaded functions must be different from the C names of all @@ -2437,7 +2441,7 @@ CREATE FUNCTION test(smallint, double precision) RETURNS ... (usually the internal one). The alternative form of the <literal>AS</> clause for the SQL <command>CREATE FUNCTION</command> command decouples the SQL function name from - the function name in the C source code. E.g., + the function name in the C source code. For instance, <programlisting> CREATE FUNCTION test(int) RETURNS int AS '<replaceable>filename</>', 'test_1arg' @@ -2450,6 +2454,128 @@ CREATE FUNCTION test(int, int) RETURNS int </para> </sect1> + <sect1 id="xfunc-volatility"> + <title>Function Volatility Categories</title> + + <indexterm zone="xfunc-volatility"> + <primary>volatility</primary> + <secondary>functions</secondary> + </indexterm> + + <para> + Every function has a <firstterm>volatility</> classification, with + the possibilities being <literal>VOLATILE</>, <literal>STABLE</>, or + <literal>IMMUTABLE</>. <literal>VOLATILE</> is the default if the + <command>CREATE FUNCTION</command> command does not specify a category. + The volatility category is a promise to the optimizer about the behavior + of the function: + + <itemizedlist> + <listitem> + <para> + A <literal>VOLATILE</> function can do anything, including modifying + the database. It can return different results on successive calls with + the same arguments. The optimizer makes no assumptions about the + behavior of such functions. A query using a volatile function will + re-evaluate the function at every row where its value is needed. + </para> + </listitem> + <listitem> + <para> + A <literal>STABLE</> function cannot modify the database and is + guaranteed to return the same results given the same arguments + for all calls within a single surrounding query. This category + allows the optimizer to optimize away multiple calls of the function + within a single query. In particular, it is safe to use an expression + containing such a function in an indexscan condition. (Since an + indexscan will evaluate the comparison value only once, not once at + each row, it is not valid to use a <literal>VOLATILE</> function in + an indexscan condition.) + </para> + </listitem> + <listitem> + <para> + An <literal>IMMUTABLE</> function cannot modify the database and is + guaranteed to return the same results given the same arguments forever. + This category allows the optimizer to pre-evaluate the function when + a query calls it with constant arguments. For example, a query like + <literal>SELECT ... WHERE x = 2 + 2</> can be simplified on sight to + <literal>SELECT ... WHERE x = 4</>, because the function underlying + the integer addition operator is marked <literal>IMMUTABLE</>. + </para> + </listitem> + </itemizedlist> + </para> + + <para> + For best optimization results, you should label your functions with the + strictest volatility category that is valid for them. + </para> + + <para> + Any function with side-effects <emphasis>must</> be labeled + <literal>VOLATILE</>, so that calls to it cannot be optimized away. + Even a function with no side-effects needs to be labeled + <literal>VOLATILE</> if its value can change within a single query; + some examples are <literal>random()</>, <literal>currval()</>, + <literal>timeofday()</>. + </para> + + <para> + There is relatively little difference between <literal>STABLE</> and + <literal>IMMUTABLE</> categories when considering simple interactive + queries that are planned and immediately executed: it doesn't matter + a lot whether a function is executed once during planning or once during + query execution startup. But there is a big difference if the plan is + saved and reused later. Labeling a function <literal>IMMUTABLE</> when + it really isn't may allow it to be prematurely folded to a constant during + planning, resulting in a stale value being re-used during subsequent uses + of the plan. This is a hazard when using prepared statements or when + using function languages that cache plans (such as + <application>PL/pgSQL</>). + </para> + + <para> + Because of the snapshotting behavior of MVCC (see <xref linkend="mvcc">) + a function containing only <command>SELECT</> commands can safely be + marked <literal>STABLE</>, even if it selects from tables that might be + undergoing modifications by concurrent queries. + <productname>PostgreSQL</productname> will execute a <literal>STABLE</> + function using the snapshot established for the calling query, and so it + will see a fixed view of the database throughout that query. + Also note + that the <function>current_timestamp</> family of functions qualify + as stable, since their values do not change within a transaction. + </para> + + <para> + The same snapshotting behavior is used for <command>SELECT</> commands + within <literal>IMMUTABLE</> functions. It is generally unwise to select + from database tables within an <literal>IMMUTABLE</> function at all, + since the immutability will be broken if the table contents ever change. + However, <productname>PostgreSQL</productname> does not enforce that you + do not do that. + </para> + + <para> + A common error is to label a function <literal>IMMUTABLE</> when its + results depend on a configuration parameter. For example, a function + that manipulates timestamps might well have results that depend on the + <xref linkend="guc-timezone"> setting. For safety, such functions should + be labeled <literal>STABLE</> instead. + </para> + + <note> + <para> + Before <productname>PostgreSQL</productname> release 8.0, the requirement + that <literal>STABLE</> and <literal>IMMUTABLE</> functions cannot modify + the database was not enforced by the system. Release 8.0 enforces it + by requiring SQL functions and procedural language functions of these + categories to contain no SQL commands other than <command>SELECT</>. + </para> + </note> + </sect1> + <!-- Keep this comment at the end of the file Local variables: mode:sgml |