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 | 2032 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 1458 insertions(+), 574 deletions(-) diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index 5f9aa5b6c8..9e4ce00fb0 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. @@ -370,9 +383,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. + + - 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. + 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. + + - 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 + + 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. + - 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. + 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. - - Execution of prepared execution plans is sometimes much faster so this - feature may be useful if the same query will be executed many times. + + + 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,149 +726,6 @@ TBD - - -SPI_saveplan -SPI - Plan Storage - - -SPI_saveplan - - - Saves a passed plan - -SPIconnecting -SPI_saveplan - - - -1997-12-24 - - -SPI_saveplan(plan) - - - - -1997-12-24 - -Inputs - - - - -void *query - - - -Passed plan - - - - - - - - -1997-12-24 - -Outputs - - - -void * - - - -Execution plan location. NULL if unsuccessful. - - - - -SPI_result - - - - - - SPI_ERROR_ARGUMENT if plan is NULL - - - SPI_ERROR_UNCONNECTED if procedure is un-connected - - - - - - - - - - - -1997-12-24 - -Description - - -SPI_saveplan - 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 an alternative, 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 - - - SPI_saveplan saves a passed plan (prepared by SPI_prepare) in memory - protected from freeing by SPI_finish and by the transaction manager and - returns a pointer to the saved plan. 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 (see below). - - - - 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_execp @@ -844,7 +735,7 @@ TBD SPI_execp -Executes a plan from SPI_saveplan +Executes a plan from SPI_prepare SPIconnecting SPI_execp @@ -893,10 +784,10 @@ char *nulls -Array describing what parameters get NULLs +Array describing which parameters are NULLs -n indicates NULL allowed -A space indicates NULL not allowed +n indicates NULL (values[] entry ignored) +space indicates not NULL (values[] entry is valid) @@ -976,19 +867,10 @@ initialized as in SPI_execp - stores a plan prepared by SPI_prepare in safe memory - protected from freeing by SPI_finish or the transaction manager. + executes a plan prepared by SPI_prepare. + tcount has the same + interpretation as in SPI_exec. - - 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 @@ -997,7 +879,7 @@ initialized as in If <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE> is NULL then <Function>SPI_execp</Function> -assumes that all values (if any) are NOT NULL. +assumes that all parameters (if any) are NOT NULL. <Note> <Para> @@ -1028,88 +910,102 @@ TBD --> </REFENTRY> -</Sect1> - -<Sect1 id="spi-interface-support"> -<Title>Interface Support Functions - - -All functions described below may be used by connected and unconnected -procedures. - - - + -SPI_copytuple -SPI - Tuple Copy +SPI_cursor_open +SPI - Cursor Support -SPI_copytuple +SPI_cursor_open -Makes copy of tuple in upper Executor context +Sets up a cursor using a plan created with SPI_prepare -SPIcopying tuples -SPI_copytuple +SPIcursors +SPI_cursor_open -1997-12-24 +2001-11-14 -SPI_copytuple(tuple) +SPI_cursor_open(name, +plan, +values, +nulls) - + -1997-12-24 +2001-11-14 Inputs -HeapTuple tuple +char *name -Input tuple to be copied +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) + - + -1997-12-24 +2001-11-14 Outputs - -HeapTuple +Portal -Copied tuple - - - non-NULL - if tuple - is not NULL and the copy was successful - - - NULL - only if tuple - is NULL - - + Pointer to Portal containing cursor, or NULL on error @@ -1117,37 +1013,42 @@ Copied tuple - + -1997-12-24 +2001-11-14 Description -SPI_copytuple - makes a copy of tuple in upper Executor context. See the section on Memory Management. - +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 -TBD + If nulls +is NULL then + SPI_cursor_open +assumes that all parameters (if any) are NOT NULL. - @@ -1157,74 +1058,61 @@ TBD - + -SPI_copytupledesc -SPI - Tuple Descriptor Copy +SPI_cursor_find +SPI - Cursor Support -SPI_copytupledesc +SPI_cursor_find -Makes copy of tuple descriptor in upper Executor context +Finds an existing cursor (Portal) by name -SPIcopying tuple descriptors -SPI_copytupledesc +SPIcursors +SPI_cursor_find -2001-08-02 +2001-11-14 -SPI_copytupledesc(tupdesc) +SPI_cursor_find(name) - + -2001-08-02 +2001-11-14 Inputs -TupleDesc tupdesc +char *name -Input tuple descriptor to be copied +Name of portal - + -2001-08-02 +2001-11-14 Outputs - -TupleDesc +Portal -Copied tuple descriptor - - - non-NULL - if tupdesc - is not NULL and the copy was successful - - - NULL - only if tupdesc - is NULL - - + Pointer to Portal with given name, or NULL if not found @@ -1232,37 +1120,32 @@ Copied tuple descriptor - + -2001-08-02 +2001-11-14 Description -SPI_copytupledesc - makes a copy of tupdesc in upper Executor context. See the section on Memory Management. - +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. + - + @@ -1272,126 +1155,127 @@ TBD - + -SPI_copytupleintoslot -SPI - Tuple and Descriptor Copy +SPI_cursor_fetch +SPI - Cursor Support -SPI_copytupleintoslot +SPI_cursor_fetch -Makes copy of tuple and descriptor in upper Executor context +Fetches some rows from a cursor -SPIcopying tuples -SPI_copytupleintoslot +SPIcursors +SPI_cursor_fetch -1997-12-24 +2001-11-14 -SPI_copytupleintoslot(tuple, tupdesc) +SPI_cursor_fetch(portal, +forward, +count) - + -1997-12-24 +2001-11-14 Inputs -HeapTuple tuple +Portal portal -Input tuple to be copied +Portal containing cursor -TupleDesc tupdesc +bool forward -Input tuple descriptor to be copied +True for fetch forward, false for fetch backward + + + + + +int count + + + +Maximum number of rows to fetch - + -1997-12-24 +2001-11-14 Outputs - -TupleTableSlot * +SPI_tuptable -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 - - - +initialized as in + SPI_exec if successful + + +SPI_processed + + + +initialized as in + SPI_exec if successful + + + - + -1997-12-24 +2001-11-14 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. - +SPI_cursor_fetch + fetches some (more) rows from a cursor. This is equivalent to the + SQL command FETCH. + - + @@ -1401,184 +1285,115 @@ TBD - + -SPI_modifytuple -SPI - Tuple Modify +SPI_cursor_move +SPI - Cursor Support -SPI_modifytuple +SPI_cursor_move -Modifies tuple of relation +Moves a cursor -SPImodifying tuples -SPI_modifytuple +SPIcursors +SPI_cursor_move -1997-12-24 +2001-11-14 -SPI_modifytuple(rel, tuple , nattrs -, attnum , Values , Nulls) +SPI_cursor_move(portal, +forward, +count) - + -1997-12-24 +2001-11-14 Inputs -Relation rel - - - - - - - - -HeapTuple tuple - - - -Input tuple to be modified - - - - - -int nattrs - - - -Number of attribute numbers in attnum - - - - - -int * attnum +Portal portal -Array of numbers of the attributes that are to be changed +Portal containing cursor -Datum * Values +bool forward -New values for the attributes specified +True for move forward, false for move backward -char * Nulls +int count -Which attributes are NULL, if any +Maximum number of rows to move - + -1997-12-24 +2001-11-14 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 +None - - - 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 +2001-11-14 Description -SPI_modifytuple -Modifies a tuple in upper Executor context. See the section on Memory Management. - +SPI_cursor_move + skips over some number of rows in a cursor. This is equivalent to the + SQL command MOVE. + - + @@ -1588,29 +1403,284 @@ is not changed. - + -SPI_fnumber -SPI - Tuple Information +SPI_cursor_close +SPI - Cursor Support -SPI_fnumber +SPI_cursor_close -Finds the attribute number for specified attribute +Closes a cursor -SPIdecoding tuples -SPI_fnumber +SPIcursors +SPI_cursor_close -1997-12-24 +2001-11-14 -SPI_fnumber(tupdesc, fname) +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 +SPI - Plan Storage + + +SPI_saveplan + + + Saves a passed plan + +SPIconnecting +SPI_saveplan + + + +1997-12-24 + + +SPI_saveplan(plan) + + + + +1997-12-24 + +Inputs + + + + +void *query + + + +Passed plan + + + + + + + + +1997-12-24 + +Outputs + + + +void * + + + +Execution plan location. NULL if unsuccessful. + + + + +SPI_result + + + + + + SPI_ERROR_ARGUMENT if plan is NULL + + + SPI_ERROR_UNCONNECTED if procedure is un-connected + + + + + + + + + + + +1997-12-24 + +Description + + +SPI_saveplan + 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 an alternative, there is the ability to reuse prepared plans in the + subsequent invocations of your procedure in the current session. + Use SPI_execp to execute this saved plan. + + + +Usage + + + SPI_saveplan saves a passed plan (prepared by SPI_prepare) in memory + protected from freeing by SPI_finish and by the transaction manager and + returns a pointer to the saved plan. 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 (see below). + + + + 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 + + +The functions described here provide convenient interfaces for extracting +information from tuple sets returned by SPI_exec and other +SPI interface functions. + + + +All functions described in this section may be used by both connected and +unconnected procedures. + + + + + + + + +SPI_fnumber +SPI - Tuple Information + + +SPI_fnumber + + +Finds the attribute number for specified attribute name + +SPIdecoding tuples +SPI_fnumber + + + +1997-12-24 + + +SPI_fnumber(tupdesc, fname) + + + 1997-12-24 @@ -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 + + +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_getrelname - returns the name of the specified relation. +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 -TBD +If successful, a pointer to the new tuple is returned. The new tuple is +allocated in upper Executor context. - + + + + + + +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 + + -TBD +Pointer to allocated tuple + + + + + + + + +1997-12-24 + +Outputs + + + + +None + + + + + + + + + + + + +1997-12-24 + +Description + + +SPI_freetuple + frees a tuple previously allocated in upper Executor context. ---> - - - - -Memory Management - - - 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. - - - - Creation and switching between memory contexts are subject of SPI manager -memory management. - - - - - SPI procedures deal with two memory contexts: upper Executor memory -context and procedure memory context (if connected). - - - - - 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. - - - + + + - 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. - + + +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 + + + + + - 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! - + + +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 + +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. + + + - If you want to return something to the upper Executor then you have to -allocate memory for this in the upper context! - + + + - + + +SPI_freeplan +SPI - Memory Management + + +SPI_freeplan + + + Releases a previously saved plan + +SPIallocating space +SPI_freeplan + + + +2001-11-14 + + +SPI_freeplan(plan) + - SPI has no ability to automatically free allocations in the upper Executor -context! - + + +2001-11-14 + +Inputs + + + + +void *plan + + + +Passed plan + + + + + - + + +2001-11-14 + +Outputs + + + +int + + + + + + SPI_ERROR_ARGUMENT if plan is NULL + + + + + + + + - 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. -- 2.11.0