2 $Header: /cvsroot/pgsql/doc/src/sgml/spi.sgml,v 1.19 2001/11/14 22:26:02 tgl Exp $
9 <FirstName>Vadim</FirstName>
10 <Surname>Mikheev</Surname>
13 <Date>Transcribed 1998-01-16</Date>
16 <Title>Server Programming Interface</Title>
19 The <FirstTerm>Server Programming Interface</FirstTerm>
20 (<Acronym>SPI</Acronym>) gives users the
21 ability to run <Acronym>SQL</Acronym> queries inside user-defined
22 <Acronym>C</Acronym> functions.
27 The available Procedural Languages (<Acronym>PL</Acronym>) give an alternate
28 means to build functions that can execute queries.
33 In fact, <Acronym>SPI</Acronym> is just a set of native interface functions
34 to simplify access to the Parser, Planner, Optimizer and Executor.
35 <Acronym>SPI</Acronym> also does some memory management.
39 To avoid misunderstanding we'll use <FirstTerm>function</FirstTerm>
40 to mean <Acronym>SPI</Acronym> interface functions and
41 <FirstTerm>procedure</FirstTerm> for user-defined C-functions
42 using <Acronym>SPI</Acronym>.
46 Procedures which use <Acronym>SPI</Acronym> are called by the
47 Executor. The <Acronym>SPI</Acronym> calls recursively invoke the
48 Executor in turn to run queries. When the Executor is invoked
49 recursively, it may itself call procedures which may make
50 <Acronym>SPI</Acronym> calls.
54 Note that if during execution of a query from a procedure the transaction is
55 aborted, then control will not be returned to your procedure. Rather, all work
56 will be rolled back and the server will wait for the next command from the
57 client. This will probably be changed in future versions.
61 A related restriction is the inability to execute BEGIN, END and ABORT
62 (transaction control statements). This will also be
63 changed in the future.
67 If successful, <Acronym>SPI</Acronym> functions return a non-negative result (either via
68 a returned integer value or in SPI_result global variable, as described below).
69 On error, a negative or NULL result will be returned.
72 <Sect1 id="spi-interface">
73 <Title>Interface Functions</Title>
75 <REFENTRY ID="SPI-SPICONNECT">
77 <REFENTRYTITLE>SPI_connect</REFENTRYTITLE>
78 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
84 Connects your procedure to the SPI manager.
86 <INDEXTERM ID="IX-SPI-SPICONNECT-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
87 <INDEXTERM ID="IX-SPI-SPICONNECT-2"><PRIMARY>SPI_connect</PRIMARY></INDEXTERM>
91 <DATE>1997-12-24</DATE>
97 <REFSECT2 ID="R2-SPI-SPICONNECT-1">
99 <DATE>1997-12-24</DATE>
107 <REFSECT2 ID="R2-SPI-SPICONNECT-2">
109 <DATE>1997-12-24</DATE>
122 <TERM><ReturnValue>SPI_OK_CONNECT</ReturnValue>
131 <TERM><ReturnValue>SPI_ERROR_CONNECT</ReturnValue>
147 <REFSECT1 ID="R1-SPI-SPICONNECT-1">
149 <DATE>1997-12-24</DATE>
154 <FUNCTION>SPI_connect</FUNCTION> opens a connection from a procedure
155 invocation to the SPI manager.
156 You must call this function if you will need to execute queries. Some
157 utility SPI functions may be called from un-connected procedures.
160 If your procedure is already connected,
161 <Function>SPI_connect</Function> will return an
162 <ReturnValue>SPI_ERROR_CONNECT</ReturnValue> error. Note that this
163 may happen if a procedure which has called
164 <Function>SPI_connect</Function> directly calls another procedure
165 which itself calls <Function>SPI_connect</Function>. While
166 recursive calls to the <Acronym>SPI</Acronym> manager are permitted
167 when an <Acronym>SPI</Acronym> query invokes another function which
168 uses <Acronym>SPI</Acronym>, directly nested calls to
169 <Function>SPI_connect</Function> and
170 <Function>SPI_finish</Function> are forbidden.
173 <REFSECT1 ID="R1-SPI-SPICONNECT-2">
178 XXX thomas 1997-12-24
182 <REFSECT1 ID="R1-SPI-SPICONNECT-3">
185 <PARA><FUNCTION>SPI_connect</FUNCTION> performs the following:
186 Initializes the SPI internal
187 structures for query execution and memory management.
191 <REFSECT1 ID="R1-SPI-SPICONNECT-4">
200 <!-- *********************************************** -->
201 <!-- *********************************************** -->
202 <!-- *********************************************** -->
204 <REFENTRY ID="SPI-SPIFINISH">
206 <REFENTRYTITLE>SPI_finish</REFENTRYTITLE>
207 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
213 Disconnects your procedure from the SPI manager.
215 <INDEXTERM ID="IX-SPI-SPIFINISH-1"><PRIMARY>SPI</PRIMARY><SECONDARY>disconnecting</SECONDARY></INDEXTERM>
216 <INDEXTERM ID="IX-SPI-SPIFINISH-2"><PRIMARY>SPI_finish</PRIMARY></INDEXTERM>
220 <DATE>1997-12-24</DATE>
221 </REFSYNOPSISDIVINFO>
226 <REFSECT2 ID="R2-SPI-SPIFINISH-1">
228 <DATE>1997-12-24</DATE>
236 <REFSECT2 ID="R2-SPI-SPIFINISH-2">
238 <DATE>1997-12-24</DATE>
250 <ReturnValue>SPI_OK_FINISH</ReturnValue>
251 if properly disconnected
254 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue>
255 if called from an un-connected procedure
265 <REFSECT1 ID="R1-SPI-SPIFINISH-1">
267 <DATE>1997-12-24</DATE>
272 <FUNCTION>SPI_finish</FUNCTION> closes an existing connection to the
274 You must call this function after completing the SPI operations needed
275 during your procedure's current invocation.
278 You may get the error return <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if <Function>SPI_finish</Function> is
279 called without having a current valid connection.
280 There is no fundamental problem
281 with this; it means that nothing was done by the SPI manager.
284 <REFSECT1 ID="R1-SPI-SPIFINISH-2">
288 <Function>SPI_finish</Function> <Emphasis>must</Emphasis> be called as a final step by a connected procedure,
290 unpredictable results! However, you do not need to worry about making
291 this happen if the transaction is aborted via elog(ERROR). In that case
292 SPI will clean itself up.
296 <REFSECT1 ID="R1-SPI-SPIFINISH-3">
299 <PARA><FUNCTION>SPI_finish</FUNCTION> performs the following:
300 Disconnects your procedure from the SPI manager and frees all memory
301 allocations made by your procedure via <Function>palloc</Function> since
302 the <Function>SPI_connect</Function>.
303 These allocations can't be used any more! See Memory management.
307 <REFSECT1 ID="R1-SPI-SPIFINISH-4">
316 <!-- *********************************************** -->
317 <!-- *********************************************** -->
318 <!-- *********************************************** -->
320 <REFENTRY ID="SPI-SPIEXEC">
322 <REFENTRYTITLE>SPI_exec</REFENTRYTITLE>
323 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
329 Creates an execution plan (parser+planner+optimizer) and executes a query.
331 <INDEXTERM ID="IX-SPI-SPIEXEC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>executing</SECONDARY></INDEXTERM>
332 <INDEXTERM ID="IX-SPI-SPIEXEC-2"><PRIMARY>SPI_exec</PRIMARY></INDEXTERM>
336 <DATE>1997-12-24</DATE>
337 </REFSYNOPSISDIVINFO>
339 SPI_exec(<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>)
342 <REFSECT2 ID="R2-SPI-SPIEXEC-1">
344 <DATE>1997-12-24</DATE>
351 char *<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
355 String containing query plan
361 int <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>
365 Maximum number of tuples to return
372 <REFSECT2 ID="R2-SPI-SPIEXEC-2">
374 <DATE>1997-12-24</DATE>
386 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if called from an un-connected procedure
389 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0.
392 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is unconnected.
395 <ReturnValue>SPI_ERROR_COPY</ReturnValue> if COPY TO/FROM stdin.
398 <ReturnValue>SPI_ERROR_CURSOR</ReturnValue> if DECLARE/CLOSE CURSOR, FETCH.
401 <ReturnValue>SPI_ERROR_TRANSACTION</ReturnValue> if BEGIN/ABORT/END.
404 <ReturnValue>SPI_ERROR_OPUNKNOWN</ReturnValue> if type of query is unknown (this shouldn't occur).
409 If execution of your query was successful then one of the following
410 (non-negative) values will be returned:
413 <ReturnValue>SPI_OK_UTILITY</ReturnValue> if some utility (e.g. CREATE TABLE ...) was executed
416 <ReturnValue>SPI_OK_SELECT</ReturnValue> if SELECT (but not SELECT ... INTO!) was executed
419 <ReturnValue>SPI_OK_SELINTO</ReturnValue> if SELECT ... INTO was executed
422 <ReturnValue>SPI_OK_INSERT</ReturnValue> if INSERT (or INSERT ... SELECT) was executed
425 <ReturnValue>SPI_OK_DELETE</ReturnValue> if DELETE was executed
428 <ReturnValue>SPI_OK_UPDATE</ReturnValue> if UPDATE was executed
438 <REFSECT1 ID="R1-SPI-SPIEXEC-1">
440 <DATE>1997-12-24</DATE>
445 <FUNCTION>SPI_exec</FUNCTION> creates an execution plan (parser+planner+optimizer)
446 and executes the query for <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> tuples.
450 <REFSECT1 ID="R1-SPI-SPIEXEC-2">
454 This should only be called from a connected procedure.
455 If <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> is zero then it executes the query for all tuples returned by the
456 query scan. Using <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> > 0 you may restrict the number of tuples for
457 which the query will be executed (much like a LIMIT clause). For example,
460 SPI_exec ("INSERT INTO tab SELECT * FROM tab", 5);
463 will allow at most 5 tuples to be inserted into table.
465 If execution of your query was successful then a non-negative value will be returned.
469 You may pass multiple queries in one string or query string may be
470 re-written by RULEs. <Function>SPI_exec</Function> returns the result for the last query
476 The actual number of tuples for which the (last) query was executed is
477 returned in the global variable SPI_processed (if not <ReturnValue>SPI_OK_UTILITY</ReturnValue>).
479 If <ReturnValue>SPI_OK_SELECT</ReturnValue> is returned and SPI_processed > 0 then you may use global
480 pointer SPITupleTable *SPI_tuptable to access the result tuples.
484 <Function>SPI_exec</Function> may return one of the following (negative) values:
487 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0.
490 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is unconnected.
493 <ReturnValue>SPI_ERROR_COPY</ReturnValue> if COPY TO/FROM stdin.
496 <ReturnValue>SPI_ERROR_CURSOR</ReturnValue> if DECLARE/CLOSE CURSOR, FETCH.
499 <ReturnValue>SPI_ERROR_TRANSACTION</ReturnValue> if BEGIN/ABORT/END.
502 <ReturnValue>SPI_ERROR_OPUNKNOWN</ReturnValue> if type of query is unknown (this shouldn't occur).
509 <REFSECT1 ID="R1-SPI-SPIEXEC-3">
516 <REFSECT1 ID="R1-SPI-SPIEXEC-4">
520 If <ReturnValue>SPI_OK_SELECT</ReturnValue> is returned and SPI_processed > 0 then you may use the global
521 pointer SPITupleTable *SPI_tuptable to access the selected tuples.
525 Structure SPITupleTable is defined in spi.h:
529 MemoryContext tuptabcxt; /* memory context of result table */
530 uint32 alloced; /* # of alloced vals */
531 uint32 free; /* # of free vals */
532 TupleDesc tupdesc; /* tuple descriptor */
533 HeapTuple *vals; /* tuples */
539 vals is an array of pointers to tuples (the number of useful entries
540 is given by SPI_processed). TupleDesc tupdesc is
541 a tuple descriptor which you may pass to SPI functions dealing with
542 tuples. tuptabcxt, alloced, and free are internal fields not intended
543 for use by SPI callers.
548 Functions <Function>SPI_exec</Function>, <Function>SPI_execp</Function> and
549 <Function>SPI_prepare</Function> change both SPI_processed and SPI_tuptable
550 (just the pointer, not the contents of the structure).
551 Save these two global variables into local procedure variables if you need
552 to access the result of one <Function>SPI_exec</Function> or
553 <Function>SPI_execp</Function> across later calls.
558 <Function>SPI_finish</Function> frees all SPITupleTables allocated during
559 the current procedure. You can free a particular result table earlier,
560 if you are done with it, by calling <Function>SPI_freetuptable</Function>.
565 <!-- *********************************************** -->
566 <!-- *********************************************** -->
567 <!-- *********************************************** -->
569 <REFENTRY ID="SPI-SPIPREPARE">
571 <REFENTRYTITLE>SPI_prepare</REFENTRYTITLE>
572 <REFMISCINFO>SPI - Plan Preparation</REFMISCINFO>
578 Prepares a plan for a query, without executing it yet
580 <INDEXTERM ID="IX-SPI-SPIPREPARE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
581 <INDEXTERM ID="IX-SPI-SPIPREPARE-2"><PRIMARY>SPI_prepare</PRIMARY></INDEXTERM>
585 <DATE>1997-12-24</DATE>
586 </REFSYNOPSISDIVINFO>
588 SPI_prepare(<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">nargs</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">argtypes</REPLACEABLE>)
591 <REFSECT2 ID="R2-SPI-SPIPREPARE-1">
593 <DATE>1997-12-24</DATE>
600 <REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
610 <REPLACEABLE CLASS="PARAMETER">nargs</REPLACEABLE>
614 Number of input parameters ($1 ... $nargs - as in SQL-functions)
620 <REPLACEABLE CLASS="PARAMETER">argtypes</REPLACEABLE>
624 Pointer to array of type <Acronym>OID</Acronym>s for input parameter types
631 <REFSECT2 ID="R2-SPI-SPIPREPARE-2">
633 <DATE>1997-12-24</DATE>
643 Pointer to an execution plan (parser+planner+optimizer)
651 <REFSECT1 ID="R1-SPI-SPIPREPARE-1">
653 <DATE>1997-12-24</DATE>
658 <FUNCTION>SPI_prepare</FUNCTION>
659 creates and returns an execution plan (parser+planner+optimizer) but doesn't
660 execute the query. Should only be called from a connected procedure.
664 <REFSECT1 ID="R1-SPI-SPIPREPARE-2">
668 When the same or similar query is to be executed repeatedly, it may
669 be advantageous to perform query planning only once.
670 <FUNCTION>SPI_prepare</FUNCTION> converts a query string into an execution
671 plan that can be passed repeatedly to <FUNCTION>SPI_execp</FUNCTION>.
674 A prepared query can be generalized by writing parameters ($1, $2, etc)
675 in place of what would be constants in a normal query. The values of
676 the parameters are then specified when <FUNCTION>SPI_execp</FUNCTION>
677 is called. This allows the prepared query to be used over a wider
678 range of situations than would be possible without parameters.
682 However, there is a disadvantage: since the planner does not know the
683 values that will be supplied for the parameters, it may make worse
684 query planning choices than it would make for a simple query with
685 all constants visible.
689 If the query uses parameters, their number and datatypes must be
690 specified in the call to <FUNCTION>SPI_prepare</FUNCTION>.
693 The plan returned by <Function>SPI_prepare</Function> may be used only in current
694 invocation of the procedure since <Function>SPI_finish</Function> frees memory allocated for a plan.
695 But see <Function>SPI_saveplan</Function> to save a plan for longer.
698 If successful, a non-null pointer will be returned. Otherwise, you'll get
699 a NULL plan. In both cases SPI_result will be set like the value returned
700 by SPI_exec, except that it is set to
701 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or nargs < 0 or nargs > 0 && argtypes
707 <REFSECT1 ID="R1-SPI-SPIPREPARE-3">
710 <PARA><FUNCTION>SPI_prepare</FUNCTION> performs the following:
716 <REFSECT1 ID="R1-SPI-SPIPREPARE-4">
725 <!-- *********************************************** -->
726 <!-- *********************************************** -->
727 <!-- *********************************************** -->
729 <REFENTRY ID="SPI-SPIEXECP">
731 <REFENTRYTITLE>SPI_execp</REFENTRYTITLE>
732 <REFMISCINFO>SPI - Plan Execution</REFMISCINFO>
738 Executes a plan from <Function>SPI_prepare</Function>
740 <INDEXTERM ID="IX-SPI-SPIEXECP-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
741 <INDEXTERM ID="IX-SPI-SPIEXECP-2"><PRIMARY>SPI_execp</PRIMARY></INDEXTERM>
745 <DATE>1997-12-24</DATE>
746 </REFSYNOPSISDIVINFO>
748 SPI_execp(<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>,
749 <REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>,
750 <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>,
751 <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>)
754 <REFSECT2 ID="R2-SPI-SPIEXECP-1">
756 <DATE>1997-12-24</DATE>
763 void *<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
773 Datum *<REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
777 Actual parameter values
783 char *<REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
787 Array describing which parameters are NULLs
789 <Member><literal>n</literal> indicates NULL (values[] entry ignored)</Member>
790 <Member>space indicates not NULL (values[] entry is valid)</Member>
797 int <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>
801 Number of tuples for which plan is to be executed
808 <REFSECT2 ID="R2-SPI-SPIEXECP-2">
810 <DATE>1997-12-24</DATE>
820 Returns the same value as <Function>SPI_exec</Function> as well as
823 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue>
824 if <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
825 is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0
828 <ReturnValue>SPI_ERROR_PARAM</ReturnValue>
829 if <REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
831 and <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
832 was prepared with some parameters.
844 <Function>SPI_exec</Function> if successful
854 <Function>SPI_exec</Function> if successful
862 <REFSECT1 ID="R1-SPI-SPIEXECP-1">
864 <DATE>1997-12-24</DATE>
869 <FUNCTION>SPI_execp</FUNCTION>
870 executes a plan prepared by <Function>SPI_prepare</Function>.
871 <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> has the same
872 interpretation as in <Function>SPI_exec</Function>.
875 <REFSECT1 ID="R1-SPI-SPIEXECP-2">
879 If <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
881 <Function>SPI_execp</Function>
882 assumes that all parameters (if any) are NOT NULL.
886 If one of the objects (a relation, function, etc.) referenced by the prepared
887 plan is dropped during your session (by your backend or another process) then the
888 results of <Function>SPI_execp</Function> for this plan will be unpredictable.
895 <REFSECT1 ID="R1-SPI-SPIEXECP-3">
898 <PARA><FUNCTION>SPI_execp</FUNCTION> performs the following:
904 <REFSECT1 ID="R1-SPI-SPIEXECP-4">
913 <!-- *********************************************** -->
914 <!-- *********************************************** -->
915 <!-- *********************************************** -->
917 <REFENTRY ID="SPI-SPICURSOR-OPEN">
919 <REFENTRYTITLE>SPI_cursor_open</REFENTRYTITLE>
920 <REFMISCINFO>SPI - Cursor Support</REFMISCINFO>
923 <REFNAME>SPI_cursor_open
926 Sets up a cursor using a plan created with <Function>SPI_prepare</Function>
928 <INDEXTERM ID="IX-SPI-SPICURSOR-OPEN-1"><PRIMARY>SPI</PRIMARY><SECONDARY>cursors</SECONDARY></INDEXTERM>
929 <INDEXTERM ID="IX-SPI-SPICURSOR-OPEN-2"><PRIMARY>SPI_cursor_open</PRIMARY></INDEXTERM>
933 <DATE>2001-11-14</DATE>
934 </REFSYNOPSISDIVINFO>
936 SPI_cursor_open(<REPLACEABLE CLASS="PARAMETER">name</REPLACEABLE>,
937 <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>,
938 <REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>,
939 <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>)
942 <REFSECT2 ID="R2-SPI-SPICURSOR-OPEN-1">
944 <DATE>2001-11-14</DATE>
951 char *<REPLACEABLE CLASS="PARAMETER">name</REPLACEABLE>
955 Name for portal, or NULL to let the system select a name
961 void *<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
971 Datum *<REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
975 Actual parameter values
981 char *<REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
985 Array describing which parameters are NULLs
987 <Member><literal>n</literal> indicates NULL (values[] entry ignored)</Member>
988 <Member>space indicates not NULL (values[] entry is valid)</Member>
996 <REFSECT2 ID="R2-SPI-SPICURSOR-OPEN-2">
998 <DATE>2001-11-14</DATE>
1008 Pointer to Portal containing cursor, or NULL on error
1016 <REFSECT1 ID="R1-SPI-SPICURSOR-OPEN-1">
1018 <DATE>2001-11-14</DATE>
1023 <FUNCTION>SPI_cursor_open</FUNCTION>
1024 sets up a cursor (internally, a Portal) that will execute a plan
1025 prepared by <Function>SPI_prepare</Function>.
1028 Using a cursor instead of executing the plan directly has two
1029 benefits. First, the result rows can be retrieved a few at a time,
1030 avoiding memory overrun for queries that return many rows. Second,
1031 a Portal can outlive the current procedure (it can, in fact, live to
1032 the end of the current transaction). Returning the portal name to
1033 the procedure's caller provides a way of returning a rowset result.
1036 <REFSECT1 ID="R1-SPI-SPICURSOR-OPEN-2">
1040 If <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
1042 <Function>SPI_cursor_open</Function>
1043 assumes that all parameters (if any) are NOT NULL.
1047 <REFSECT1 ID="R1-SPI-SPICURSOR-OPEN-3">
1050 <PARA><FUNCTION>SPI_cursor_open</FUNCTION> performs the following:
1057 <!-- *********************************************** -->
1058 <!-- *********************************************** -->
1059 <!-- *********************************************** -->
1061 <REFENTRY ID="SPI-SPICURSOR-FIND">
1063 <REFENTRYTITLE>SPI_cursor_find</REFENTRYTITLE>
1064 <REFMISCINFO>SPI - Cursor Support</REFMISCINFO>
1067 <REFNAME>SPI_cursor_find
1070 Finds an existing cursor (Portal) by name
1072 <INDEXTERM ID="IX-SPI-SPICURSOR-FIND-1"><PRIMARY>SPI</PRIMARY><SECONDARY>cursors</SECONDARY></INDEXTERM>
1073 <INDEXTERM ID="IX-SPI-SPICURSOR-FIND-2"><PRIMARY>SPI_cursor_find</PRIMARY></INDEXTERM>
1076 <REFSYNOPSISDIVINFO>
1077 <DATE>2001-11-14</DATE>
1078 </REFSYNOPSISDIVINFO>
1080 SPI_cursor_find(<REPLACEABLE CLASS="PARAMETER">name</REPLACEABLE>)
1083 <REFSECT2 ID="R2-SPI-SPICURSOR-FIND-1">
1085 <DATE>2001-11-14</DATE>
1092 char *<REPLACEABLE CLASS="PARAMETER">name</REPLACEABLE>
1103 <REFSECT2 ID="R2-SPI-SPICURSOR-FIND-2">
1105 <DATE>2001-11-14</DATE>
1115 Pointer to Portal with given name, or NULL if not found
1123 <REFSECT1 ID="R1-SPI-SPICURSOR-FIND-1">
1125 <DATE>2001-11-14</DATE>
1130 <FUNCTION>SPI_cursor_find</FUNCTION>
1131 finds a pre-existing Portal by name. This is primarily useful
1132 to resolve a cursor name returned as text by some other function.
1136 <REFSECT1 ID="R1-SPI-SPICURSOR-FIND-2">
1144 <REFSECT1 ID="R1-SPI-SPICURSOR-FIND-3">
1147 <PARA><FUNCTION>SPI_cursor_find</FUNCTION> performs the following:
1154 <!-- *********************************************** -->
1155 <!-- *********************************************** -->
1156 <!-- *********************************************** -->
1158 <REFENTRY ID="SPI-SPICURSOR-FETCH">
1160 <REFENTRYTITLE>SPI_cursor_fetch</REFENTRYTITLE>
1161 <REFMISCINFO>SPI - Cursor Support</REFMISCINFO>
1164 <REFNAME>SPI_cursor_fetch
1167 Fetches some rows from a cursor
1169 <INDEXTERM ID="IX-SPI-SPICURSOR-FETCH-1"><PRIMARY>SPI</PRIMARY><SECONDARY>cursors</SECONDARY></INDEXTERM>
1170 <INDEXTERM ID="IX-SPI-SPICURSOR-FETCH-2"><PRIMARY>SPI_cursor_fetch</PRIMARY></INDEXTERM>
1173 <REFSYNOPSISDIVINFO>
1174 <DATE>2001-11-14</DATE>
1175 </REFSYNOPSISDIVINFO>
1177 SPI_cursor_fetch(<REPLACEABLE CLASS="PARAMETER">portal</REPLACEABLE>,
1178 <REPLACEABLE CLASS="PARAMETER">forward</REPLACEABLE>,
1179 <REPLACEABLE CLASS="PARAMETER">count</REPLACEABLE>)
1182 <REFSECT2 ID="R2-SPI-SPICURSOR-FETCH-1">
1184 <DATE>2001-11-14</DATE>
1191 Portal <REPLACEABLE CLASS="PARAMETER">portal</REPLACEABLE>
1195 Portal containing cursor
1201 bool <REPLACEABLE CLASS="PARAMETER">forward</REPLACEABLE>
1205 True for fetch forward, false for fetch backward
1211 int <REPLACEABLE CLASS="PARAMETER">count</REPLACEABLE>
1215 Maximum number of rows to fetch
1222 <REFSECT2 ID="R2-SPI-SPICURSOR-FETCH-2">
1224 <DATE>2001-11-14</DATE>
1235 <Function>SPI_exec</Function> if successful
1245 <Function>SPI_exec</Function> if successful
1253 <REFSECT1 ID="R1-SPI-SPICURSOR-FETCH-1">
1255 <DATE>2001-11-14</DATE>
1260 <FUNCTION>SPI_cursor_fetch</FUNCTION>
1261 fetches some (more) rows from a cursor. This is equivalent to the
1262 SQL command <command>FETCH</>.
1266 <REFSECT1 ID="R1-SPI-SPICURSOR-FETCH-2">
1274 <REFSECT1 ID="R1-SPI-SPICURSOR-FETCH-3">
1277 <PARA><FUNCTION>SPI_cursor_fetch</FUNCTION> performs the following:
1284 <!-- *********************************************** -->
1285 <!-- *********************************************** -->
1286 <!-- *********************************************** -->
1288 <REFENTRY ID="SPI-SPICURSOR-MOVE">
1290 <REFENTRYTITLE>SPI_cursor_move</REFENTRYTITLE>
1291 <REFMISCINFO>SPI - Cursor Support</REFMISCINFO>
1294 <REFNAME>SPI_cursor_move
1299 <INDEXTERM ID="IX-SPI-SPICURSOR-MOVE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>cursors</SECONDARY></INDEXTERM>
1300 <INDEXTERM ID="IX-SPI-SPICURSOR-MOVE-2"><PRIMARY>SPI_cursor_move</PRIMARY></INDEXTERM>
1303 <REFSYNOPSISDIVINFO>
1304 <DATE>2001-11-14</DATE>
1305 </REFSYNOPSISDIVINFO>
1307 SPI_cursor_move(<REPLACEABLE CLASS="PARAMETER">portal</REPLACEABLE>,
1308 <REPLACEABLE CLASS="PARAMETER">forward</REPLACEABLE>,
1309 <REPLACEABLE CLASS="PARAMETER">count</REPLACEABLE>)
1312 <REFSECT2 ID="R2-SPI-SPICURSOR-MOVE-1">
1314 <DATE>2001-11-14</DATE>
1321 Portal <REPLACEABLE CLASS="PARAMETER">portal</REPLACEABLE>
1325 Portal containing cursor
1331 bool <REPLACEABLE CLASS="PARAMETER">forward</REPLACEABLE>
1335 True for move forward, false for move backward
1341 int <REPLACEABLE CLASS="PARAMETER">count</REPLACEABLE>
1345 Maximum number of rows to move
1352 <REFSECT2 ID="R2-SPI-SPICURSOR-MOVE-2">
1354 <DATE>2001-11-14</DATE>
1371 <REFSECT1 ID="R1-SPI-SPICURSOR-MOVE-1">
1373 <DATE>2001-11-14</DATE>
1378 <FUNCTION>SPI_cursor_move</FUNCTION>
1379 skips over some number of rows in a cursor. This is equivalent to the
1380 SQL command <command>MOVE</>.
1384 <REFSECT1 ID="R1-SPI-SPICURSOR-MOVE-2">
1392 <REFSECT1 ID="R1-SPI-SPICURSOR-MOVE-3">
1395 <PARA><FUNCTION>SPI_cursor_move</FUNCTION> performs the following:
1402 <!-- *********************************************** -->
1403 <!-- *********************************************** -->
1404 <!-- *********************************************** -->
1406 <REFENTRY ID="SPI-SPICURSOR-CLOSE">
1408 <REFENTRYTITLE>SPI_cursor_close</REFENTRYTITLE>
1409 <REFMISCINFO>SPI - Cursor Support</REFMISCINFO>
1412 <REFNAME>SPI_cursor_close
1417 <INDEXTERM ID="IX-SPI-SPICURSOR-CLOSE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>cursors</SECONDARY></INDEXTERM>
1418 <INDEXTERM ID="IX-SPI-SPICURSOR-CLOSE-2"><PRIMARY>SPI_cursor_close</PRIMARY></INDEXTERM>
1421 <REFSYNOPSISDIVINFO>
1422 <DATE>2001-11-14</DATE>
1423 </REFSYNOPSISDIVINFO>
1425 SPI_cursor_close(<REPLACEABLE CLASS="PARAMETER">portal</REPLACEABLE>)
1428 <REFSECT2 ID="R2-SPI-SPICURSOR-CLOSE-1">
1430 <DATE>2001-11-14</DATE>
1437 Portal <REPLACEABLE CLASS="PARAMETER">portal</REPLACEABLE>
1441 Portal containing cursor
1448 <REFSECT2 ID="R2-SPI-SPICURSOR-CLOSE-2">
1450 <DATE>2001-11-14</DATE>
1467 <REFSECT1 ID="R1-SPI-SPICURSOR-CLOSE-1">
1469 <DATE>2001-11-14</DATE>
1474 <FUNCTION>SPI_cursor_close</FUNCTION>
1475 closes a previously created cursor and releases its Portal storage.
1478 <REFSECT1 ID="R1-SPI-SPICURSOR-CLOSE-2">
1482 All open cursors are closed implicitly at transaction end.
1483 <FUNCTION>SPI_cursor_close</FUNCTION> need only be invoked if
1484 it is desirable to release resources sooner.
1488 <REFSECT1 ID="R1-SPI-SPICURSOR-CLOSE-3">
1491 <PARA><FUNCTION>SPI_cursor_close</FUNCTION> performs the following:
1498 <!-- *********************************************** -->
1499 <!-- *********************************************** -->
1500 <!-- *********************************************** -->
1502 <REFENTRY ID="SPI-SPISAVEPLAN">
1504 <REFENTRYTITLE>SPI_saveplan</REFENTRYTITLE>
1505 <REFMISCINFO>SPI - Plan Storage</REFMISCINFO>
1508 <REFNAME>SPI_saveplan
1513 <INDEXTERM ID="IX-SPI-SPISAVEPLAN-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
1514 <INDEXTERM ID="IX-SPI-SPISAVEPLAN-2"><PRIMARY>SPI_saveplan</PRIMARY></INDEXTERM>
1517 <REFSYNOPSISDIVINFO>
1518 <DATE>1997-12-24</DATE>
1519 </REFSYNOPSISDIVINFO>
1521 SPI_saveplan(<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>)
1524 <REFSECT2 ID="R2-SPI-SPISAVEPLAN-1">
1526 <DATE>1997-12-24</DATE>
1533 void *<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
1544 <REFSECT2 ID="R2-SPI-SPISAVEPLAN-2">
1546 <DATE>1997-12-24</DATE>
1556 Execution plan location. NULL if unsuccessful.
1567 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if plan is NULL
1570 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is un-connected
1580 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-1">
1582 <DATE>1997-12-24</DATE>
1587 <FUNCTION>SPI_saveplan</FUNCTION>
1588 stores a plan prepared by <Function>SPI_prepare</Function> in safe memory
1589 protected from freeing by <Function>SPI_finish</Function> or the transaction manager.
1592 In the current version of <ProductName>Postgres</ProductName> there is no ability to
1593 store prepared plans in the system
1594 catalog and fetch them from there for execution. This will be implemented
1597 As an alternative, there is the ability to reuse prepared plans in the
1598 subsequent invocations of your procedure in the current session.
1599 Use <Function>SPI_execp</Function> to execute this saved plan.
1602 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-2">
1606 <Function>SPI_saveplan</Function> saves a passed plan (prepared by <Function>SPI_prepare</Function>) in memory
1607 protected from freeing by <Function>SPI_finish</Function> and by the transaction manager and
1608 returns a pointer to the saved plan. You may save the pointer returned in
1609 a local variable. Always check if this pointer is NULL or not either when
1610 preparing a plan or using an already prepared plan in SPI_execp (see below).
1614 If one of the objects (a relation, function, etc.) referenced by the prepared
1615 plan is dropped during your session (by your backend or another process) then the
1616 results of <Function>SPI_execp</Function> for this plan will be unpredictable.
1623 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-3">
1626 <PARA><FUNCTION>SPI_saveplan</FUNCTION> performs the following:
1632 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-4">
1643 <Sect1 id="spi-interface-support">
1644 <Title>Interface Support Functions</Title>
1647 The functions described here provide convenient interfaces for extracting
1648 information from tuple sets returned by <function>SPI_exec</> and other
1649 SPI interface functions.
1653 All functions described in this section may be used by both connected and
1654 unconnected procedures.
1657 <!-- *********************************************** -->
1658 <!-- *********************************************** -->
1659 <!-- *********************************************** -->
1661 <REFENTRY ID="SPI-SPIFNUMBER">
1663 <REFENTRYTITLE>SPI_fnumber</REFENTRYTITLE>
1664 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1667 <REFNAME>SPI_fnumber
1670 Finds the attribute number for specified attribute name
1672 <INDEXTERM ID="IX-SPI-SPIFNUMBER-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1673 <INDEXTERM ID="IX-SPI-SPIFNUMBER-2"><PRIMARY>SPI_fnumber</PRIMARY></INDEXTERM>
1676 <REFSYNOPSISDIVINFO>
1677 <DATE>1997-12-24</DATE>
1678 </REFSYNOPSISDIVINFO>
1680 SPI_fnumber(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>)
1683 <REFSECT2 ID="R2-SPI-SPIFNUMBER-1">
1685 <DATE>1997-12-24</DATE>
1692 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1696 Input tuple description
1702 char * <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>
1713 <REFSECT2 ID="R2-SPI-SPIFNUMBER-2">
1715 <DATE>1997-12-24</DATE>
1729 Valid one-based index number of attribute
1732 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> if the named attribute is not found
1742 <REFSECT1 ID="R1-SPI-SPIFNUMBER-1">
1744 <DATE>1997-12-24</DATE>
1749 <FUNCTION>SPI_fnumber</FUNCTION>
1750 returns the attribute number for the attribute with name in fname.
1753 <REFSECT1 ID="R1-SPI-SPIFNUMBER-2">
1757 Attribute numbers are 1 based.
1760 If the given fname refers to a system attribute (eg, <literal>oid</>)
1761 then the appropriate negative attribute number will be returned.
1762 The caller should be careful to test for exact equality to
1763 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> to detect error;
1764 testing for result <= 0 is not correct unless system attributes
1769 <REFSECT1 ID="R1-SPI-SPIFNUMBER-3">
1777 <REFSECT1 ID="R1-SPI-SPIFNUMBER-4">
1786 <!-- *********************************************** -->
1787 <!-- *********************************************** -->
1788 <!-- *********************************************** -->
1790 <REFENTRY ID="SPI-SPIFNAME">
1792 <REFENTRYTITLE>SPI_fname</REFENTRYTITLE>
1793 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1799 Finds the attribute name for the specified attribute number
1801 <INDEXTERM ID="IX-SPI-SPIFNAME-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1802 <INDEXTERM ID="IX-SPI-SPIFNAME-2"><PRIMARY>SPI_fname</PRIMARY></INDEXTERM>
1805 <REFSYNOPSISDIVINFO>
1806 <DATE>1997-12-24</DATE>
1807 </REFSYNOPSISDIVINFO>
1809 SPI_fname(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
1812 <REFSECT2 ID="R2-SPI-SPIFNAME-1">
1814 <DATE>1997-12-24</DATE>
1821 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1825 Input tuple description
1831 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1842 <REFSECT2 ID="R2-SPI-SPIFNAME-2">
1844 <DATE>1997-12-24</DATE>
1858 NULL if fnumber is out of range
1862 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> on error
1872 <REFSECT1 ID="R1-SPI-SPIFNAME-1">
1874 <DATE>1997-12-24</DATE>
1879 <FUNCTION>SPI_fname</FUNCTION>
1880 returns the attribute name for the specified attribute.
1883 <REFSECT1 ID="R1-SPI-SPIFNAME-2">
1887 Attribute numbers are 1 based.
1890 <REFSECT1 ID="R1-SPI-SPIFNAME-3">
1894 Returns a newly-allocated copy of the attribute name.
1895 (Use pfree() to release the copy when done with it.)
1899 <REFSECT1 ID="R1-SPI-SPIFNAME-4">
1908 <!-- *********************************************** -->
1909 <!-- *********************************************** -->
1910 <!-- *********************************************** -->
1912 <REFENTRY ID="SPI-SPIGETVALUE">
1914 <REFENTRYTITLE>SPI_getvalue</REFENTRYTITLE>
1915 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1918 <REFNAME>SPI_getvalue
1921 Returns the string value of the specified attribute
1923 <INDEXTERM ID="IX-SPI-SPIGETVALUE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1924 <INDEXTERM ID="IX-SPI-SPIGETVALUE-2"><PRIMARY>SPI_getvalue</PRIMARY></INDEXTERM>
1927 <REFSYNOPSISDIVINFO>
1928 <DATE>1997-12-24</DATE>
1929 </REFSYNOPSISDIVINFO>
1931 SPI_getvalue(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
1934 <REFSECT2 ID="R2-SPI-SPIGETVALUE-1">
1936 <DATE>1997-12-24</DATE>
1943 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1947 Input tuple to be examined
1953 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1957 Input tuple description
1963 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1974 <REFSECT2 ID="R2-SPI-SPIGETVALUE-2">
1976 <DATE>1997-12-24</DATE>
1987 Attribute value or NULL if
1993 fnumber is out of range
1995 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>)
1998 no output function available
2000 <ReturnValue>SPI_ERROR_NOOUTFUNC</ReturnValue>)
2010 <REFSECT1 ID="R1-SPI-SPIGETVALUE-1">
2012 <DATE>1997-12-24</DATE>
2017 <FUNCTION>SPI_getvalue</FUNCTION>
2018 returns an external (string) representation of the value of the specified attribute.
2021 <REFSECT1 ID="R1-SPI-SPIGETVALUE-2">
2025 Attribute numbers are 1 based.
2028 <REFSECT1 ID="R1-SPI-SPIGETVALUE-3">
2032 The result is returned as a palloc'd string.
2033 (Use pfree() to release the string when done with it.)
2037 <REFSECT1 ID="R1-SPI-SPIGETVALUE-4">
2046 <!-- *********************************************** -->
2047 <!-- *********************************************** -->
2048 <!-- *********************************************** -->
2050 <REFENTRY ID="SPI-SPIGETBINVAL">
2052 <REFENTRYTITLE>SPI_getbinval</REFENTRYTITLE>
2053 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2056 <REFNAME>SPI_getbinval
2059 Returns the binary value of the specified attribute
2061 <INDEXTERM ID="IX-SPI-SPIGETBINVAL-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
2062 <INDEXTERM ID="IX-SPI-SPIGETBINVAL-2"><PRIMARY>SPI_getbinval</PRIMARY></INDEXTERM>
2065 <REFSYNOPSISDIVINFO>
2066 <DATE>1997-12-24</DATE>
2067 </REFSYNOPSISDIVINFO>
2069 SPI_getbinval(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">isnull</REPLACEABLE>)
2072 <REFSECT2 ID="R2-SPI-SPIGETBINVAL-1">
2074 <DATE>1997-12-24</DATE>
2081 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2085 Input tuple to be examined
2091 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2095 Input tuple description
2101 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2112 <REFSECT2 ID="R2-SPI-SPIGETBINVAL-2">
2114 <DATE>1997-12-24</DATE>
2125 Attribute binary value
2131 bool * <REPLACEABLE CLASS="PARAMETER">isnull</REPLACEABLE>
2135 flag for null value in attribute
2147 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2157 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-1">
2159 <DATE>1997-12-24</DATE>
2164 <FUNCTION>SPI_getbinval</FUNCTION>
2165 returns the specified attribute's value in internal form (as a Datum).
2168 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-2">
2172 Attribute numbers are 1 based.
2175 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-3">
2179 Does not allocate new space for the datum. In the case of a pass-by-
2180 reference datatype, the Datum will be a pointer into the given tuple.
2184 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-4">
2193 <!-- *********************************************** -->
2194 <!-- *********************************************** -->
2195 <!-- *********************************************** -->
2197 <REFENTRY ID="SPI-SPIGETTYPE">
2199 <REFENTRYTITLE>SPI_gettype</REFENTRYTITLE>
2200 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2203 <REFNAME>SPI_gettype
2206 Returns the type name of the specified attribute
2208 <INDEXTERM ID="IX-SPI-SPIGETTYPE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
2209 <INDEXTERM ID="IX-SPI-SPIGETTYPE-2"><PRIMARY>SPI_gettype</PRIMARY></INDEXTERM>
2212 <REFSYNOPSISDIVINFO>
2213 <DATE>1997-12-24</DATE>
2214 </REFSYNOPSISDIVINFO>
2216 SPI_gettype(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
2219 <REFSECT2 ID="R2-SPI-SPIGETTYPE-1">
2221 <DATE>1997-12-24</DATE>
2228 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2232 Input tuple description
2238 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2249 <REFSECT2 ID="R2-SPI-SPIGETTYPE-2">
2251 <DATE>1997-12-24</DATE>
2262 The type name for the specified attribute number
2274 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2284 <REFSECT1 ID="R1-SPI-SPIGETTYPE-1">
2286 <DATE>1997-12-24</DATE>
2291 <FUNCTION>SPI_gettype</FUNCTION>
2292 returns a copy of the type name for the specified attribute,
2296 <REFSECT1 ID="R1-SPI-SPIGETTYPE-2">
2300 Attribute numbers are 1 based.
2303 <REFSECT1 ID="R1-SPI-SPIGETTYPE-3">
2307 Returns a newly-allocated copy of the type name.
2308 (Use pfree() to release the copy when done with it.)
2312 <REFSECT1 ID="R1-SPI-SPIGETTYPE-4">
2321 <!-- *********************************************** -->
2322 <!-- *********************************************** -->
2323 <!-- *********************************************** -->
2325 <REFENTRY ID="SPI-SPIGETTYPEID">
2327 <REFENTRYTITLE>SPI_gettypeid</REFENTRYTITLE>
2328 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2331 <REFNAME>SPI_gettypeid
2334 Returns the type <Acronym>OID</Acronym> of the specified attribute
2336 <INDEXTERM ID="IX-SPI-SPIGETTYPEID-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
2337 <INDEXTERM ID="IX-SPI-SPIGETTYPEID-2"><PRIMARY>SPI_gettypeid</PRIMARY></INDEXTERM>
2340 <REFSYNOPSISDIVINFO>
2341 <DATE>1997-12-24</DATE>
2342 </REFSYNOPSISDIVINFO>
2344 SPI_gettypeid(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
2347 <REFSECT2 ID="R2-SPI-SPIGETTYPEID-1">
2349 <DATE>1997-12-24</DATE>
2356 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2360 Input tuple description
2366 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2377 <REFSECT2 ID="R2-SPI-SPIGETTYPEID-2">
2379 <DATE>1997-12-24</DATE>
2386 <Acronym>OID</Acronym>
2390 The type <Acronym>OID</Acronym> for the specified attribute number
2402 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2412 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-1">
2414 <DATE>1997-12-24</DATE>
2419 <FUNCTION>SPI_gettypeid</FUNCTION>
2420 returns the type <Acronym>OID</Acronym> for the specified attribute.
2423 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-2">
2427 Attribute numbers are 1 based.
2431 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-3">
2440 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-4">
2449 <!-- *********************************************** -->
2450 <!-- *********************************************** -->
2451 <!-- *********************************************** -->
2453 <REFENTRY ID="SPI-SPIGETRELNAME">
2455 <REFENTRYTITLE>SPI_getrelname</REFENTRYTITLE>
2456 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2459 <REFNAME>SPI_getrelname
2462 Returns the name of the specified relation
2464 <INDEXTERM ID="IX-SPI-SPIGETRELNAME-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
2465 <INDEXTERM ID="IX-SPI-SPIGETRELNAME-2"><PRIMARY>SPI_getrelname</PRIMARY></INDEXTERM>
2468 <REFSYNOPSISDIVINFO>
2469 <DATE>1997-12-24</DATE>
2470 </REFSYNOPSISDIVINFO>
2472 SPI_getrelname(<REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>)
2475 <REFSECT2 ID="R2-SPI-SPIGETRELNAME-1">
2477 <DATE>1997-12-24</DATE>
2484 Relation <REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>
2495 <REFSECT2 ID="R2-SPI-SPIGETRELNAME-2">
2497 <DATE>1997-12-24</DATE>
2508 The name of the specified relation
2516 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-1">
2518 <DATE>1997-12-24</DATE>
2523 <FUNCTION>SPI_getrelname</FUNCTION>
2524 returns the name of the specified relation.
2528 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-2">
2536 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-3">
2540 Returns a newly-allocated copy of the rel name.
2541 (Use pfree() to release the copy when done with it.)
2545 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-4">
2556 <Sect1 id="spi-memory">
2557 <Title>Memory Management</Title>
2560 <ProductName>Postgres</ProductName> allocates memory within memory
2561 <firstterm>contexts</firstterm>, which provide a convenient method of
2562 managing allocations made in many different places that need to live
2563 for differing amounts of time. Destroying a context releases all the
2564 memory that was allocated in it. Thus, it is not necessary to keep track
2565 of individual objects to avoid memory leaks --- only a relatively small number
2566 of contexts have to be managed. <Function>palloc</Function> and related
2567 functions allocate memory from the <quote>current</> context.
2570 <Function>SPI_connect</Function> creates a new memory context and makes
2571 it current. <Function>SPI_finish</Function> restores the previous
2572 current memory context and destroys the context created by
2573 <Function>SPI_connect</Function>. These actions ensure that transient
2574 memory allocations made inside your procedure are reclaimed at procedure
2575 exit, avoiding memory leakage.
2578 However, if your procedure needs to return an allocated memory object
2579 (such as a value of a pass-by-reference datatype), you can't allocate
2580 the return object using <Function>palloc</Function>, at least not while
2581 you are connected to SPI. If you try, the object will be deallocated
2582 during <Function>SPI_finish</Function>, and your procedure will not
2586 To solve this problem, use <Function>SPI_palloc</Function> to allocate
2587 your return object. <Function>SPI_palloc</Function> allocates space
2588 from <quote>upper Executor</> memory --- that is, the memory context
2589 that was current when <Function>SPI_connect</Function> was called,
2590 which is precisely the right context for return values of your procedure.
2593 If called while not connected to SPI, <Function>SPI_palloc</Function>
2594 acts the same as plain <Function>palloc</Function>.
2597 Before a procedure connects to the SPI manager, the current memory context
2598 is the upper Executor context, so all allocations made by the procedure via
2599 <Function>palloc</Function> or by SPI utility functions are
2600 made in this context.
2603 After <Function>SPI_connect</Function> is called, the current context is
2604 the procedure's private context made by <Function>SPI_connect</Function>.
2605 All allocations made via
2606 <Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility
2607 functions (except for <Function>SPI_copytuple</Function>,
2608 <Function>SPI_copytupledesc</Function>,
2609 <Function>SPI_copytupleintoslot</Function>,
2610 <Function>SPI_modifytuple</Function>,
2611 and <Function>SPI_palloc</Function>) are
2612 made in this context.
2615 When a procedure disconnects from the SPI manager (via
2616 <Function>SPI_finish</Function>) the
2617 current context is restored to the upper Executor context, and all allocations
2618 made in the procedure memory context are freed and can't be used any more!
2622 All functions described in this section may be used by both connected and
2623 unconnected procedures. In an unconnected procedure, they act the same
2624 as the underlying ordinary backend functions (<function>palloc</> etc).
2627 <!-- *********************************************** -->
2628 <!-- *********************************************** -->
2629 <!-- *********************************************** -->
2631 <REFENTRY ID="SPI-SPICOPYTUPLE">
2633 <REFENTRYTITLE>SPI_copytuple</REFENTRYTITLE>
2634 <REFMISCINFO>SPI - Tuple Copy</REFMISCINFO>
2637 <REFNAME>SPI_copytuple
2640 Makes copy of tuple in upper Executor context
2642 <INDEXTERM ID="IX-SPI-SPICOPYTUPLE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuples</SECONDARY></INDEXTERM>
2643 <INDEXTERM ID="IX-SPI-SPICOPYTUPLE-2"><PRIMARY>SPI_copytuple</PRIMARY></INDEXTERM>
2646 <REFSYNOPSISDIVINFO>
2647 <DATE>1997-12-24</DATE>
2648 </REFSYNOPSISDIVINFO>
2650 SPI_copytuple(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>)
2653 <REFSECT2 ID="R2-SPI-SPICOPYTUPLE-1">
2655 <DATE>1997-12-24</DATE>
2662 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2666 Input tuple to be copied
2673 <REFSECT2 ID="R2-SPI-SPICOPYTUPLE-2">
2675 <DATE>1997-12-24</DATE>
2689 <ReturnValue>non-NULL</ReturnValue>
2690 if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2691 is not NULL and the copy was successful
2694 <ReturnValue>NULL</ReturnValue>
2695 only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2706 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-1">
2708 <DATE>1997-12-24</DATE>
2713 <FUNCTION>SPI_copytuple</FUNCTION>
2714 makes a copy of tuple in upper Executor context.
2717 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-2">
2725 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-3">
2733 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-4">
2742 <!-- *********************************************** -->
2743 <!-- *********************************************** -->
2744 <!-- *********************************************** -->
2746 <REFENTRY ID="SPI-SPICOPYTUPLEDESC">
2748 <REFENTRYTITLE>SPI_copytupledesc</REFENTRYTITLE>
2749 <REFMISCINFO>SPI - Tuple Descriptor Copy</REFMISCINFO>
2752 <REFNAME>SPI_copytupledesc
2755 Makes copy of tuple descriptor in upper Executor context
2757 <INDEXTERM ID="IX-SPI-SPICOPYTUPLEDESC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuple descriptors</SECONDARY></INDEXTERM>
2758 <INDEXTERM ID="IX-SPI-SPICOPYTUPLEDESC-2"><PRIMARY>SPI_copytupledesc</PRIMARY></INDEXTERM>
2761 <REFSYNOPSISDIVINFO>
2762 <DATE>2001-08-02</DATE>
2763 </REFSYNOPSISDIVINFO>
2765 SPI_copytupledesc(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>)
2768 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-1">
2770 <DATE>2001-08-02</DATE>
2777 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2781 Input tuple descriptor to be copied
2788 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-2">
2790 <DATE>2001-08-02</DATE>
2801 Copied tuple descriptor
2804 <ReturnValue>non-NULL</ReturnValue>
2805 if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2806 is not NULL and the copy was successful
2809 <ReturnValue>NULL</ReturnValue>
2810 only if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2821 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-1">
2823 <DATE>2001-08-02</DATE>
2828 <FUNCTION>SPI_copytupledesc</FUNCTION>
2829 makes a copy of tupdesc in upper Executor context.
2832 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-2">
2840 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-3">
2848 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-4">
2857 <!-- *********************************************** -->
2858 <!-- *********************************************** -->
2859 <!-- *********************************************** -->
2861 <REFENTRY ID="SPI-SPICOPYTUPLEINTOSLOT">
2863 <REFENTRYTITLE>SPI_copytupleintoslot</REFENTRYTITLE>
2864 <REFMISCINFO>SPI - Tuple and Descriptor Copy</REFMISCINFO>
2867 <REFNAME>SPI_copytupleintoslot
2870 Makes copy of tuple and descriptor in upper Executor context
2872 <INDEXTERM ID="IX-SPI-SPICOPYTUPLEINTOSLOT-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuples</SECONDARY></INDEXTERM>
2873 <INDEXTERM ID="IX-SPI-SPICOPYTUPLEINTOSLOT-2"><PRIMARY>SPI_copytupleintoslot</PRIMARY></INDEXTERM>
2876 <REFSYNOPSISDIVINFO>
2877 <DATE>1997-12-24</DATE>
2878 </REFSYNOPSISDIVINFO>
2880 SPI_copytupleintoslot(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>)
2883 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEINTOSLOT-1">
2885 <DATE>1997-12-24</DATE>
2892 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2896 Input tuple to be copied
2902 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2906 Input tuple descriptor to be copied
2913 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEINTOSLOT-2">
2915 <DATE>1997-12-24</DATE>
2926 Tuple slot containing copied tuple and descriptor
2929 <ReturnValue>non-NULL</ReturnValue>
2930 if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2931 and <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2932 are not NULL and the copy was successful
2935 <ReturnValue>NULL</ReturnValue>
2936 only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
2937 or <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2948 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-1">
2950 <DATE>1997-12-24</DATE>
2955 <FUNCTION>SPI_copytupleintoslot</FUNCTION>
2956 makes a copy of tuple in upper Executor context, returning it in the
2957 form of a filled-in TupleTableSlot.
2960 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-2">
2968 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-3">
2976 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEINTOSLOT-4">
2985 <!-- *********************************************** -->
2986 <!-- *********************************************** -->
2987 <!-- *********************************************** -->
2989 <REFENTRY ID="SPI-SPIMODIFYTUPLE">
2991 <REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
2992 <REFMISCINFO>SPI - Tuple Modify</REFMISCINFO>
2995 <REFNAME>SPI_modifytuple
2998 Creates a tuple by replacing selected fields of a given tuple
3000 <INDEXTERM ID="IX-SPI-SPIMODIFYTUPLE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>modifying tuples</SECONDARY></INDEXTERM>
3001 <INDEXTERM ID="IX-SPI-SPIMODIFYTUPLE-2"><PRIMARY>SPI_modifytuple</PRIMARY></INDEXTERM>
3004 <REFSYNOPSISDIVINFO>
3005 <DATE>1997-12-24</DATE>
3006 </REFSYNOPSISDIVINFO>
3008 SPI_modifytuple(<REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">nattrs</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">attnum</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">Values</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">Nulls</REPLACEABLE>)
3011 <REFSECT2 ID="R2-SPI-SPIMODIFYTUPLE-1">
3013 <DATE>1997-12-24</DATE>
3020 Relation <REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>
3024 Used only as source of tuple descriptor for tuple. (Passing a relation
3025 rather than a tuple descriptor is a misfeature.)
3031 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
3035 Input tuple to be modified
3041 int <REPLACEABLE CLASS="PARAMETER">nattrs</REPLACEABLE>
3045 Number of attribute numbers in attnum array
3051 int * <REPLACEABLE CLASS="PARAMETER">attnum</REPLACEABLE>
3055 Array of numbers of the attributes that are to be changed
3061 Datum * <REPLACEABLE CLASS="PARAMETER">Values</REPLACEABLE>
3065 New values for the attributes specified
3071 char * <REPLACEABLE CLASS="PARAMETER">Nulls</REPLACEABLE>
3075 Which new values are NULL, if any
3082 <REFSECT2 ID="R2-SPI-SPIMODIFYTUPLE-2">
3084 <DATE>1997-12-24</DATE>
3095 New tuple with modifications
3098 <ReturnValue>non-NULL</ReturnValue>
3099 if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
3100 is not NULL and the modify was successful
3103 <ReturnValue>NULL</ReturnValue>
3104 only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
3119 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if rel is NULL or tuple is NULL or natts <= 0 or
3120 attnum is NULL or Values is NULL.
3123 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> if there is an invalid
3124 attribute number in attnum (attnum <= 0 or > number of
3125 attributes in tuple)
3135 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-1">
3137 <DATE>1997-12-24</DATE>
3142 <FUNCTION>SPI_modifytuple</FUNCTION>
3143 creates a new tuple by substituting new values for selected attributes,
3144 copying the original tuple's attributes at other positions. The input
3145 tuple is not modified.
3148 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-2">
3152 If successful, a pointer to the new tuple is returned. The new tuple is
3153 allocated in upper Executor context.
3157 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-3">
3165 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-4">
3174 <!-- *********************************************** -->
3175 <!-- *********************************************** -->
3176 <!-- *********************************************** -->
3178 <REFENTRY ID="SPI-SPIPALLOC">
3180 <REFENTRYTITLE>SPI_palloc</REFENTRYTITLE>
3181 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
3187 Allocates memory in upper Executor context
3189 <INDEXTERM ID="IX-SPI-SPIPALLOC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
3190 <INDEXTERM ID="IX-SPI-SPIPALLOC-2"><PRIMARY>SPI_palloc</PRIMARY></INDEXTERM>
3193 <REFSYNOPSISDIVINFO>
3194 <DATE>1997-12-24</DATE>
3195 </REFSYNOPSISDIVINFO>
3197 SPI_palloc(<REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)
3200 <REFSECT2 ID="R2-SPI-SPIPALLOC-1">
3202 <DATE>1997-12-24</DATE>
3209 Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>
3213 Octet size of storage to allocate
3220 <REFSECT2 ID="R2-SPI-SPIPALLOC-2">
3222 <DATE>1997-12-24</DATE>
3233 New storage space of specified size
3241 <REFSECT1 ID="R1-SPI-SPIPALLOC-1">
3243 <DATE>1997-12-24</DATE>
3248 <FUNCTION>SPI_palloc</FUNCTION>
3249 allocates memory in upper Executor context.
3252 <REFSECT1 ID="R1-SPI-SPIPALLOC-2">
3260 <REFSECT1 ID="R1-SPI-SPIPALLOC-3">
3269 <REFSECT1 ID="R1-SPI-SPIPALLOC-4">
3278 <!-- *********************************************** -->
3279 <!-- *********************************************** -->
3280 <!-- *********************************************** -->
3282 <REFENTRY ID="SPI-SPIREPALLOC">
3284 <REFENTRYTITLE>SPI_repalloc</REFENTRYTITLE>
3285 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
3288 <REFNAME>SPI_repalloc
3291 Re-allocates memory in upper Executor context
3293 <INDEXTERM ID="IX-SPI-SPIREPALLOC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
3294 <INDEXTERM ID="IX-SPI-SPIREPALLOC-2"><PRIMARY>SPI_repalloc</PRIMARY></INDEXTERM>
3297 <REFSYNOPSISDIVINFO>
3298 <DATE>1997-12-24</DATE>
3299 </REFSYNOPSISDIVINFO>
3301 SPI_repalloc(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)
3304 <REFSECT2 ID="R2-SPI-SPIREPALLOC-1">
3306 <DATE>1997-12-24</DATE>
3313 void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
3317 Pointer to existing storage
3323 Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>
3327 Octet size of storage to allocate
3334 <REFSECT2 ID="R2-SPI-SPIREPALLOC-2">
3336 <DATE>1997-12-24</DATE>
3347 New storage space of specified size with contents copied from existing area
3355 <REFSECT1 ID="R1-SPI-SPIREPALLOC-1">
3357 <DATE>1997-12-24</DATE>
3362 <FUNCTION>SPI_repalloc</FUNCTION>
3363 re-allocates memory in upper Executor context.
3366 <REFSECT1 ID="R1-SPI-SPIREPALLOC-2">
3370 This function is no longer different from plain <FUNCTION>repalloc</FUNCTION>.
3371 It's kept just for backward compatibility of existing code.
3375 <REFSECT1 ID="R1-SPI-SPIREPALLOC-3">
3384 <REFSECT1 ID="R1-SPI-SPIREPALLOC-4">
3393 <!-- *********************************************** -->
3394 <!-- *********************************************** -->
3395 <!-- *********************************************** -->
3397 <REFENTRY ID="SPI-SPIPFREE">
3399 <REFENTRYTITLE>SPI_pfree</REFENTRYTITLE>
3400 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
3406 Frees memory in upper Executor context
3408 <INDEXTERM ID="IX-SPI-SPIPFREE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
3409 <INDEXTERM ID="IX-SPI-SPIPFREE-2"><PRIMARY>SPI_pfree</PRIMARY></INDEXTERM>
3412 <REFSYNOPSISDIVINFO>
3413 <DATE>1997-12-24</DATE>
3414 </REFSYNOPSISDIVINFO>
3416 SPI_pfree(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>)
3419 <REFSECT2 ID="R2-SPI-SPIPFREE-1">
3421 <DATE>1997-12-24</DATE>
3428 void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
3432 Pointer to existing storage
3439 <REFSECT2 ID="R2-SPI-SPIPFREE-2">
3441 <DATE>1997-12-24</DATE>
3459 <REFSECT1 ID="R1-SPI-SPIPFREE-1">
3461 <DATE>1997-12-24</DATE>
3466 <FUNCTION>SPI_pfree</FUNCTION>
3467 frees memory in upper Executor context.
3470 <REFSECT1 ID="R1-SPI-SPIPFREE-2">
3474 This function is no longer different from plain <FUNCTION>pfree</FUNCTION>.
3475 It's kept just for backward compatibility of existing code.
3480 <!-- *********************************************** -->
3481 <!-- *********************************************** -->
3482 <!-- *********************************************** -->
3484 <REFENTRY ID="SPI-SPIFREETUPLE">
3486 <REFENTRYTITLE>SPI_freetuple</REFENTRYTITLE>
3487 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
3490 <REFNAME>SPI_freetuple
3493 Frees a tuple allocated in upper Executor context
3495 <INDEXTERM ID="IX-SPI-SPIFREETUPLE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
3496 <INDEXTERM ID="IX-SPI-SPIFREETUPLE-2"><PRIMARY>SPI_freetuple</PRIMARY></INDEXTERM>
3499 <REFSYNOPSISDIVINFO>
3500 <DATE>1997-12-24</DATE>
3501 </REFSYNOPSISDIVINFO>
3503 SPI_freetuple(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>)
3506 <REFSECT2 ID="R2-SPI-SPIFREETUPLE-1">
3508 <DATE>1997-12-24</DATE>
3515 HeapTuple <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
3519 Pointer to allocated tuple
3526 <REFSECT2 ID="R2-SPI-SPIFREETUPLE-2">
3528 <DATE>1997-12-24</DATE>
3546 <REFSECT1 ID="R1-SPI-SPIFREETUPLE-1">
3548 <DATE>1997-12-24</DATE>
3553 <FUNCTION>SPI_freetuple</FUNCTION>
3554 frees a tuple previously allocated in upper Executor context.
3557 <REFSECT1 ID="R1-SPI-SPIFREETUPLE-2">
3561 This function is no longer different from plain <FUNCTION>heap_freetuple</FUNCTION>.
3562 It's kept just for backward compatibility of existing code.
3567 <!-- *********************************************** -->
3568 <!-- *********************************************** -->
3569 <!-- *********************************************** -->
3571 <REFENTRY ID="SPI-SPIFREETUPTABLE">
3573 <REFENTRYTITLE>SPI_freetuptable</REFENTRYTITLE>
3574 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
3577 <REFNAME>SPI_freetuptable
3580 Frees a tuple set created by <function>SPI_exec</> or similar function
3582 <INDEXTERM ID="IX-SPI-SPIFREETUPTABLE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
3583 <INDEXTERM ID="IX-SPI-SPIFREETUPTABLE-2"><PRIMARY>SPI_freetuptable</PRIMARY></INDEXTERM>
3586 <REFSYNOPSISDIVINFO>
3587 <DATE>2001-11-14</DATE>
3588 </REFSYNOPSISDIVINFO>
3590 SPI_freetuptable(<REPLACEABLE CLASS="PARAMETER">tuptable</REPLACEABLE>)
3593 <REFSECT2 ID="R2-SPI-SPIFREETUPTABLE-1">
3595 <DATE>2001-11-14</DATE>
3602 SPITupleTable * <REPLACEABLE CLASS="PARAMETER">tuptable</REPLACEABLE>
3606 Pointer to tuple table
3613 <REFSECT2 ID="R2-SPI-SPIFREETUPTABLE-2">
3615 <DATE>2001-11-14</DATE>
3633 <REFSECT1 ID="R1-SPI-SPIFREETUPTABLE-1">
3635 <DATE>2001-11-14</DATE>
3640 <FUNCTION>SPI_freetuptable</FUNCTION>
3641 frees a tuple set created by a prior SPI query function, such as
3642 <function>SPI_exec</>.
3645 <REFSECT1 ID="R1-SPI-SPIFREETUPTABLE-2">
3649 This function is useful if a SPI procedure needs to execute multiple
3650 queries and does not want to keep the results of earlier queries around
3651 until it ends. Note that any unfreed tuple sets will be freed anyway
3652 at <function>SPI_finish</>.
3657 <!-- *********************************************** -->
3658 <!-- *********************************************** -->
3659 <!-- *********************************************** -->
3661 <REFENTRY ID="SPI-SPIFREEPLAN">
3663 <REFENTRYTITLE>SPI_freeplan</REFENTRYTITLE>
3664 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
3667 <REFNAME>SPI_freeplan
3670 Releases a previously saved plan
3672 <INDEXTERM ID="IX-SPI-SPIFREEPLAN-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
3673 <INDEXTERM ID="IX-SPI-SPIFREEPLAN-2"><PRIMARY>SPI_freeplan</PRIMARY></INDEXTERM>
3676 <REFSYNOPSISDIVINFO>
3677 <DATE>2001-11-14</DATE>
3678 </REFSYNOPSISDIVINFO>
3680 SPI_freeplan(<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>)
3683 <REFSECT2 ID="R2-SPI-SPIFREEPLAN-1">
3685 <DATE>2001-11-14</DATE>
3692 void *<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
3703 <REFSECT2 ID="R2-SPI-SPIFREEPLAN-2">
3705 <DATE>2001-11-14</DATE>
3717 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if plan is NULL
3727 <REFSECT1 ID="R1-SPI-SPIFREEPLAN-1">
3729 <DATE>2001-11-14</DATE>
3734 <FUNCTION>SPI_freeplan</FUNCTION>
3735 releases a query plan previously returned by
3736 <Function>SPI_prepare</Function> or saved by
3737 <Function>SPI_saveplan</Function>.
3744 <Sect1 id="spi-visibility">
3745 <Title>Visibility of Data Changes</Title>
3748 <ProductName>Postgres</ProductName> data changes visibility rule: during a query execution, data
3749 changes made by the query itself (via SQL-function, SPI-function, triggers)
3750 are invisible to the query scan. For example, in query
3752 INSERT INTO a SELECT * FROM a
3754 tuples inserted are invisible for SELECT's scan. In effect, this
3755 duplicates the database table within itself (subject to unique index
3756 rules, of course) without recursing.
3760 Changes made by query Q are visible to queries that are started after
3761 query Q, no matter whether they are started inside Q (during the execution
3762 of Q) or after Q is done.
3766 <Sect1 id="spi-examples">
3767 <Title>Examples</Title>
3770 This example of SPI usage demonstrates the visibility rule.
3771 There are more complex examples in src/test/regress/regress.c and
3776 This is a very simple example of SPI usage. The procedure execq accepts
3777 an SQL-query in its first argument and tcount in its second, executes the
3778 query using SPI_exec and returns the number of tuples for which the query
3782 #include "executor/spi.h" /* this is what you need to work with SPI */
3784 int execq(text *sql, int cnt);
3787 execq(text *sql, int cnt)
3793 /* Convert given TEXT object to a C string */
3794 query = DatumGetCString(DirectFunctionCall1(textout,
3795 PointerGetDatum(sql)));
3799 ret = SPI_exec(query, cnt);
3801 proc = SPI_processed;
3803 * If this is SELECT and some tuple(s) fetched -
3804 * returns tuples to the caller via elog (NOTICE).
3806 if ( ret == SPI_OK_SELECT && SPI_processed > 0 )
3808 TupleDesc tupdesc = SPI_tuptable->tupdesc;
3809 SPITupleTable *tuptable = SPI_tuptable;
3813 for (j = 0; j < proc; j++)
3815 HeapTuple tuple = tuptable->vals[j];
3817 for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
3818 sprintf(buf + strlen (buf), " %s%s",
3819 SPI_getvalue(tuple, tupdesc, i),
3820 (i == tupdesc->natts) ? " " : " |");
3821 elog (NOTICE, "EXECQ: %s", buf);
3835 Now, compile and create the function:
3838 CREATE FUNCTION execq (text, integer) RETURNS integer
3844 vac=> SELECT execq('CREATE TABLE a (x INTEGER)', 0);
3850 vac=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)',0));
3852 vac=> SELECT execq('SELECT * FROM a',0);
3853 NOTICE:EXECQ: 0 <<< inserted by execq
3855 NOTICE:EXECQ: 1 <<< value returned by execq and inserted by upper INSERT
3862 vac=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a',1);
3868 vac=> SELECT execq('SELECT * FROM a', 10);
3873 NOTICE:EXECQ: 2 <<< 0 + 2, only one tuple inserted - as specified
3877 3 <<< 10 is max value only, 3 is real # of tuples
3880 vac=> DELETE FROM a;
3882 vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
3884 vac=> SELECT * FROM a;
3887 1 <<< no tuples in a (0) + 1
3890 vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
3893 vac=> SELECT * FROM a;
3897 2 <<< there was single tuple in a + 1
3900 -- This demonstrates data changes visibility rule:
3902 vac=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
3909 vac=> SELECT * FROM a;
3914 2 <<< 2 tuples * 1 (x in first tuple)
3915 6 <<< 3 tuples (2 + 1 just inserted) * 2 (x in second tuple)
3917 tuples visible to execq() in different invocations