5 <FirstName>Vadim</FirstName>
6 <Surname>Mikheev</Surname>
9 <Date>Transcribed 1998-01-16</Date>
12 <Title>Server Programming Interface</Title>
15 The <FirstTerm>Server Programming Interface</FirstTerm>
16 (<Acronym>SPI</Acronym>) gives users the
17 ability to run <Acronym>SQL</Acronym> queries inside user-defined
18 <Acronym>C</Acronym> functions.
19 The available Procedural Languages (<Acronym>PL</Acronym>) give an alternate
20 means to access these capabilities.
24 In fact, <Acronym>SPI</Acronym> is just a set of native interface functions
25 to simplify access to the Parser, Planner, Optimizer and Executor.
26 <Acronym>SPI</Acronym> also does some memory management.
30 To avoid misunderstanding we'll use <FirstTerm>function</FirstTerm>
31 to mean <Acronym>SPI</Acronym> interface functions and
32 <FirstTerm>procedure</FirstTerm> for user-defined C-functions
33 using <Acronym>SPI</Acronym>.
37 Procedures which use <Acronym>SPI</Acronym> are called by the
38 Executor. The <Acronym>SPI</Acronym> calls recursively invoke the
39 Executor in turn to run queries. When the Executor is invoked
40 recursively, it may itself call procedures which may make
41 <Acronym>SPI</Acronym> calls.
45 Note, that if during execution of a query from a procedure the transaction
46 is aborted then control will not be returned to your procedure. Rather, all work
47 will be rolled back and the server will wait for the next command from the
48 client. This will be changed in future versions.
52 Other restrictions are the inability to execute BEGIN, END and ABORT
53 (transaction control statements) and cursor operations. This will also be
54 changed in the future.
58 If successful, <Acronym>SPI</Acronym> functions return a non-negative result (either via
59 a returned integer value or in SPI_result global variable, as described below).
60 On error, a negative or NULL result will be returned.
63 <Sect1 id="spi-interface">
64 <Title>Interface Functions</Title>
66 <REFENTRY ID="SPI-SPICONNECT">
68 <REFENTRYTITLE>SPI_connect</REFENTRYTITLE>
69 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
75 Connects your procedure to the SPI manager.
77 <INDEXTERM ID="IX-SPI-SPICONNECT-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
78 <INDEXTERM ID="IX-SPI-SPICONNECT-2"><PRIMARY>SPI_connect</PRIMARY></INDEXTERM>
82 <DATE>1997-12-24</DATE>
88 <REFSECT2 ID="R2-SPI-SPICONNECT-1">
90 <DATE>1997-12-24</DATE>
98 <REFSECT2 ID="R2-SPI-SPICONNECT-2">
100 <DATE>1997-12-24</DATE>
113 <TERM><ReturnValue>SPI_OK_CONNECT</ReturnValue>
122 <TERM><ReturnValue>SPI_ERROR_CONNECT</ReturnValue>
138 <REFSECT1 ID="R1-SPI-SPICONNECT-1">
140 <DATE>1997-12-24</DATE>
145 <FUNCTION>SPI_connect</FUNCTION> opens a connection to the <ProductName>Postgres</ProductName> backend.
146 You should call this function if you will need to execute queries. Some
147 utility SPI functions may be called from un-connected procedures.
150 If your procedure is already connected,
151 <Function>SPI_connect</Function> will return an
152 <ReturnValue>SPI_ERROR_CONNECT</ReturnValue> error. Note that this
153 may happen if a procedure which has called
154 <Function>SPI_connect</Function> directly calls another procedure
155 which itself calls <Function>SPI_connect</Function>. While
156 recursive calls to the <Acronym>SPI</Acronym> manager are permitted
157 when an <Acronym>SPI</Acronym> query invokes another function which
158 uses <Acronym>SPI</Acronym>, directly nested calls to
159 <Function>SPI_connect</Function> and
160 <Function>SPI_finish</Function> are forbidden.
163 <REFSECT1 ID="R1-SPI-SPICONNECT-2">
168 XXX thomas 1997-12-24
172 <REFSECT1 ID="R1-SPI-SPICONNECT-3">
175 <PARA><FUNCTION>SPI_connect</FUNCTION> performs the following:
176 Initializes the SPI internal
177 structures for query execution and memory management.
181 <REFSECT1 ID="R1-SPI-SPICONNECT-4">
190 <!-- *********************************************** -->
191 <!-- *********************************************** -->
192 <!-- *********************************************** -->
194 <REFENTRY ID="SPI-SPIFINISH">
196 <REFENTRYTITLE>SPI_finish</REFENTRYTITLE>
197 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
203 Disconnects your procedure from the SPI manager.
205 <INDEXTERM ID="IX-SPI-SPIFINISH-1"><PRIMARY>SPI</PRIMARY><SECONDARY>disconnecting</SECONDARY></INDEXTERM>
206 <INDEXTERM ID="IX-SPI-SPIFINISH-2"><PRIMARY>SPI_finish</PRIMARY></INDEXTERM>
210 <DATE>1997-12-24</DATE>
211 </REFSYNOPSISDIVINFO>
216 <REFSECT2 ID="R2-SPI-SPIFINISH-1">
218 <DATE>1997-12-24</DATE>
226 <REFSECT2 ID="R2-SPI-SPIFINISH-2">
228 <DATE>1997-12-24</DATE>
240 <ReturnValue>SPI_OK_FINISH</ReturnValue>
241 if properly disconnected
244 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue>
245 if called from an un-connected procedure
255 <REFSECT1 ID="R1-SPI-SPIFINISH-1">
257 <DATE>1997-12-24</DATE>
262 <FUNCTION>SPI_finish</FUNCTION> closes an existing connection to the <ProductName>Postgres</ProductName> backend.
263 You should call this function after completing operations through the SPI manager.
266 You may get the error return <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if <Function>SPI_finish</Function> is
267 called without having a current valid connection.
268 There is no fundamental problem
269 with this; it means that nothing was done by the SPI manager.
272 <REFSECT1 ID="R1-SPI-SPIFINISH-2">
276 <Function>SPI_finish</Function> <Emphasis>must</Emphasis> be called as a final step by a connected procedure
278 unpredictable results! Note that you can safely skip the call to <Function>SPI_finish</Function>
279 if you abort the transaction (via elog(ERROR)).
283 <REFSECT1 ID="R1-SPI-SPIFINISH-3">
286 <PARA><FUNCTION>SPI_finish</FUNCTION> performs the following:
287 Disconnects your procedure from the SPI manager and frees all memory
288 allocations made by your procedure via <Function>palloc</Function> since
289 the <Function>SPI_connect</Function>.
290 These allocations can't be used any more! See Memory management.
294 <REFSECT1 ID="R1-SPI-SPIFINISH-4">
303 <!-- *********************************************** -->
304 <!-- *********************************************** -->
305 <!-- *********************************************** -->
307 <REFENTRY ID="SPI-SPIEXEC">
309 <REFENTRYTITLE>SPI_exec</REFENTRYTITLE>
310 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
316 Creates an execution plan (parser+planner+optimizer) and executes a query.
318 <INDEXTERM ID="IX-SPI-SPIEXEC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>executing</SECONDARY></INDEXTERM>
319 <INDEXTERM ID="IX-SPI-SPIEXEC-2"><PRIMARY>SPI_exec</PRIMARY></INDEXTERM>
323 <DATE>1997-12-24</DATE>
324 </REFSYNOPSISDIVINFO>
326 SPI_exec(<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>)
329 <REFSECT2 ID="R2-SPI-SPIEXEC-1">
331 <DATE>1997-12-24</DATE>
338 char *<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
342 String containing query plan
348 int <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>
352 Maximum number of tuples to return
359 <REFSECT2 ID="R2-SPI-SPIEXEC-2">
361 <DATE>1997-12-24</DATE>
373 <ReturnValue>SPI_OK_EXEC</ReturnValue> if properly disconnected
376 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if called from an un-connected procedure
379 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0.
382 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is unconnected.
385 <ReturnValue>SPI_ERROR_COPY</ReturnValue> if COPY TO/FROM stdin.
388 <ReturnValue>SPI_ERROR_CURSOR</ReturnValue> if DECLARE/CLOSE CURSOR, FETCH.
391 <ReturnValue>SPI_ERROR_TRANSACTION</ReturnValue> if BEGIN/ABORT/END.
394 <ReturnValue>SPI_ERROR_OPUNKNOWN</ReturnValue> if type of query is unknown (this shouldn't occur).
399 If execution of your query was successful then one of the following
400 (non-negative) values will be returned:
403 <ReturnValue>SPI_OK_UTILITY</ReturnValue> if some utility (e.g. CREATE TABLE ...) was executed
406 <ReturnValue>SPI_OK_SELECT</ReturnValue> if SELECT (but not SELECT ... INTO!) was executed
409 <ReturnValue>SPI_OK_SELINTO</ReturnValue> if SELECT ... INTO was executed
412 <ReturnValue>SPI_OK_INSERT</ReturnValue> if INSERT (or INSERT ... SELECT) was executed
415 <ReturnValue>SPI_OK_DELETE</ReturnValue> if DELETE was executed
418 <ReturnValue>SPI_OK_UPDATE</ReturnValue> if UPDATE was executed
428 <REFSECT1 ID="R1-SPI-SPIEXEC-1">
430 <DATE>1997-12-24</DATE>
435 <FUNCTION>SPI_exec</FUNCTION> creates an execution plan (parser+planner+optimizer)
436 and executes the query for <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> tuples.
440 <REFSECT1 ID="R1-SPI-SPIEXEC-2">
444 This should only be called from a connected procedure.
445 If <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> is zero then it executes the query for all tuples returned by the
446 query scan. Using <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> > 0 you may restrict the number of tuples for
447 which the query will be executed. For example,
450 SPI_exec ("INSERT INTO tab SELECT * FROM tab", 5);
453 will allow at most 5 tuples to be inserted into table.
455 If execution of your query was successful then a non-negative value will be returned.
459 You may pass many queries in one string or query string may be
460 re-written by RULEs. <Function>SPI_exec</Function> returns the result for the last query
466 The actual number of tuples for which the (last) query was executed is
467 returned in the global variable SPI_processed (if not <ReturnValue>SPI_OK_UTILITY</ReturnValue>).
469 If <ReturnValue>SPI_OK_SELECT</ReturnValue> returned and SPI_processed > 0 then you may use global
470 pointer SPITupleTable *SPI_tuptable to access the selected tuples:
472 Also NOTE, that <Function>SPI_finish</Function> frees and makes all SPITupleTables
473 unusable! (See Memory management).
477 <Function>SPI_exec</Function> may return one of the following (negative) values:
480 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0.
483 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is unconnected.
486 <ReturnValue>SPI_ERROR_COPY</ReturnValue> if COPY TO/FROM stdin.
489 <ReturnValue>SPI_ERROR_CURSOR</ReturnValue> if DECLARE/CLOSE CURSOR, FETCH.
492 <ReturnValue>SPI_ERROR_TRANSACTION</ReturnValue> if BEGIN/ABORT/END.
495 <ReturnValue>SPI_ERROR_OPUNKNOWN</ReturnValue> if type of query is unknown (this shouldn't occur).
501 <REFSECT1 ID="R1-SPI-SPIEXEC-3">
504 <PARA><FUNCTION>SPI_exec</FUNCTION> performs the following:
505 Disconnects your procedure from the SPI manager and frees all memory
506 allocations made by your procedure via <Function>palloc</Function> since the <Function>SPI_connect</Function>.
507 These allocations can't be used any more! See Memory management.
511 <REFSECT1 ID="R1-SPI-SPIEXEC-4">
515 If <ReturnValue>SPI_OK_SELECT</ReturnValue> returned and SPI_processed > 0 then you may use the global
516 pointer SPITupleTable *SPI_tuptable to access the selected tuples.
519 Structure SPITupleTable is defined in spi.h:
523 uint32 alloced; /* # of alloced vals */
524 uint32 free; /* # of free vals */
525 TupleDesc tupdesc; /* tuple descriptor */
526 HeapTuple *vals; /* tuples */
531 HeapTuple *vals is an array of pointers to tuples. TupleDesc tupdesc is
532 a tuple descriptor which you may pass to SPI functions dealing with
536 NOTE! Functions <Function>SPI_exec</Function>, <Function>SPI_execp</Function> and <Function>SPI_prepare</Function> change both
537 SPI_processed and SPI_tuptable (just the pointer, not the contents of the
538 structure)! So, save them in local procedure variables if you need them.
541 Also NOTE, that <Function>SPI_finish</Function> frees and makes all SPITupleTables
542 unusable! (See Memory management).
548 <!-- *********************************************** -->
549 <!-- *********************************************** -->
550 <!-- *********************************************** -->
552 <REFENTRY ID="SPI-SPIPREPARE">
554 <REFENTRYTITLE>SPI_prepare</REFENTRYTITLE>
555 <REFMISCINFO>SPI - Plan Preparation</REFMISCINFO>
561 Connects your procedure to the SPI manager.
563 <INDEXTERM ID="IX-SPI-SPIPREPARE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
564 <INDEXTERM ID="IX-SPI-SPIPREPARE-2"><PRIMARY>SPI_prepare</PRIMARY></INDEXTERM>
568 <DATE>1997-12-24</DATE>
569 </REFSYNOPSISDIVINFO>
571 SPI_prepare(<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">nargs</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">argtypes</REPLACEABLE>)
574 <REFSECT2 ID="R2-SPI-SPIPREPARE-1">
576 <DATE>1997-12-24</DATE>
583 <REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
593 <REPLACEABLE CLASS="PARAMETER">nargs</REPLACEABLE>
597 Number of input parameters ($1 ... $nargs - as in SQL-functions)
603 <REPLACEABLE CLASS="PARAMETER">argtypes</REPLACEABLE>
607 Pointer list of type <Acronym>OID</Acronym>s to input arguments
614 <REFSECT2 ID="R2-SPI-SPIPREPARE-2">
616 <DATE>1997-12-24</DATE>
626 Pointer to an execution plan (parser+planner+optimizer)
634 <REFSECT1 ID="R1-SPI-SPIPREPARE-1">
636 <DATE>1997-12-24</DATE>
641 <FUNCTION>SPI_prepare</FUNCTION>
642 creates and returns an execution plan (parser+planner+optimizer) but doesn't
643 execute the query. Should only be called from a connected procedure.
647 <REFSECT1 ID="R1-SPI-SPIPREPARE-2">
651 nargs is number of parameters ($1 ... $nargs - as in SQL-functions),
652 and nargs may be 0 only if there is not any $1 in query.
655 Execution of prepared execution plans is sometimes much faster so this
656 feature may be useful if the same query will be executed many times.
659 The plan returned by <Function>SPI_prepare</Function> may be used only in current
660 invocation of the procedure since <Function>SPI_finish</Function> frees memory allocated for a plan.
661 See <Function>SPI_saveplan</Function>.
664 If successful, a non-null pointer will be returned. Otherwise, you'll get
665 a NULL plan. In both cases SPI_result will be set like the value returned
666 by SPI_exec, except that it is set to
667 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or nargs < 0 or nargs > 0 && argtypes
673 <REFSECT1 ID="R1-SPI-SPIPREPARE-3">
676 <PARA><FUNCTION>SPI_prepare</FUNCTION> performs the following:
682 <REFSECT1 ID="R1-SPI-SPIPREPARE-4">
691 <!-- *********************************************** -->
692 <!-- *********************************************** -->
693 <!-- *********************************************** -->
695 <REFENTRY ID="SPI-SPISAVEPLAN">
697 <REFENTRYTITLE>SPI_saveplan</REFENTRYTITLE>
698 <REFMISCINFO>SPI - Plan Storage</REFMISCINFO>
701 <REFNAME>SPI_saveplan
706 <INDEXTERM ID="IX-SPI-SPISAVEPLAN-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
707 <INDEXTERM ID="IX-SPI-SPISAVEPLAN-2"><PRIMARY>SPI_saveplan</PRIMARY></INDEXTERM>
711 <DATE>1997-12-24</DATE>
712 </REFSYNOPSISDIVINFO>
714 SPI_saveplan(<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>)
717 <REFSECT2 ID="R2-SPI-SPISAVEPLAN-1">
719 <DATE>1997-12-24</DATE>
726 void *<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
737 <REFSECT2 ID="R2-SPI-SPISAVEPLAN-2">
739 <DATE>1997-12-24</DATE>
749 Execution plan location. NULL if unsuccessful.
760 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if plan is NULL
763 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is un-connected
773 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-1">
775 <DATE>1997-12-24</DATE>
780 <FUNCTION>SPI_saveplan</FUNCTION>
781 stores a plan prepared by <Function>SPI_prepare</Function> in safe memory
782 protected from freeing by <Function>SPI_finish</Function> or the transaction manager.
785 In the current version of <ProductName>Postgres</ProductName> there is no ability to
786 store prepared plans in the system
787 catalog and fetch them from there for execution. This will be implemented
790 As an alternative, there is the ability to reuse prepared plans in the
791 consequent invocations of your procedure in the current session.
792 Use <Function>SPI_execp</Function> to execute this saved plan.
795 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-2">
799 <Function>SPI_saveplan</Function> saves a passed plan (prepared by <Function>SPI_prepare</Function>) in memory
800 protected from freeing by <Function>SPI_finish</Function> and by the transaction manager and
801 returns a pointer to the saved plan. You may save the pointer returned in
802 a local variable. Always check if this pointer is NULL or not either when
803 preparing a plan or using an already prepared plan in SPI_execp (see below).
807 If one of the objects (a relation, function, etc.) referenced by the prepared
808 plan is dropped during your session (by your backend or another process) then the
809 results of <Function>SPI_execp</Function> for this plan will be unpredictable.
816 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-3">
819 <PARA><FUNCTION>SPI_saveplan</FUNCTION> performs the following:
825 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-4">
834 <!-- *********************************************** -->
835 <!-- *********************************************** -->
836 <!-- *********************************************** -->
838 <REFENTRY ID="SPI-SPIEXECP">
840 <REFENTRYTITLE>SPI_execp</REFENTRYTITLE>
841 <REFMISCINFO>SPI - Plan Execution</REFMISCINFO>
847 Executes a plan from <Function>SPI_saveplan</Function>
849 <INDEXTERM ID="IX-SPI-SPIEXECP-1"><PRIMARY>SPI</PRIMARY><SECONDARY>connecting</SECONDARY></INDEXTERM>
850 <INDEXTERM ID="IX-SPI-SPIEXECP-2"><PRIMARY>SPI_execp</PRIMARY></INDEXTERM>
854 <DATE>1997-12-24</DATE>
855 </REFSYNOPSISDIVINFO>
857 SPI_execp(<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>,
858 <REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>,
859 <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>,
860 <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>)
863 <REFSECT2 ID="R2-SPI-SPIEXECP-1">
865 <DATE>1997-12-24</DATE>
872 void *<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
882 Datum *<REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
886 Actual parameter values
892 char *<REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
896 Array describing what parameters get NULLs
898 <Member><literal>n</literal> indicates NULL allowed</Member>
899 <Member>A space indicates NULL not allowed</Member>
906 int <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>
910 Number of tuples for which plan is to be executed
917 <REFSECT2 ID="R2-SPI-SPIEXECP-2">
919 <DATE>1997-12-24</DATE>
929 Returns the same value as <Function>SPI_exec</Function> as well as
932 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue>
933 if <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
934 is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0
937 <ReturnValue>SPI_ERROR_PARAM</ReturnValue>
938 if <REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
940 and <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
941 was prepared with some parameters.
953 <Function>SPI_exec</Function> if successful
963 <Function>SPI_exec</Function> if successful
971 <REFSECT1 ID="R1-SPI-SPIEXECP-1">
973 <DATE>1997-12-24</DATE>
978 <FUNCTION>SPI_execp</FUNCTION>
979 stores a plan prepared by <Function>SPI_prepare</Function> in safe memory
980 protected from freeing by <Function>SPI_finish</Function> or the transaction manager.
983 In the current version of <ProductName>Postgres</ProductName> there is no ability to
984 store prepared plans in the system
985 catalog and fetch them from there for execution. This will be implemented
988 As a work arround, there is the ability to reuse prepared plans in the
989 consequent invocations of your procedure in the current session.
990 Use <Function>SPI_execp</Function> to execute this saved plan.
993 <REFSECT1 ID="R1-SPI-SPIEXECP-2">
997 If <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
999 <Function>SPI_execp</Function>
1000 assumes that all values (if any) are NOT NULL.
1004 If one of the objects (a relation, function, etc.) referenced by the prepared
1005 plan is dropped during your session (by your backend or another process) then the
1006 results of <Function>SPI_execp</Function> for this plan will be unpredictable.
1013 <REFSECT1 ID="R1-SPI-SPIEXECP-3">
1016 <PARA><FUNCTION>SPI_execp</FUNCTION> performs the following:
1022 <REFSECT1 ID="R1-SPI-SPIEXECP-4">
1033 <Sect1 id="spi-interface-support">
1034 <Title>Interface Support Functions</Title>
1037 All functions described below may be used by connected and unconnected
1041 <!-- *********************************************** -->
1042 <!-- *********************************************** -->
1043 <!-- *********************************************** -->
1045 <REFENTRY ID="SPI-SPICOPYTUPLE">
1047 <REFENTRYTITLE>SPI_copytuple</REFENTRYTITLE>
1048 <REFMISCINFO>SPI - Tuple Copy</REFMISCINFO>
1051 <REFNAME>SPI_copytuple
1054 Makes copy of tuple in upper Executor context
1056 <INDEXTERM ID="IX-SPI-SPICOPYTUPLE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuples</SECONDARY></INDEXTERM>
1057 <INDEXTERM ID="IX-SPI-SPICOPYTUPLE-2"><PRIMARY>SPI_copytuple</PRIMARY></INDEXTERM>
1060 <REFSYNOPSISDIVINFO>
1061 <DATE>1997-12-24</DATE>
1062 </REFSYNOPSISDIVINFO>
1064 SPI_copytuple(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>)
1067 <REFSECT2 ID="R2-SPI-SPICOPYTUPLE-1">
1069 <DATE>1997-12-24</DATE>
1076 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1080 Input tuple to be copied
1087 <REFSECT2 ID="R2-SPI-SPICOPYTUPLE-2">
1089 <DATE>1997-12-24</DATE>
1103 <ReturnValue>non-NULL</ReturnValue>
1104 if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1105 is not NULL and the copy was successful
1108 <ReturnValue>NULL</ReturnValue>
1109 only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1120 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-1">
1122 <DATE>1997-12-24</DATE>
1127 <FUNCTION>SPI_copytuple</FUNCTION>
1128 makes a copy of tuple in upper Executor context. See the section on Memory Management.
1131 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-2">
1139 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-3">
1147 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-4">
1156 <!-- *********************************************** -->
1157 <!-- *********************************************** -->
1158 <!-- *********************************************** -->
1160 <REFENTRY ID="SPI-SPICOPYTUPLEDESC">
1162 <REFENTRYTITLE>SPI_copytupledesc</REFENTRYTITLE>
1163 <REFMISCINFO>SPI - Tuple Descriptor Copy</REFMISCINFO>
1166 <REFNAME>SPI_copytupledesc
1169 Makes copy of tuple descriptor in upper Executor context
1171 <INDEXTERM ID="IX-SPI-SPICOPYTUPLEDESC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuple descriptors</SECONDARY></INDEXTERM>
1172 <INDEXTERM ID="IX-SPI-SPICOPYTUPLEDESC-2"><PRIMARY>SPI_copytupledesc</PRIMARY></INDEXTERM>
1175 <REFSYNOPSISDIVINFO>
1176 <DATE>2001-08-02</DATE>
1177 </REFSYNOPSISDIVINFO>
1179 SPI_copytupledesc(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>)
1182 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-1">
1184 <DATE>2001-08-02</DATE>
1191 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1195 Input tuple descriptor to be copied
1202 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-2">
1204 <DATE>2001-08-02</DATE>
1215 Copied tuple descriptor
1218 <ReturnValue>non-NULL</ReturnValue>
1219 if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1220 is not NULL and the copy was successful
1223 <ReturnValue>NULL</ReturnValue>
1224 only if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1235 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-1">
1237 <DATE>2001-08-02</DATE>
1242 <FUNCTION>SPI_copytupledesc</FUNCTION>
1243 makes a copy of tupdesc in upper Executor context. See the section on Memory Management.
1246 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-2">
1254 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-3">
1262 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-4">
1271 <!-- *********************************************** -->
1272 <!-- *********************************************** -->
1273 <!-- *********************************************** -->
1275 <REFENTRY ID="SPI-SPIMODIFYTUPLE">
1277 <REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
1278 <REFMISCINFO>SPI - Tuple Modify</REFMISCINFO>
1281 <REFNAME>SPI_modifytuple
1284 Modifies tuple of relation
1286 <INDEXTERM ID="IX-SPI-SPIMODIFYTUPLE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>modifying tuples</SECONDARY></INDEXTERM>
1287 <INDEXTERM ID="IX-SPI-SPIMODIFYTUPLE-2"><PRIMARY>SPI_modifytuple</PRIMARY></INDEXTERM>
1290 <REFSYNOPSISDIVINFO>
1291 <DATE>1997-12-24</DATE>
1292 </REFSYNOPSISDIVINFO>
1294 SPI_modifytuple(<REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE> , <REPLACEABLE CLASS="PARAMETER">nattrs</REPLACEABLE>
1295 , <REPLACEABLE CLASS="PARAMETER">attnum</REPLACEABLE> , <REPLACEABLE CLASS="PARAMETER">Values</REPLACEABLE> , <REPLACEABLE CLASS="PARAMETER">Nulls</REPLACEABLE>)
1298 <REFSECT2 ID="R2-SPI-SPIMODIFYTUPLE-1">
1300 <DATE>1997-12-24</DATE>
1307 Relation <REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>
1316 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1320 Input tuple to be modified
1326 int <REPLACEABLE CLASS="PARAMETER">nattrs</REPLACEABLE>
1330 Number of attribute numbers in attnum
1336 int * <REPLACEABLE CLASS="PARAMETER">attnum</REPLACEABLE>
1340 Array of numbers of the attributes that are to be changed
1346 Datum * <REPLACEABLE CLASS="PARAMETER">Values</REPLACEABLE>
1350 New values for the attributes specified
1356 char * <REPLACEABLE CLASS="PARAMETER">Nulls</REPLACEABLE>
1360 Which attributes are NULL, if any
1367 <REFSECT2 ID="R2-SPI-SPIMODIFYTUPLE-2">
1369 <DATE>1997-12-24</DATE>
1380 New tuple with modifications
1383 <ReturnValue>non-NULL</ReturnValue>
1384 if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1385 is not NULL and the modify was successful
1388 <ReturnValue>NULL</ReturnValue>
1389 only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1404 <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if rel is NULL or tuple is NULL or natts ≤ 0 or
1405 attnum is NULL or Values is NULL.
1408 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> if there is an invalid
1409 attribute number in attnum (attnum ≤ 0 or > number of
1410 attributes in tuple)
1420 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-1">
1422 <DATE>1997-12-24</DATE>
1427 <FUNCTION>SPI_modifytuple</FUNCTION>
1428 Modifies a tuple in upper Executor context. See the section on Memory Management.
1431 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-2">
1435 If successful, a pointer to the new tuple is returned. The new tuple is
1436 allocated in upper Executor context (see Memory management). Passed tuple
1441 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-3">
1449 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-4">
1458 <!-- *********************************************** -->
1459 <!-- *********************************************** -->
1460 <!-- *********************************************** -->
1462 <REFENTRY ID="SPI-SPIFNUMBER">
1464 <REFENTRYTITLE>SPI_fnumber</REFENTRYTITLE>
1465 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1468 <REFNAME>SPI_fnumber
1471 Finds the attribute number for specified attribute
1473 <INDEXTERM ID="IX-SPI-SPIFNUMBER-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1474 <INDEXTERM ID="IX-SPI-SPIFNUMBER-2"><PRIMARY>SPI_fnumber</PRIMARY></INDEXTERM>
1477 <REFSYNOPSISDIVINFO>
1478 <DATE>1997-12-24</DATE>
1479 </REFSYNOPSISDIVINFO>
1481 SPI_fnumber(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>)
1484 <REFSECT2 ID="R2-SPI-SPIFNUMBER-1">
1486 <DATE>1997-12-24</DATE>
1493 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1497 Input tuple description
1503 char * <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>
1514 <REFSECT2 ID="R2-SPI-SPIFNUMBER-2">
1516 <DATE>1997-12-24</DATE>
1530 Valid one-based index number of attribute
1533 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> if the named attribute is not found
1543 <REFSECT1 ID="R1-SPI-SPIFNUMBER-1">
1545 <DATE>1997-12-24</DATE>
1550 <FUNCTION>SPI_fnumber</FUNCTION>
1551 returns the attribute number for the attribute with name in fname.
1554 <REFSECT1 ID="R1-SPI-SPIFNUMBER-2">
1558 Attribute numbers are 1 based.
1562 <REFSECT1 ID="R1-SPI-SPIFNUMBER-3">
1570 <REFSECT1 ID="R1-SPI-SPIFNUMBER-4">
1579 <!-- *********************************************** -->
1580 <!-- *********************************************** -->
1581 <!-- *********************************************** -->
1583 <REFENTRY ID="SPI-SPIFNAME">
1585 <REFENTRYTITLE>SPI_fname</REFENTRYTITLE>
1586 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1592 Finds the attribute name for the specified attribute
1594 <INDEXTERM ID="IX-SPI-SPIFNAME-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1595 <INDEXTERM ID="IX-SPI-SPIFNAME-2"><PRIMARY>SPI_fname</PRIMARY></INDEXTERM>
1598 <REFSYNOPSISDIVINFO>
1599 <DATE>1997-12-24</DATE>
1600 </REFSYNOPSISDIVINFO>
1602 SPI_fname(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>)
1605 <REFSECT2 ID="R2-SPI-SPIFNAME-1">
1607 <DATE>1997-12-24</DATE>
1614 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1618 Input tuple description
1624 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1635 <REFSECT2 ID="R2-SPI-SPIFNAME-2">
1637 <DATE>1997-12-24</DATE>
1651 NULL if fnumber is out of range
1655 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> on error
1665 <REFSECT1 ID="R1-SPI-SPIFNAME-1">
1667 <DATE>1997-12-24</DATE>
1672 <FUNCTION>SPI_fname</FUNCTION>
1673 returns the attribute name for the specified attribute.
1676 <REFSECT1 ID="R1-SPI-SPIFNAME-2">
1680 Attribute numbers are 1 based.
1683 <REFSECT1 ID="R1-SPI-SPIFNAME-3">
1687 Returns a newly-allocated copy of the attribute name.
1691 <REFSECT1 ID="R1-SPI-SPIFNAME-4">
1700 <!-- *********************************************** -->
1701 <!-- *********************************************** -->
1702 <!-- *********************************************** -->
1704 <REFENTRY ID="SPI-SPIGETVALUE">
1706 <REFENTRYTITLE>SPI_getvalue</REFENTRYTITLE>
1707 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1710 <REFNAME>SPI_getvalue
1713 Returns the string value of the specified attribute
1715 <INDEXTERM ID="IX-SPI-SPIGETVALUE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1716 <INDEXTERM ID="IX-SPI-SPIGETVALUE-2"><PRIMARY>SPI_getvalue</PRIMARY></INDEXTERM>
1719 <REFSYNOPSISDIVINFO>
1720 <DATE>1997-12-24</DATE>
1721 </REFSYNOPSISDIVINFO>
1723 SPI_getvalue(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
1726 <REFSECT2 ID="R2-SPI-SPIGETVALUE-1">
1728 <DATE>1997-12-24</DATE>
1735 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1739 Input tuple to be examined
1745 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1749 Input tuple description
1755 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1766 <REFSECT2 ID="R2-SPI-SPIGETVALUE-2">
1768 <DATE>1997-12-24</DATE>
1779 Attribute value or NULL if
1785 fnumber is out of range
1787 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>)
1790 no output function available
1792 <ReturnValue>SPI_ERROR_NOOUTFUNC</ReturnValue>)
1802 <REFSECT1 ID="R1-SPI-SPIGETVALUE-1">
1804 <DATE>1997-12-24</DATE>
1809 <FUNCTION>SPI_getvalue</FUNCTION>
1810 returns an external (string) representation of the value of the specified attribute.
1813 <REFSECT1 ID="R1-SPI-SPIGETVALUE-2">
1817 Attribute numbers are 1 based.
1820 <REFSECT1 ID="R1-SPI-SPIGETVALUE-3">
1824 Allocates memory as required by the value.
1828 <REFSECT1 ID="R1-SPI-SPIGETVALUE-4">
1837 <!-- *********************************************** -->
1838 <!-- *********************************************** -->
1839 <!-- *********************************************** -->
1841 <REFENTRY ID="SPI-SPIGETBINVAL">
1843 <REFENTRYTITLE>SPI_getbinval</REFENTRYTITLE>
1844 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1847 <REFNAME>SPI_getbinval
1850 Returns the binary value of the specified attribute
1852 <INDEXTERM ID="IX-SPI-SPIGETBINVAL-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1853 <INDEXTERM ID="IX-SPI-SPIGETBINVAL-2"><PRIMARY>SPI_getbinval</PRIMARY></INDEXTERM>
1856 <REFSYNOPSISDIVINFO>
1857 <DATE>1997-12-24</DATE>
1858 </REFSYNOPSISDIVINFO>
1860 SPI_getbinval(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">isnull</REPLACEABLE>)
1863 <REFSECT2 ID="R2-SPI-SPIGETBINVAL-1">
1865 <DATE>1997-12-24</DATE>
1872 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1876 Input tuple to be examined
1882 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1886 Input tuple description
1892 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1903 <REFSECT2 ID="R2-SPI-SPIGETBINVAL-2">
1905 <DATE>1997-12-24</DATE>
1916 Attribute binary value
1922 bool * <REPLACEABLE CLASS="PARAMETER">isnull</REPLACEABLE>
1926 flag for null value in attribute
1938 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
1948 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-1">
1950 <DATE>1997-12-24</DATE>
1955 <FUNCTION>SPI_getbinval</FUNCTION>
1956 returns the binary value of the specified attribute.
1959 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-2">
1963 Attribute numbers are 1 based.
1966 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-3">
1970 Does not allocate new space for the binary value.
1974 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-4">
1983 <!-- *********************************************** -->
1984 <!-- *********************************************** -->
1985 <!-- *********************************************** -->
1987 <REFENTRY ID="SPI-SPIGETTYPE">
1989 <REFENTRYTITLE>SPI_gettype</REFENTRYTITLE>
1990 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1993 <REFNAME>SPI_gettype
1996 Returns the type name of the specified attribute
1998 <INDEXTERM ID="IX-SPI-SPIGETTYPE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
1999 <INDEXTERM ID="IX-SPI-SPIGETTYPE-2"><PRIMARY>SPI_gettype</PRIMARY></INDEXTERM>
2002 <REFSYNOPSISDIVINFO>
2003 <DATE>1997-12-24</DATE>
2004 </REFSYNOPSISDIVINFO>
2006 SPI_gettype(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
2009 <REFSECT2 ID="R2-SPI-SPIGETTYPE-1">
2011 <DATE>1997-12-24</DATE>
2018 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2022 Input tuple description
2028 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2039 <REFSECT2 ID="R2-SPI-SPIGETTYPE-2">
2041 <DATE>1997-12-24</DATE>
2052 The type name for the specified attribute number
2064 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2074 <REFSECT1 ID="R1-SPI-SPIGETTYPE-1">
2076 <DATE>1997-12-24</DATE>
2081 <FUNCTION>SPI_gettype</FUNCTION>
2082 returns a copy of the type name for the specified attribute.
2085 <REFSECT1 ID="R1-SPI-SPIGETTYPE-2">
2089 Attribute numbers are 1 based.
2092 <REFSECT1 ID="R1-SPI-SPIGETTYPE-3">
2096 Does not allocate new space for the binary value.
2100 <REFSECT1 ID="R1-SPI-SPIGETTYPE-4">
2109 <!-- *********************************************** -->
2110 <!-- *********************************************** -->
2111 <!-- *********************************************** -->
2113 <REFENTRY ID="SPI-SPIGETTYPEID">
2115 <REFENTRYTITLE>SPI_gettypeid</REFENTRYTITLE>
2116 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2119 <REFNAME>SPI_gettypeid
2122 Returns the type <Acronym>OID</Acronym> of the specified attribute
2124 <INDEXTERM ID="IX-SPI-SPIGETTYPEID-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
2125 <INDEXTERM ID="IX-SPI-SPIGETTYPEID-2"><PRIMARY>SPI_gettypeid</PRIMARY></INDEXTERM>
2128 <REFSYNOPSISDIVINFO>
2129 <DATE>1997-12-24</DATE>
2130 </REFSYNOPSISDIVINFO>
2132 SPI_gettypeid(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
2135 <REFSECT2 ID="R2-SPI-SPIGETTYPEID-1">
2137 <DATE>1997-12-24</DATE>
2144 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2148 Input tuple description
2154 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2165 <REFSECT2 ID="R2-SPI-SPIGETTYPEID-2">
2167 <DATE>1997-12-24</DATE>
2174 <Acronym>OID</Acronym>
2178 The type <Acronym>OID</Acronym> for the specified attribute number
2190 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2200 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-1">
2202 <DATE>1997-12-24</DATE>
2207 <FUNCTION>SPI_gettypeid</FUNCTION>
2208 returns the type <Acronym>OID</Acronym> for the specified attribute.
2211 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-2">
2215 Attribute numbers are 1 based.
2218 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-3">
2226 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-4">
2235 <!-- *********************************************** -->
2236 <!-- *********************************************** -->
2237 <!-- *********************************************** -->
2239 <REFENTRY ID="SPI-SPIGETRELNAME">
2241 <REFENTRYTITLE>SPI_getrelname</REFENTRYTITLE>
2242 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2245 <REFNAME>SPI_getrelname
2248 Returns the name of the specified relation
2250 <INDEXTERM ID="IX-SPI-SPIGETRELNAME-1"><PRIMARY>SPI</PRIMARY><SECONDARY>decoding tuples</SECONDARY></INDEXTERM>
2251 <INDEXTERM ID="IX-SPI-SPIGETRELNAME-2"><PRIMARY>SPI_getrelname</PRIMARY></INDEXTERM>
2254 <REFSYNOPSISDIVINFO>
2255 <DATE>1997-12-24</DATE>
2256 </REFSYNOPSISDIVINFO>
2258 SPI_getrelname(<REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>)
2261 <REFSECT2 ID="R2-SPI-SPIGETRELNAME-1">
2263 <DATE>1997-12-24</DATE>
2270 Relation <REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>
2281 <REFSECT2 ID="R2-SPI-SPIGETRELNAME-2">
2283 <DATE>1997-12-24</DATE>
2294 The name of the specified relation
2302 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-1">
2304 <DATE>1997-12-24</DATE>
2309 <FUNCTION>SPI_getrelname</FUNCTION>
2310 returns the name of the specified relation.
2313 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-2">
2320 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-3">
2324 Copies the relation name into new storage.
2328 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-4">
2337 <!-- *********************************************** -->
2338 <!-- *********************************************** -->
2339 <!-- *********************************************** -->
2341 <REFENTRY ID="SPI-SPIPALLOC">
2343 <REFENTRYTITLE>SPI_palloc</REFENTRYTITLE>
2344 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
2350 Allocates memory in upper Executor context
2352 <INDEXTERM ID="IX-SPI-SPIPALLOC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
2353 <INDEXTERM ID="IX-SPI-SPIPALLOC-2"><PRIMARY>SPI_palloc</PRIMARY></INDEXTERM>
2356 <REFSYNOPSISDIVINFO>
2357 <DATE>1997-12-24</DATE>
2358 </REFSYNOPSISDIVINFO>
2360 SPI_palloc(<REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)
2363 <REFSECT2 ID="R2-SPI-SPIPALLOC-1">
2365 <DATE>1997-12-24</DATE>
2372 Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>
2376 Octet size of storage to allocate
2383 <REFSECT2 ID="R2-SPI-SPIPALLOC-2">
2385 <DATE>1997-12-24</DATE>
2396 New storage space of specified size
2404 <REFSECT1 ID="R1-SPI-SPIPALLOC-1">
2406 <DATE>1997-12-24</DATE>
2411 <FUNCTION>SPI_palloc</FUNCTION>
2412 allocates memory in upper Executor context. See section on memory management.
2415 <REFSECT1 ID="R1-SPI-SPIPALLOC-2">
2423 <REFSECT1 ID="R1-SPI-SPIPALLOC-3">
2432 <REFSECT1 ID="R1-SPI-SPIPALLOC-4">
2441 <!-- *********************************************** -->
2442 <!-- *********************************************** -->
2443 <!-- *********************************************** -->
2445 <REFENTRY ID="SPI-SPIREPALLOC">
2447 <REFENTRYTITLE>SPI_repalloc</REFENTRYTITLE>
2448 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
2451 <REFNAME>SPI_repalloc
2454 Re-allocates memory in upper Executor context
2456 <INDEXTERM ID="IX-SPI-SPIREPALLOC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
2457 <INDEXTERM ID="IX-SPI-SPIREPALLOC-2"><PRIMARY>SPI_repalloc</PRIMARY></INDEXTERM>
2460 <REFSYNOPSISDIVINFO>
2461 <DATE>1997-12-24</DATE>
2462 </REFSYNOPSISDIVINFO>
2464 SPI_repalloc(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)
2467 <REFSECT2 ID="R2-SPI-SPIREPALLOC-1">
2469 <DATE>1997-12-24</DATE>
2476 void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
2480 Pointer to existing storage
2486 Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>
2490 Octet size of storage to allocate
2497 <REFSECT2 ID="R2-SPI-SPIREPALLOC-2">
2499 <DATE>1997-12-24</DATE>
2510 New storage space of specified size with contents copied from existing area
2518 <REFSECT1 ID="R1-SPI-SPIREPALLOC-1">
2520 <DATE>1997-12-24</DATE>
2525 <FUNCTION>SPI_repalloc</FUNCTION>
2526 re-allocates memory in upper Executor context. See section on memory management.
2529 <REFSECT1 ID="R1-SPI-SPIREPALLOC-2">
2537 <REFSECT1 ID="R1-SPI-SPIREPALLOC-3">
2546 <REFSECT1 ID="R1-SPI-SPIREPALLOC-4">
2555 <!-- *********************************************** -->
2556 <!-- *********************************************** -->
2557 <!-- *********************************************** -->
2559 <REFENTRY ID="SPI-SPIPFREE">
2561 <REFENTRYTITLE>SPI_pfree</REFENTRYTITLE>
2562 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
2568 Frees memory from upper Executor context
2570 <INDEXTERM ID="IX-SPI-SPIPFREE-1"><PRIMARY>SPI</PRIMARY><SECONDARY>allocating space</SECONDARY></INDEXTERM>
2571 <INDEXTERM ID="IX-SPI-SPIPFREE-2"><PRIMARY>SPI_pfree</PRIMARY></INDEXTERM>
2574 <REFSYNOPSISDIVINFO>
2575 <DATE>1997-12-24</DATE>
2576 </REFSYNOPSISDIVINFO>
2578 SPI_pfree(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>)
2581 <REFSECT2 ID="R2-SPI-SPIPFREE-1">
2583 <DATE>1997-12-24</DATE>
2590 void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
2594 Pointer to existing storage
2601 <REFSECT2 ID="R2-SPI-SPIPFREE-2">
2603 <DATE>1997-12-24</DATE>
2621 <REFSECT1 ID="R1-SPI-SPIPFREE-1">
2623 <DATE>1997-12-24</DATE>
2628 <FUNCTION>SPI_pfree</FUNCTION>
2629 frees memory in upper Executor context. See section on memory management.
2632 <REFSECT1 ID="R1-SPI-SPIPFREE-2">
2640 <REFSECT1 ID="R1-SPI-SPIPFREE-3">
2649 <REFSECT1 ID="R1-SPI-SPIPFREE-4">
2660 <Sect1 id="spi-memory">
2661 <Title>Memory Management</Title>
2664 Server allocates memory in memory contexts in such way that allocations
2665 made in one context may be freed by context destruction without affecting
2666 allocations made in other contexts. All allocations (via <Function>palloc</Function>, etc) are
2667 made in the context that is chosen as the current one. You'll get
2668 unpredictable results if you'll try to free (or reallocate) memory allocated
2669 not in current context.
2673 Creation and switching between memory contexts are subject of SPI manager
2679 SPI procedures deal with two memory contexts: upper Executor memory
2680 context and procedure memory context (if connected).
2685 Before a procedure is connected to the SPI manager, current memory context
2686 is upper Executor context so all allocation made by the procedure itself via
2687 <Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility functions before connecting to SPI are
2688 made in this context.
2693 After <Function>SPI_connect</Function> is called current context is the
2694 procedure's one. All allocations made via
2695 <Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility
2696 functions (except for <Function>SPI_copytuple</Function>,
2697 <Function>SPI_copytupledesc</Function>,
2698 <Function>SPI_modifytuple</Function>,
2699 <Function>SPI_palloc</Function> and <Function>SPI_repalloc</Function>) are
2700 made in this context.
2705 When a procedure disconnects from the SPI manager (via <Function>SPI_finish</Function>) the
2706 current context is restored to the upper Executor context and all allocations
2707 made in the procedure memory context are freed and can't be used any more!
2712 If you want to return something to the upper Executor then you have to
2713 allocate memory for this in the upper context!
2718 SPI has no ability to automatically free allocations in the upper Executor
2724 SPI automatically frees memory allocated during execution of a query when
2730 <Sect1 id="spi-visibility">
2731 <Title>Visibility of Data Changes</Title>
2734 <ProductName>Postgres</ProductName> data changes visibility rule: during a query execution, data
2735 changes made by the query itself (via SQL-function, SPI-function, triggers)
2736 are invisible to the query scan. For example, in query
2738 INSERT INTO a SELECT * FROM a
2740 tuples inserted are invisible for SELECT's scan. In effect, this
2741 duplicates the database table within itself (subject to unique index
2742 rules, of course) without recursing.
2746 Changes made by query Q are visible to queries that are started after
2747 query Q, no matter whether they are started inside Q (during the execution
2748 of Q) or after Q is done.
2752 <Sect1 id="spi-examples">
2753 <Title>Examples</Title>
2756 This example of SPI usage demonstrates the visibility rule.
2757 There are more complex examples in src/test/regress/regress.c and
2762 This is a very simple example of SPI usage. The procedure execq accepts
2763 an SQL-query in its first argument and tcount in its second, executes the
2764 query using SPI_exec and returns the number of tuples for which the query
2768 #include "executor/spi.h" /* this is what you need to work with SPI */
2770 int execq(text *sql, int cnt);
2773 execq(text *sql, int cnt)
2779 /* Convert given TEXT object to a C string */
2780 query = DatumGetCString(DirectFunctionCall1(textout,
2781 PointerGetDatum(sql)));
2785 ret = SPI_exec(query, cnt);
2787 proc = SPI_processed;
2789 * If this is SELECT and some tuple(s) fetched -
2790 * returns tuples to the caller via elog (NOTICE).
2792 if ( ret == SPI_OK_SELECT && SPI_processed > 0 )
2794 TupleDesc tupdesc = SPI_tuptable->tupdesc;
2795 SPITupleTable *tuptable = SPI_tuptable;
2799 for (j = 0; j < proc; j++)
2801 HeapTuple tuple = tuptable->vals[j];
2803 for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
2804 sprintf(buf + strlen (buf), " %s%s",
2805 SPI_getvalue(tuple, tupdesc, i),
2806 (i == tupdesc->natts) ? " " : " |");
2807 elog (NOTICE, "EXECQ: %s", buf);
2821 Now, compile and create the function:
2824 CREATE FUNCTION execq (TEXT, INT4) RETURNS INT4 AS '...path_to_so' LANGUAGE 'c';
2828 vac=> SELECT execq('CREATE TABLE a (x INT4)', 0);
2834 vac=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)',0));
2836 vac=> select execq('SELECT * FROM a',0);
2837 NOTICE:EXECQ: 0 <<< inserted by execq
2839 NOTICE:EXECQ: 1 <<< value returned by execq and inserted by upper INSERT
2846 vac=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a',1);
2852 vac=> SELECT execq('SELECT * FROM a', 10);
2857 NOTICE:EXECQ: 2 <<< 0 + 2, only one tuple inserted - as specified
2861 3 <<< 10 is max value only, 3 is real # of tuples
2864 vac=> DELETE FROM a;
2866 vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
2868 vac=> SELECT * FROM a;
2871 1 <<< no tuples in a (0) + 1
2874 vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
2877 vac=> SELECT * FROM a;
2881 2 <<< there was single tuple in a + 1
2884 -- This demonstrates data changes visibility rule:
2886 vac=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
2893 vac=> SELECT * FROM a;
2898 2 <<< 2 tuples * 1 (x in first tuple)
2899 6 <<< 3 tuples (2 + 1 just inserted) * 2 (x in second tuple)
2901 tuples visible to execq() in different invocations