SPI_push
- pushes SPI stack to allow recursive SPI calls
+ pushes SPI stack to allow recursive SPI usage
Description
- SPI_push pushes a new environment on to the
- SPI call stack, allowing recursive calls to use a new environment.
+ SPI_push should be called before executing another
+ procedure that might itself wish to use SPI.
+ After SPI_push, SPI is no longer in a
+ connected> state, and SPI function calls will be rejected unless
+ a fresh SPI_connect 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
+ SPI_pop to restore access to your own SPI state.
+
+
+ Note that SPI_execute and related functions
+ automatically do the equivalent of SPI_push 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
+ SPI_connect calls do you need to issue
+ SPI_push and SPI_pop.
SPI_pop
- pops SPI stack to allow recursive SPI calls
+ pops SPI stack to return from recursive SPI usage
SPI_pop pops the previous environment from the
- SPI call stack. For use when returning from recursive SPI calls.
+ SPI call stack. See SPI_push.
-
+ute">
- SPI_exec
+ SPI_execute
- SPI_exec
+ SPI_execute
execute a command
-int SPI_exec
(const char * command, int
count)
+int SPI_exec
ute(const char * command, bool read_only, int
count)
Description
- SPI_exec executes the specified SQL command
+ SPI_execute executes the specified SQL command
+ for
count rows. If
read_only
+ is true>, the command must be read-only, and execution overhead
+ is somewhat reduced.
+
+
+ This function may only be called from a connected procedure.
- This function should only be called from a connected procedure. If
-
count is zero then it executes the command
+ If
count is zero then the command is executed
for all rows that it applies to. If
count
is greater than 0, then the number of rows for which the command
will be executed is restricted (much like a
LIMIT clause). For example,
-SPI_exec("INSERT INTO tab SELECT * FROM tab", 5);
+SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
will allow at most 5 rows to be inserted into the table.
- You may pass multiple commands in one string, and the command may
- be rewritten by rules. SPI_exec returns the
- result for the command executed last.
+ You may pass multiple commands in one string, and the commands may
+ be rewritten by rules. SPI_execute returns the
+ result for the command executed last. The
count
+ limit applies to each command separately, but it is not applied to
+ hidden commands generated by rules.
+
+
+ When
read_only is
false>,
+ SPI_execute increments the command
+ counter and computes a new snapshot> before executing each
+ command in the string. The snapshot does not actually change if the
+ current transaction isolation level is SERIALIZABLE>, but in
+ 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.
+
+
+ When
read_only is
true>,
+ SPI_execute does not update either the snapshot
+ or the command counter, and it allows only plain 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
+ stable> functions to be built: since successive executions
+ will all use the same snapshot, there will be no change in the results.
+
+
+ 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.
is returned in the global variable SPI_processed
(unless the return value of the function is
SPI_OK_UTILITY). If the return value of the
- function is SPI_OK_SELECT then you may the use
+ function is SPI_OK_SELECT then you may use the
global pointer SPITupleTable *SPI_tuptable to
access the result rows.
} SPITupleTable;
vals> is an array of pointers to rows. (The number
- of valid entries is given by SPI_processed).
+ of valid entries is given by SPI_processed.)
tupdesc> is a row descriptor which you may pass to
SPI functions dealing with rows. tuptabcxt>,
alloced>, and free> are internal
+
+
+ true> for read-only execution
+
+
+
+
Notes
- The functions SPI_exec,
- SPI_execp, and
- SPI_prepare change both
+ The functions SPI_execute,
+ SPI_exec,
+ SPI_execute_plan, and
+ SPI_execp change both
SPI_processed and
SPI_tuptable (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
- SPI_exec or SPI_execp
+ procedure variables if you need to access the result table of
+ SPI_execute or a related function
across later calls.
+
+
+ SPI_exec
+
+
+
+ SPI_exec
+ execute a read/write command
+
+
+
+
+
+int SPI_exec(const char *
command, int
count)
+
+
+
+
+
Description
+
+ SPI_exec is the same as
+ SPI_execute, with the latter's
+
read_only parameter always taken as
+ false>.
+
+
+
+
+
Arguments
+
+
+
+
+ string containing command to execute
+
+
+
+
+
+
+ maximum number of rows to process or return
+
+
+
+
+
+
+
+
Return Value
+
+ See SPI_execute.
+
+
+
+
+
+
SPI_prepare
may be advantageous to perform the planning only once.
SPI_prepare converts a command string into an
execution plan that can be executed repeatedly using
- SPI_execp.
+ SPI_execute_plan.
A prepared command can be generalized by writing parameters
($1>, $2>, etc.) in place of what would be
constants in a normal command. The actual values of the parameters
- are then specified when SPI_execp is called.
+ are then specified when SPI_execute_plan is called.
This allows the prepared command to be used over a wider range of
situations than would be possible without parameters.
Return Value
- SPI_prepare returns non-null pointer to an
- execution plan. On error, NULL will be returned.
- In both cases, SPI_result will be set analogous
- to the value returned by SPI_exec, except that
+ SPI_prepare returns a non-null pointer to an
+ execution plan. On error, NULL will be returned,
+ and SPI_result will be set to one of the same
+ error codes used by SPI_execute, except that
it is set to SPI_ERROR_ARGUMENT if
nargs> is less than 0, or if nargs> is
SPI_getargcount
- returns the number of arguments needed when executing a plan
+ returns the number of arguments needed by a plan
prepared by SPI_prepare
SPI_getargcount returns the number of arguments needed
- when executing a plan prepared by SPI_prepare.
+ to execute a plan prepared by SPI_prepare.
Return Value
- The expected argument count for the
plan or
+ The expected argument count for the
plan, or
SPI_ERROR_ARGUMENT if the
plan
is NULL
SPI_getargtypeid
- returns the expected typeid for the specified argument when
- executing a plan prepared by SPI_prepare
+ returns the expected typeid for the specified argument of
+ a plan prepared by SPI_prepare
SPI_getargtypeid returns the Oid representing the type
- id for
argument at argIndex in a plan prepared by
+ id for
the argIndex'th argument of a plan prepared by
SPI_prepare. First argument is at index zero.
Return Value
- The type id of the argument at the given index or
- SPI_ERROR_ARGUMENT if the
plan is
+ The type id of the argument at the given index, or
+
SPI_ERROR_ARGUMENT if the
plan is
NULL or
argIndex is less than 0 or
- not less than the number of arguments declared for the
plan
-
+ not less than the number of arguments declared for the
+ <parameter>plan</parameter>
SPI_is_cursor_plan
returns true if a plan
- prepared by SPI_prepare can be passed
- as an argument to SPI_cursor_open
+ prepared by SPI_prepare can be used with
+ SPI_cursor_open
SPI_is_cursor_plan returns true
if a plan prepared by SPI_prepare can be passed
as an argument to SPI_cursor_open and
- false if that is not the case. The criteria is that the
+ false if that is not the case. The criteria are that the
plan represents one single command and that this
command is a SELECT without an INTO
clause.
-p">
+ute-plan">
- SPI_execp
+ SPI_execute_plan
- SPI_execp
+ SPI_execute_plan
executes a plan prepared by SPI_prepare
-int SPI_execp(void *
plan, Datum *
values, const char *
nulls, int
count)
+int SPI_execute_plan(void *
plan, Datum *
values, const char *
nulls,
+ bool
read_only, int
count)
Description
- SPI_execp executes a plan prepared by
- has the same interpretation as in SPI_exec.
+ SPI_execute_plan executes a plan prepared by
+
SPI_prepare.
read_only and
+
count have the same interpretation as in
+ SPI_execute.
- actual parameter values
+ An array of actual parameter values. Must have same length as the
+ plan's number of arguments.
- 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.
n indicates a null value (entry in
values> will be ignored); a space indicates a
nonnull value (entry in
values> is valid).
- SPI_execp assumes that no parameters are
+ SPI_execute_plan assumes that no parameters are
null.
+
+
+ true> for read-only execution
+
+
+
+
- number of row for which plan is to be executed
+ maximum number of rows to process or return
Return Value
- The return value is the same as for SPI_exec
- or one of the following:
+ The return value is the same as for SPI_execute,
+ with the following additional possible error (negative) results:
SPI_processed and
SPI_tuptable are set as in
- SPI_exec if successful.
+ SPI_execute if successful.
If one of the objects (a table, function, etc.) referenced by the
prepared plan is dropped during the session then the result of
- SPI_execp for this plan will be unpredictable.
+ SPI_execute_plan for this plan will be unpredictable.
+
+
+
+
+
+
+
+
+ SPI_execp
+
+
+
+ SPI_execp
+ executes a plan in read/write mode
+
+
+
+
+
+int SPI_execp(void *
plan, Datum *
values, const char *
nulls, int
count)
+
+
+
+
+
Description
+
+ SPI_execp is the same as
+ SPI_execute_plan, with the latter's
+
read_only parameter always taken as
+ false>.
+
+
+
+
+
Arguments
+
+
+
+
+ execution plan (returned by SPI_prepare)
+
+
+
+
+
+
+ An array of actual parameter values. Must have same length as the
+ plan's number of arguments.
+
+
+
+
+
+
+ An array describing which parameters are null. Must have same length as
+ the plan's number of arguments.
+ n indicates a null value (entry in
+
values> will be ignored); a space indicates a
+ nonnull value (entry in
values> is valid).
+
+
+ SPI_execp assumes that no parameters are
+ null.
+
+
+
+
+
+
+ maximum number of rows to process or return
+
+
+
+
+
+
+
+
Return Value
+
+ See SPI_execute_plan.
+
+
+ SPI_processed and
+ SPI_tuptable are set as in
+ SPI_execute if successful.
-Portal SPI_cursor_open(const char *
name, void *
plan, Datum *
values, const char *
nulls)
+Portal SPI_cursor_open(const char *
name, void *
plan,
+ Datum *
values, const char *
nulls,
SPI_cursor_open sets up a cursor (internally,
a portal) that will execute a plan prepared by
- SPI_prepare.
+ SPI_prepare. The parameters have the same
+ meanings as the corresponding parameters to
+ SPI_execute_plan.
- actual parameter values
+ An array of actual parameter values. Must have same length as the
+ plan's number of arguments.
- 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.
n indicates a null value (entry in
values> will be ignored); a space indicates a
- nonnull value (entry in
values> is valid). If
- SPI_cursor_open assumes that no parameters
- are null.
+ nonnull value (entry in
values> is valid).
+
+
+ SPI_cursor_open assumes that no parameters are
+ null.
+
+
+
+
+
+
+ true> for read-only execution
SPI_processed and
SPI_tuptable are set as in
- SPI_exec if successful.
+ SPI_execute if successful.
your procedure in the current session. You may save the pointer
returned in a local variable. Always check if this pointer is
NULL or not either when preparing a plan or using
- an already prepared plan in SPI_execp.
+ an already prepared plan in SPI_execute_plan.
If one of the objects (a table, function, etc.) referenced by the
prepared plan is dropped during the session then the results of
- SPI_execp for this plan will be unpredictable.
+ SPI_execute_plan for this plan will be unpredictable.
The functions described here provide an interface for extracting
- information from result sets returned by SPI_exec> and
+ information from result sets returned by SPI_execute> and
other SPI functions.
- which new values are null, if any (see SPI_execp for the format)
+ which new values are null, if any (see
+ SPI_execute_plan for the format)
SPI_freetuptable
- free a row set created by SPI_exec> or a similar function
+ free a row set created by SPI_execute> or a similar
+ function
SPI_freetuptable frees a row set created by a
prior SPI command execution function, such as
- SPI_exec>. Therefore, this function is usually called
+ SPI_execute>. Therefore, this function is usually called
with the global variable SPI_tupletable as
argument.
number of arguments, up to a finite maximum number.
- A function may also have the same name as an attribute. (Recall
- that attribute(table) is equivalent to
- table.attribute.) 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.
-
-
When creating a family of overloaded functions, one should be
careful not to create ambiguities. For instance, given the
relies on this behavior.
+ 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 attribute(table) is considered equivalent
+ to table.attribute. 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, schema.func(table)) but it's better to
+ avoid the problem by not choosing conflicting names.
+
+
When overloading C-language functions, there is an additional
constraint: The C name of each function in the family of
(usually the internal one). The alternative form of the
AS> clause for the SQL CREATE
FUNCTION 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,
CREATE FUNCTION test(int) RETURNS int
AS 'filename>', 'test_1arg'
+
+
Function Volatility Categories
+
+
+ functions
+
+
+ Every function has a volatility> classification, with
+ the possibilities being VOLATILE>, STABLE>, or
+ IMMUTABLE>. VOLATILE> is the default if the
+ CREATE FUNCTION command does not specify a category.
+ The volatility category is a promise to the optimizer about the behavior
+ of the function:
+
+
+
+ A 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.
+
+
+
+ A 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 VOLATILE> function in
+ an indexscan condition.)
+
+
+
+ An 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
+ SELECT ... WHERE x = 2 + 2> can be simplified on sight to
+ SELECT ... WHERE x = 4>, because the function underlying
+ the integer addition operator is marked IMMUTABLE>.
+
+
+
+
+
+ For best optimization results, you should label your functions with the
+ strictest volatility category that is valid for them.
+
+
+ Any function with side-effects must> be labeled
+ VOLATILE>, so that calls to it cannot be optimized away.
+ Even a function with no side-effects needs to be labeled
+ VOLATILE> if its value can change within a single query;
+ some examples are random()>, currval()>,
+ timeofday()>.
+
+
+ There is relatively little difference between STABLE> and
+ 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 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
+
+
+ Because of the snapshotting behavior of MVCC (see )
+ a function containing only SELECT> commands can safely be
+ marked STABLE>, even if it selects from tables that might be
+ undergoing modifications by concurrent queries.
+
PostgreSQL will execute a
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 current_timestamp> family of functions qualify
+ as stable, since their values do not change within a transaction.
+
+
+ The same snapshotting behavior is used for SELECT> commands
+ within IMMUTABLE> functions. It is generally unwise to select
+ from database tables within an IMMUTABLE> function at all,
+ since the immutability will be broken if the table contents ever change.
+ However,
PostgreSQL does not enforce that you
+ do not do that.
+
+
+ A common error is to label a function IMMUTABLE> when its
+ results depend on a configuration parameter. For example, a function
+ that manipulates timestamps might well have results that depend on the
+ setting. For safety, such functions should
+ be labeled STABLE> instead.
+
+
+
+ Before
PostgreSQL release 8.0, the requirement
+ that STABLE> and 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 SELECT>.
+
+
+
+