From b3bbeed1f6e6c3c4dd505a8e6fa4a7ec51442d15 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 14 Nov 2001 22:26:02 +0000 Subject: [PATCH] Overhaul SPI documentation: bring it into some semblance of agreement with reality, and add doco for Jan's recent round of enhancements. --- doc/src/sgml/spi.sgml | 2664 +++++++++++++++++++++++++++-------------- 1 file changed, 1774 insertions(+), 890 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index 5f9aa5b6c80..9e4ce00fb06 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -1,3 +1,7 @@ + + @@ -16,10 +20,15 @@ The Server Programming Interface (SPI) gives users the ability to run SQL queries inside user-defined C functions. -The available Procedural Languages (PL) give an alternate -means to access these capabilities. + + +The available Procedural Languages (PL) give an alternate +means to build functions that can execute queries. + + + In fact, SPI is just a set of native interface functions to simplify access to the Parser, Planner, Optimizer and Executor. @@ -42,15 +51,15 @@ recursively, it may itself call procedures which may make -Note, that if during execution of a query from a procedure the transaction -is aborted then control will not be returned to your procedure. Rather, all work +Note that if during execution of a query from a procedure the transaction is +aborted, then control will not be returned to your procedure. Rather, all work will be rolled back and the server will wait for the next command from the -client. This will be changed in future versions. +client. This will probably be changed in future versions. -Other restrictions are the inability to execute BEGIN, END and ABORT -(transaction control statements) and cursor operations. This will also be +A related restriction is the inability to execute BEGIN, END and ABORT +(transaction control statements). This will also be changed in the future. @@ -142,8 +151,9 @@ Return status Description -SPI_connect opens a connection to the Postgres backend. - You should call this function if you will need to execute queries. Some +SPI_connect opens a connection from a procedure +invocation to the SPI manager. + You must call this function if you will need to execute queries. Some utility SPI functions may be called from un-connected procedures. @@ -259,8 +269,10 @@ SPI_finish(void) Description -SPI_finish closes an existing connection to the Postgres backend. - You should call this function after completing operations through the SPI manager. +SPI_finish closes an existing connection to the +SPI manager. + You must call this function after completing the SPI operations needed + during your procedure's current invocation. You may get the error return SPI_ERROR_UNCONNECTED if SPI_finish is @@ -273,10 +285,11 @@ SPI_finish(void) Usage - SPI_finish must be called as a final step by a connected procedure + SPI_finish must be called as a final step by a connected procedure, or you may get - unpredictable results! Note that you can safely skip the call to SPI_finish - if you abort the transaction (via elog(ERROR)). + unpredictable results! However, you do not need to worry about making +this happen if the transaction is aborted via elog(ERROR). In that case +SPI will clean itself up. @@ -369,9 +382,6 @@ Maximum number of tuples to return - - SPI_OK_EXEC if properly disconnected - SPI_ERROR_UNCONNECTED if called from an un-connected procedure @@ -444,7 +454,7 @@ Maximum number of tuples to return This should only be called from a connected procedure. If tcount is zero then it executes the query for all tuples returned by the query scan. Using tcount > 0 you may restrict the number of tuples for - which the query will be executed. For example, + which the query will be executed (much like a LIMIT clause). For example, SPI_exec ("INSERT INTO tab SELECT * FROM tab", 5); @@ -456,7 +466,7 @@ will allow at most 5 tuples to be inserted into table. -You may pass many queries in one string or query string may be +You may pass multiple queries in one string or query string may be re-written by RULEs. SPI_exec returns the result for the last query executed. @@ -466,11 +476,8 @@ You may pass many queries in one string or query string may be The actual number of tuples for which the (last) query was executed is returned in the global variable SPI_processed (if not SPI_OK_UTILITY). - If SPI_OK_SELECT returned and SPI_processed > 0 then you may use global - pointer SPITupleTable *SPI_tuptable to access the selected tuples: - - Also NOTE, that SPI_finish frees and makes all SPITupleTables - unusable! (See Memory management). + If SPI_OK_SELECT is returned and SPI_processed > 0 then you may use global + pointer SPITupleTable *SPI_tuptable to access the result tuples. @@ -498,51 +505,61 @@ You may pass many queries in one string or query string may be + Structures - - If SPI_OK_SELECT returned and SPI_processed > 0 then you may use the global + + If SPI_OK_SELECT is returned and SPI_processed > 0 then you may use the global pointer SPITupleTable *SPI_tuptable to access the selected tuples. + Structure SPITupleTable is defined in spi.h: typedef struct { + MemoryContext tuptabcxt; /* memory context of result table */ uint32 alloced; /* # of alloced vals */ uint32 free; /* # of free vals */ TupleDesc tupdesc; /* tuple descriptor */ HeapTuple *vals; /* tuples */ } SPITupleTable; + - HeapTuple *vals is an array of pointers to tuples. TupleDesc tupdesc is + vals is an array of pointers to tuples (the number of useful entries + is given by SPI_processed). TupleDesc tupdesc is a tuple descriptor which you may pass to SPI functions dealing with - tuples. + tuples. tuptabcxt, alloced, and free are internal fields not intended + for use by SPI callers. + + + + + Functions SPI_exec, SPI_execp and + SPI_prepare 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 one SPI_exec or + SPI_execp across later calls. + + - NOTE! Functions SPI_exec, SPI_execp and SPI_prepare change both - SPI_processed and SPI_tuptable (just the pointer, not the contents of the - structure)! So, save them in local procedure variables if you need them. - - - Also NOTE, that SPI_finish frees and makes all SPITupleTables - unusable! (See Memory management). - + SPI_finish frees all SPITupleTables allocated during + the current procedure. You can free a particular result table earlier, + if you are done with it, by calling SPI_freetuptable. + ---> @@ -558,7 +575,7 @@ You may pass many queries in one string or query string may be SPI_prepare - Connects your procedure to the SPI manager. + Prepares a plan for a query, without executing it yet SPIconnecting SPI_prepare @@ -604,7 +621,7 @@ Number of input parameters ($1 ... $nargs - as in SQL-functions) -Pointer list of type OIDs to input arguments +Pointer to array of type OIDs for input parameter types @@ -647,18 +664,35 @@ Pointer to an execution plan (parser+planner+optimizer) Usage - - nargs is number of parameters ($1 ... $nargs - as in SQL-functions), - and nargs may be 0 only if there is not any $1 in query. - - Execution of prepared execution plans is sometimes much faster so this - feature may be useful if the same query will be executed many times. + When the same or similar query is to be executed repeatedly, it may + be advantageous to perform query planning only once. + SPI_prepare converts a query string into an execution + plan that can be passed repeatedly to SPI_execp. + + + A prepared query can be generalized by writing parameters ($1, $2, etc) + in place of what would be constants in a normal query. The values of + the parameters are then specified when SPI_execp + is called. This allows the prepared query to be used over a wider + range of situations than would be possible without parameters. + + + + However, there is a disadvantage: since the planner does not know the + values that will be supplied for the parameters, it may make worse + query planning choices than it would make for a simple query with + all constants visible. + + + + If the query uses parameters, their number and datatypes must be + specified in the call to SPI_prepare. The plan returned by SPI_prepare may be used only in current invocation of the procedure since SPI_finish frees memory allocated for a plan. - See SPI_saveplan. + But see SPI_saveplan to save a plan for longer. If successful, a non-null pointer will be returned. Otherwise, you'll get @@ -692,6 +726,779 @@ TBD + + +SPI_execp +SPI - Plan Execution + + +SPI_execp + + +Executes a plan from SPI_prepare + +SPIconnecting +SPI_execp + + + +1997-12-24 + + +SPI_execp(plan, +values, +nulls, +tcount) + + + + +1997-12-24 + +Inputs + + + + +void *plan + + + +Execution plan + + + + + +Datum *values + + + +Actual parameter values + + + + + +char *nulls + + + +Array describing which parameters are NULLs + +n indicates NULL (values[] entry ignored) +space indicates not NULL (values[] entry is valid) + + + + + + +int tcount + + + +Number of tuples for which plan is to be executed + + + + + + + + +1997-12-24 + +Outputs + + + +int + + + + Returns the same value as SPI_exec as well as + + + SPI_ERROR_ARGUMENT + if plan + is NULL or tcount < 0 + + + SPI_ERROR_PARAM + if values + is NULL + and plan + was prepared with some parameters. + + + + + + +SPI_tuptable + + + +initialized as in + SPI_exec if successful + + + + +SPI_processed + + + +initialized as in + SPI_exec if successful + + + + + + + + + +1997-12-24 + +Description + + +SPI_execp + executes a plan prepared by SPI_prepare. + tcount has the same + interpretation as in SPI_exec. + + + +Usage + + + If nulls +is NULL then + SPI_execp +assumes that all parameters (if any) are NOT NULL. + + + + If one of the objects (a relation, function, etc.) referenced by the prepared + plan is dropped during your session (by your backend or another process) then the + results of SPI_execp for this plan will be unpredictable. + + + + + + + + + + + + + + + +SPI_cursor_open +SPI - Cursor Support + + +SPI_cursor_open + + +Sets up a cursor using a plan created with SPI_prepare + +SPIcursors +SPI_cursor_open + + + +2001-11-14 + + +SPI_cursor_open(name, +plan, +values, +nulls) + + + + +2001-11-14 + +Inputs + + + + +char *name + + + +Name for portal, or NULL to let the system select a name + + + + + +void *plan + + + +Execution plan + + + + + +Datum *values + + + +Actual parameter values + + + + + +char *nulls + + + +Array describing which parameters are NULLs + +n indicates NULL (values[] entry ignored) +space indicates not NULL (values[] entry is valid) + + + + + + + + + +2001-11-14 + +Outputs + + + +Portal + + + + Pointer to Portal containing cursor, or NULL on error + + + + + + + + + +2001-11-14 + +Description + + +SPI_cursor_open + sets up a cursor (internally, a Portal) that will execute a plan + prepared by SPI_prepare. + + + Using a cursor instead of executing the plan 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 procedure (it can, in fact, live to + the end of the current transaction). Returning the portal name to + the procedure's caller provides a way of returning a rowset result. + + + +Usage + + + If nulls +is NULL then + SPI_cursor_open +assumes that all parameters (if any) are NOT NULL. + + + + + + + + + + + +SPI_cursor_find +SPI - Cursor Support + + +SPI_cursor_find + + +Finds an existing cursor (Portal) by name + +SPIcursors +SPI_cursor_find + + + +2001-11-14 + + +SPI_cursor_find(name) + + + + +2001-11-14 + +Inputs + + + + +char *name + + + +Name of portal + + + + + + + + +2001-11-14 + +Outputs + + + +Portal + + + + Pointer to Portal with given name, or NULL if not found + + + + + + + + + +2001-11-14 + +Description + + +SPI_cursor_find + finds a pre-existing Portal by name. This is primarily useful + to resolve a cursor name returned as text by some other function. + + + + + + + + + + + + +SPI_cursor_fetch +SPI - Cursor Support + + +SPI_cursor_fetch + + +Fetches some rows from a cursor + +SPIcursors +SPI_cursor_fetch + + + +2001-11-14 + + +SPI_cursor_fetch(portal, +forward, +count) + + + + +2001-11-14 + +Inputs + + + + +Portal portal + + + +Portal containing cursor + + + + + +bool forward + + + +True for fetch forward, false for fetch backward + + + + + +int count + + + +Maximum number of rows to fetch + + + + + + + + +2001-11-14 + +Outputs + + + +SPI_tuptable + + + +initialized as in + SPI_exec if successful + + + + +SPI_processed + + + +initialized as in + SPI_exec if successful + + + + + + + + + +2001-11-14 + +Description + + +SPI_cursor_fetch + fetches some (more) rows from a cursor. This is equivalent to the + SQL command FETCH. + + + + + + + + + + + + +SPI_cursor_move +SPI - Cursor Support + + +SPI_cursor_move + + +Moves a cursor + +SPIcursors +SPI_cursor_move + + + +2001-11-14 + + +SPI_cursor_move(portal, +forward, +count) + + + + +2001-11-14 + +Inputs + + + + +Portal portal + + + +Portal containing cursor + + + + + +bool forward + + + +True for move forward, false for move backward + + + + + +int count + + + +Maximum number of rows to move + + + + + + + + +2001-11-14 + +Outputs + + + +None + + + + + + + + + + + + +2001-11-14 + +Description + + +SPI_cursor_move + skips over some number of rows in a cursor. This is equivalent to the + SQL command MOVE. + + + + + + + + + + + + +SPI_cursor_close +SPI - Cursor Support + + +SPI_cursor_close + + +Closes a cursor + +SPIcursors +SPI_cursor_close + + + +2001-11-14 + + +SPI_cursor_close(portal) + + + + +2001-11-14 + +Inputs + + + + +Portal portal + + + +Portal containing cursor + + + + + + + + +2001-11-14 + +Outputs + + + +None + + + + + + + + + + + + +2001-11-14 + +Description + + +SPI_cursor_close + closes a previously created cursor and releases its Portal storage. + + + +Usage + + + All open cursors are closed implicitly at transaction end. + SPI_cursor_close need only be invoked if + it is desirable to release resources sooner. + + + + + + + + + SPI_saveplan @@ -788,7 +1595,7 @@ Execution plan location. NULL if unsuccessful. in future versions. As an alternative, there is the ability to reuse prepared plans in the - consequent invocations of your procedure in the current session. + subsequent invocations of your procedure in the current session. Use SPI_execp to execute this saved plan. @@ -831,758 +1638,21 @@ TBD --> - - - - - - -SPI_execp -SPI - Plan Execution - - -SPI_execp - - -Executes a plan from SPI_saveplan - -SPIconnecting -SPI_execp - - - -1997-12-24 - - -SPI_execp(plan, -values, -nulls, -tcount) - - - - -1997-12-24 - -Inputs - - - - -void *plan - - - -Execution plan - - - - - -Datum *values - - - -Actual parameter values - - - - - -char *nulls - - - -Array describing what parameters get NULLs - -n indicates NULL allowed -A space indicates NULL not allowed - - - - - - -int tcount - - - -Number of tuples for which plan is to be executed - - - - - - - - -1997-12-24 - -Outputs - - - -int - - - - Returns the same value as SPI_exec as well as - - - SPI_ERROR_ARGUMENT - if plan - is NULL or tcount < 0 - - - SPI_ERROR_PARAM - if values - is NULL - and plan - was prepared with some parameters. - - - - - - -SPI_tuptable - - - -initialized as in - SPI_exec if successful - - - - -SPI_processed - - - -initialized as in - SPI_exec if successful - - - - - - - - - -1997-12-24 - -Description - - -SPI_execp - stores a plan prepared by SPI_prepare in safe memory - protected from freeing by SPI_finish or the transaction manager. - - - In the current version of Postgres there is no ability to - store prepared plans in the system - catalog and fetch them from there for execution. This will be implemented - in future versions. - - As a work arround, there is the ability to reuse prepared plans in the - consequent invocations of your procedure in the current session. - Use SPI_execp to execute this saved plan. - - - -Usage - - - If nulls -is NULL then - SPI_execp -assumes that all values (if any) are NOT NULL. - - - - If one of the objects (a relation, function, etc.) referenced by the prepared - plan is dropped during your session (by your backend or another process) then the - results of SPI_execp for this plan will be unpredictable. - - - - - - - - - Interface Support Functions -All functions described below may be used by connected and unconnected -procedures. +The functions described here provide convenient interfaces for extracting +information from tuple sets returned by SPI_exec and other +SPI interface functions. - - - - - - -SPI_copytuple -SPI - Tuple Copy - - -SPI_copytuple - - -Makes copy of tuple in upper Executor context - -SPIcopying tuples -SPI_copytuple - - - -1997-12-24 - - -SPI_copytuple(tuple) - - - - -1997-12-24 - -Inputs - - - - -HeapTuple tuple - - - -Input tuple to be copied - - - - - - - - -1997-12-24 - -Outputs - - - - -HeapTuple - - - -Copied tuple - - - non-NULL - if tuple - is not NULL and the copy was successful - - - NULL - only if tuple - is NULL - - - - - - - - - - - -1997-12-24 - -Description - - -SPI_copytuple - makes a copy of tuple in upper Executor context. See the section on Memory Management. - - - -Usage - -TBD - - - - - - - - - - - - -SPI_copytupledesc -SPI - Tuple Descriptor Copy - - -SPI_copytupledesc - - -Makes copy of tuple descriptor in upper Executor context - -SPIcopying tuple descriptors -SPI_copytupledesc - - - -2001-08-02 - - -SPI_copytupledesc(tupdesc) - - - - -2001-08-02 - -Inputs - - - - -TupleDesc tupdesc - - - -Input tuple descriptor to be copied - - - - - - - - -2001-08-02 - -Outputs - - - - -TupleDesc - - - -Copied tuple descriptor - - - non-NULL - if tupdesc - is not NULL and the copy was successful - - - NULL - only if tupdesc - is NULL - - - - - - - - - - - -2001-08-02 - -Description - - -SPI_copytupledesc - makes a copy of tupdesc in upper Executor context. See the section on Memory Management. - - - -Usage - - -TBD - - - - - - - - - - - - -SPI_copytupleintoslot -SPI - Tuple and Descriptor Copy - - -SPI_copytupleintoslot - - -Makes copy of tuple and descriptor in upper Executor context - -SPIcopying tuples -SPI_copytupleintoslot - - - -1997-12-24 - - -SPI_copytupleintoslot(tuple, tupdesc) - - - - -1997-12-24 - -Inputs - - - - -HeapTuple tuple - - - -Input tuple to be copied - - - - - -TupleDesc tupdesc - - - -Input tuple descriptor to be copied - - - - - - - - -1997-12-24 - -Outputs - - - - -TupleTableSlot * - - - -Tuple slot containing copied tuple and descriptor - - - non-NULL - if tuple - and tupdesc - are not NULL and the copy was successful - - - NULL - only if tuple - or tupdesc - is NULL - - - - - - - - - - - -1997-12-24 - -Description - - -SPI_copytupleintoslot - makes a copy of tuple in upper Executor context, returning it in the - form of a filled-in TupleTableSlot. - See the section on Memory Management. - - - -Usage - - -TBD - - - - - - - - - - - - -SPI_modifytuple -SPI - Tuple Modify - - -SPI_modifytuple - - -Modifies tuple of relation - -SPImodifying tuples -SPI_modifytuple - - - -1997-12-24 - - -SPI_modifytuple(rel, tuple , nattrs -, attnum , Values , Nulls) - - - - -1997-12-24 - -Inputs - - - - -Relation rel - - - - - - - - -HeapTuple tuple - - - -Input tuple to be modified - - - - - -int nattrs - - - -Number of attribute numbers in attnum - - - - - -int * attnum - - - -Array of numbers of the attributes that are to be changed - - - - - -Datum * Values - - - -New values for the attributes specified - - - - - -char * Nulls - - - -Which attributes are NULL, if any - - - - - - - - -1997-12-24 - -Outputs - - - - -HeapTuple - - - -New tuple with modifications - - - non-NULL - if tuple - is not NULL and the modify was successful - - - NULL - only if tuple - is NULL - - - - - - - -SPI_result - - - - - - SPI_ERROR_ARGUMENT if rel is NULL or tuple is NULL or natts ≤ 0 or - attnum is NULL or Values is NULL. - - - SPI_ERROR_NOATTRIBUTE if there is an invalid - attribute number in attnum (attnum ≤ 0 or > number of - attributes in tuple) - - - - - - - - - - - -1997-12-24 - -Description - - -SPI_modifytuple -Modifies a tuple in upper Executor context. See the section on Memory Management. - - - -Usage - - -If successful, a pointer to the new tuple is returned. The new tuple is -allocated in upper Executor context (see Memory management). Passed tuple -is not changed. - - - - - +All functions described in this section may be used by both connected and +unconnected procedures. + @@ -1597,7 +1667,7 @@ is not changed. SPI_fnumber -Finds the attribute number for specified attribute +Finds the attribute number for specified attribute name SPIdecoding tuples SPI_fnumber @@ -1685,7 +1755,15 @@ Valid one-based index number of attribute Attribute numbers are 1 based. - + + +If the given fname refers to a system attribute (eg, oid) +then the appropriate negative attribute number will be returned. +The caller should be careful to test for exact equality to +SPI_ERROR_NOATTRIBUTE to detect error; +testing for result <= 0 is not correct unless system attributes +should be rejected. + Algorithm -Copies the relation name into new storage. +Returns a newly-allocated copy of the rel name. +(Use pfree() to release the copy when done with it.) + + + +Memory Management + + +Postgres allocates memory within memory +contexts, 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 --- only a relatively small number +of contexts have to be managed. palloc and related +functions allocate memory from the current context. + + +SPI_connect creates a new memory context and makes +it current. SPI_finish restores the previous +current memory context and destroys the context created by +SPI_connect. These actions ensure that transient +memory allocations made inside your procedure are reclaimed at procedure +exit, avoiding memory leakage. + + +However, if your procedure needs to return an allocated memory object +(such as a value of a pass-by-reference datatype), you can't allocate +the return object using palloc, at least not while +you are connected to SPI. If you try, the object will be deallocated +during SPI_finish, and your procedure will not +work reliably! + + +To solve this problem, use SPI_palloc to allocate +your return object. SPI_palloc allocates space +from upper Executor memory --- that is, the memory context +that was current when SPI_connect was called, +which is precisely the right context for return values of your procedure. + + +If called while not connected to SPI, SPI_palloc +acts the same as plain palloc. + + + Before a procedure connects to the SPI manager, the current memory context +is the upper Executor context, so all allocations made by the procedure via +palloc or by SPI utility functions are +made in this context. + + + After SPI_connect is called, the current context is + the procedure's private context made by SPI_connect. + All allocations made via +palloc/repalloc or by SPI utility +functions (except for SPI_copytuple, +SPI_copytupledesc, +SPI_copytupleintoslot, +SPI_modifytuple, +and SPI_palloc) are +made in this context. + + +When a procedure disconnects from the SPI manager (via +SPI_finish) the +current context is restored to the upper Executor context, and all allocations +made in the procedure memory context are freed and can't be used any more! + + + +All functions described in this section may be used by both connected and +unconnected procedures. In an unconnected procedure, they act the same +as the underlying ordinary backend functions (palloc etc). + + + + + + + + +SPI_copytuple +SPI - Tuple Copy + + +SPI_copytuple + + +Makes copy of tuple in upper Executor context + +SPIcopying tuples +SPI_copytuple + + + +1997-12-24 + + +SPI_copytuple(tuple) + + + + +1997-12-24 + +Inputs + + + + +HeapTuple tuple + + + +Input tuple to be copied + + + + + + + + +1997-12-24 + +Outputs + + + + +HeapTuple + + + +Copied tuple + + + non-NULL + if tuple + is not NULL and the copy was successful + + + NULL + only if tuple + is NULL + + + + + + + + + + + +1997-12-24 + +Description + + +SPI_copytuple + makes a copy of tuple in upper Executor context. + + + +Usage + + +TBD + + + + + + + + + + + + +SPI_copytupledesc +SPI - Tuple Descriptor Copy + + +SPI_copytupledesc + + +Makes copy of tuple descriptor in upper Executor context + +SPIcopying tuple descriptors +SPI_copytupledesc + + + +2001-08-02 + + +SPI_copytupledesc(tupdesc) + + + + +2001-08-02 + +Inputs + + + + +TupleDesc tupdesc + + + +Input tuple descriptor to be copied + + + + + + + + +2001-08-02 + +Outputs + + + + +TupleDesc + + + +Copied tuple descriptor + + + non-NULL + if tupdesc + is not NULL and the copy was successful + + + NULL + only if tupdesc + is NULL + + + + + + + + + + + +2001-08-02 + +Description + + +SPI_copytupledesc + makes a copy of tupdesc in upper Executor context. + + + +Usage + + +TBD + + + + + + + + + + + + +SPI_copytupleintoslot +SPI - Tuple and Descriptor Copy + + +SPI_copytupleintoslot + + +Makes copy of tuple and descriptor in upper Executor context + +SPIcopying tuples +SPI_copytupleintoslot + + + +1997-12-24 + + +SPI_copytupleintoslot(tuple, tupdesc) + + + + +1997-12-24 + +Inputs + + + + +HeapTuple tuple + + + +Input tuple to be copied + + + + + +TupleDesc tupdesc + + + +Input tuple descriptor to be copied + + + + + + + + +1997-12-24 + +Outputs + + + + +TupleTableSlot * + + + +Tuple slot containing copied tuple and descriptor + + + non-NULL + if tuple + and tupdesc + are not NULL and the copy was successful + + + NULL + only if tuple + or tupdesc + is NULL + + + + + + + + + + + +1997-12-24 + +Description + + +SPI_copytupleintoslot + makes a copy of tuple in upper Executor context, returning it in the + form of a filled-in TupleTableSlot. + + + +Usage + + +TBD + + + + + + + + + + + + +SPI_modifytuple +SPI - Tuple Modify + + +SPI_modifytuple + + +Creates a tuple by replacing selected fields of a given tuple + +SPImodifying tuples +SPI_modifytuple + + + +1997-12-24 + + +SPI_modifytuple(rel, tuple, nattrs, attnum, Values, Nulls) + + + + +1997-12-24 + +Inputs + + + + +Relation rel + + + +Used only as source of tuple descriptor for tuple. (Passing a relation +rather than a tuple descriptor is a misfeature.) + + + + + +HeapTuple tuple + + + +Input tuple to be modified + + + + + +int nattrs + + + +Number of attribute numbers in attnum array + + + + + +int * attnum + + + +Array of numbers of the attributes that are to be changed + + + + + +Datum * Values + + + +New values for the attributes specified + + + + + +char * Nulls + + + +Which new values are NULL, if any + + + + + + + + +1997-12-24 + +Outputs + + + + +HeapTuple + + + +New tuple with modifications + + + non-NULL + if tuple + is not NULL and the modify was successful + + + NULL + only if tuple + is NULL + + + + + + + +SPI_result + + + + + + SPI_ERROR_ARGUMENT if rel is NULL or tuple is NULL or natts <= 0 or + attnum is NULL or Values is NULL. + + + SPI_ERROR_NOATTRIBUTE if there is an invalid + attribute number in attnum (attnum <= 0 or > number of + attributes in tuple) + + + + + + + + + + + +1997-12-24 + +Description + + +SPI_modifytuple +creates a new tuple by substituting new values for selected attributes, +copying the original tuple's attributes at other positions. The input +tuple is not modified. + + + +Usage + + +If successful, a pointer to the new tuple is returned. The new tuple is +allocated in upper Executor context. + + + + + + @@ -2538,7 +3246,7 @@ New storage space of specified size SPI_palloc - allocates memory in upper Executor context. See section on memory management. + allocates memory in upper Executor context. @@ -2652,14 +3360,15 @@ New storage space of specified size with contents copied from existing area SPI_repalloc - re-allocates memory in upper Executor context. See section on memory management. + re-allocates memory in upper Executor context. Usage -TBD +This function is no longer different from plain repalloc. +It's kept just for backward compatibility of existing code. - - + + + - -Memory Management + + +SPI_freetuple +SPI - Memory Management + + +SPI_freetuple + + +Frees a tuple allocated in upper Executor context + +SPIallocating space +SPI_freetuple + + + +1997-12-24 + + +SPI_freetuple(pointer) + + + +1997-12-24 + +Inputs + + + + +HeapTuple pointer + + + +Pointer to allocated tuple + + + + + + + + +1997-12-24 + +Outputs + + + + +None + + + + + + + + + + + + +1997-12-24 + +Description + + +SPI_freetuple + frees a tuple previously allocated in upper Executor context. + + + +Usage + - Server allocates memory in memory contexts in such way that allocations -made in one context may be freed by context destruction without affecting -allocations made in other contexts. All allocations (via palloc, etc) are -made in the context that is chosen as the current one. You'll get -unpredictable results if you'll try to free (or reallocate) memory allocated -not in current context. - +This function is no longer different from plain heap_freetuple. +It's kept just for backward compatibility of existing code. + + + + + + + + + +SPI_freetuptable +SPI - Memory Management + + +SPI_freetuptable + + +Frees a tuple set created by SPI_exec or similar function + +SPIallocating space +SPI_freetuptable + + + +2001-11-14 + + +SPI_freetuptable(tuptable) + + + + +2001-11-14 + +Inputs + + + + +SPITupleTable * tuptable + + + +Pointer to tuple table + + + + + + + + +2001-11-14 + +Outputs + + + + +None + + + + + + + + + + + + +2001-11-14 + +Description + + +SPI_freetuptable + frees a tuple set created by a prior SPI query function, such as + SPI_exec. + + + +Usage + - Creation and switching between memory contexts are subject of SPI manager -memory management. - +This function is useful if a SPI procedure needs to execute multiple +queries and does not want to keep the results of earlier queries around +until it ends. Note that any unfreed tuple sets will be freed anyway +at SPI_finish. + + + - + + + - SPI procedures deal with two memory contexts: upper Executor memory -context and procedure memory context (if connected). - + + +SPI_freeplan +SPI - Memory Management + + +SPI_freeplan + + + Releases a previously saved plan + +SPIallocating space +SPI_freeplan + + + +2001-11-14 + + +SPI_freeplan(plan) + - + + +2001-11-14 + +Inputs + + + + +void *plan + + + +Passed plan + + + + + - Before a procedure is connected to the SPI manager, current memory context -is upper Executor context so all allocation made by the procedure itself via -palloc/repalloc or by SPI utility functions before connecting to SPI are -made in this context. - + + +2001-11-14 + +Outputs + + + +int + + + + + + SPI_ERROR_ARGUMENT if plan is NULL + + + + + + + + - - - After SPI_connect is called current context is the - procedure's one. All allocations made via -palloc/repalloc or by SPI utility -functions (except for SPI_copytuple, -SPI_copytupledesc, -SPI_copytupleintoslot, -SPI_modifytuple, -SPI_palloc and SPI_repalloc) are -made in this context. - - - - - When a procedure disconnects from the SPI manager (via SPI_finish) the -current context is restored to the upper Executor context and all allocations -made in the procedure memory context are freed and can't be used any more! - - - - - If you want to return something to the upper Executor then you have to -allocate memory for this in the upper context! - - - - - SPI has no ability to automatically free allocations in the upper Executor -context! - - - - - SPI automatically frees memory allocated during execution of a query when -this query is done! - + + +2001-11-14 + +Description + + +SPI_freeplan + releases a query plan previously returned by + SPI_prepare or saved by + SPI_saveplan. + + + @@ -2864,9 +3748,9 @@ this query is done! Postgres data changes visibility rule: during a query execution, data changes made by the query itself (via SQL-function, SPI-function, triggers) are invisible to the query scan. For example, in query - + INSERT INTO a SELECT * FROM a - + tuples inserted are invisible for SELECT's scan. In effect, this duplicates the database table within itself (subject to unique index rules, of course) without recursing.