]> granicus.if.org Git - postgresql/blob - doc/src/sgml/spi.sgml
Uppercase keywords where appropriate.
[postgresql] / doc / src / sgml / spi.sgml
1 <Chapter id="spi">
2 <DocInfo>
3 <AuthorGroup>
4 <Author>
5 <FirstName>Vadim</FirstName>
6 <Surname>Mikheev</Surname>
7 </Author>
8 </AuthorGroup>
9 <Date>Transcribed 1998-01-16</Date>
10 </DocInfo>
11
12 <Title>Server Programming Interface</Title>
13
14 <Para>
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.
21 </Para>
22
23 <Para>
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.
27 </Para>
28
29 <Para>
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>.
34 </Para>
35
36 <Para>
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.
42 </Para>
43
44 <Para>
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.
49 </Para>
50
51 <Para>
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.
55 </Para>
56
57 <Para>
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.
61 </Para>
62
63 <Sect1 id="spi-interface">
64 <Title>Interface Functions</Title>
65
66 <REFENTRY ID="SPI-SPICONNECT">
67 <REFMETA>
68 <REFENTRYTITLE>SPI_connect</REFENTRYTITLE>
69 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
70 </REFMETA>
71 <REFNAMEDIV>
72 <REFNAME>SPI_connect
73 </REFNAME>
74 <REFPURPOSE>
75    Connects your procedure to the SPI manager.
76 </REFPURPOSE>
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>
79 </REFNAMEDIV>
80 <REFSYNOPSISDIV>
81 <REFSYNOPSISDIVINFO>
82 <DATE>1997-12-24</DATE>
83 </REFSYNOPSISDIVINFO>
84 <SYNOPSIS>
85 int SPI_connect(void)
86 </SYNOPSIS>
87
88 <REFSECT2 ID="R2-SPI-SPICONNECT-1">
89 <REFSECT2INFO>
90 <DATE>1997-12-24</DATE>
91 </REFSECT2INFO>
92 <TITLE>Inputs
93 </TITLE>
94 <PARA>None
95 </PARA>
96 </REFSECT2>
97
98 <REFSECT2 ID="R2-SPI-SPICONNECT-2">
99 <REFSECT2INFO>
100 <DATE>1997-12-24</DATE>
101 </REFSECT2INFO>
102 <TITLE>Outputs
103 </TITLE>
104 <VARIABLELIST>
105 <VARLISTENTRY>
106 <TERM>int
107 </TERM>
108 <LISTITEM>
109 <PARA>
110 Return status
111 <VARIABLELIST>
112 <VARLISTENTRY>
113 <TERM><ReturnValue>SPI_OK_CONNECT</ReturnValue>
114 </TERM>
115 <LISTITEM>
116 <PARA>
117    if connected
118 </PARA>
119 </LISTITEM>
120 </VARLISTENTRY>
121 <VARLISTENTRY>
122 <TERM><ReturnValue>SPI_ERROR_CONNECT</ReturnValue>
123 </TERM>
124 <LISTITEM>
125 <PARA>
126    if not connected
127 </PARA>
128 </LISTITEM>
129 </VARLISTENTRY>
130 </VARIABLELIST>
131 </para>
132 </LISTITEM>
133 </VARLISTENTRY>
134 </VARIABLELIST>
135 </REFSECT2>
136 </REFSYNOPSISDIV>
137
138 <REFSECT1 ID="R1-SPI-SPICONNECT-1">
139 <REFSECT1INFO>
140 <DATE>1997-12-24</DATE>
141 </REFSECT1INFO>
142 <TITLE>Description
143 </TITLE>
144 <PARA>
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.
148 </PARA>
149 <PARA>
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.
161 </PARA>
162 </REFSECT1>
163 <REFSECT1 ID="R1-SPI-SPICONNECT-2">
164 <TITLE>Usage
165 </TITLE>
166 <PARA>
167 <!--
168 XXX thomas 1997-12-24
169 -->
170 </PARA>
171 </REFSECT1>
172 <REFSECT1 ID="R1-SPI-SPICONNECT-3">
173 <TITLE>Algorithm
174 </TITLE>
175 <PARA><FUNCTION>SPI_connect</FUNCTION> performs the following:
176   Initializes the SPI internal
177    structures for query execution and memory management.
178 </PARA>
179 </REFSECT1>
180 <!--
181 <REFSECT1 ID="R1-SPI-SPICONNECT-4">
182 <TITLE>Structures
183 </TITLE>
184 <PARA>None
185 </PARA>
186 </REFSECT1>
187 -->
188 </REFENTRY>
189
190 <!-- *********************************************** -->
191 <!-- *********************************************** -->
192 <!-- *********************************************** -->
193
194 <REFENTRY ID="SPI-SPIFINISH">
195 <REFMETA>
196 <REFENTRYTITLE>SPI_finish</REFENTRYTITLE>
197 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
198 </REFMETA>
199 <REFNAMEDIV>
200 <REFNAME>SPI_finish
201 </REFNAME>
202 <REFPURPOSE>
203    Disconnects your procedure from the SPI manager.
204 </REFPURPOSE>
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>
207 </REFNAMEDIV>
208 <REFSYNOPSISDIV>
209 <REFSYNOPSISDIVINFO>
210 <DATE>1997-12-24</DATE>
211 </REFSYNOPSISDIVINFO>
212 <SYNOPSIS>
213 SPI_finish(void)
214 </SYNOPSIS>
215
216 <REFSECT2 ID="R2-SPI-SPIFINISH-1">
217 <REFSECT2INFO>
218 <DATE>1997-12-24</DATE>
219 </REFSECT2INFO>
220 <TITLE>Inputs
221 </TITLE>
222 <PARA>None
223 </PARA>
224 </REFSECT2>
225
226 <REFSECT2 ID="R2-SPI-SPIFINISH-2">
227 <REFSECT2INFO>
228 <DATE>1997-12-24</DATE>
229 </REFSECT2INFO>
230 <TITLE>Outputs
231 </TITLE>
232 <VARIABLELIST>
233 <VARLISTENTRY>
234 <TERM>int
235 </TERM>
236 <LISTITEM>
237 <PARA>
238 <SimpleList>
239 <Member>
240 <ReturnValue>SPI_OK_FINISH</ReturnValue>
241    if properly disconnected
242 </Member>
243 <Member>
244 <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue>
245    if called from an un-connected procedure
246 </Member>
247 </SimpleList>
248 </PARA>
249 </LISTITEM>
250 </VARLISTENTRY>
251 </VARIABLELIST>
252 </REFSECT2>
253 </REFSYNOPSISDIV>
254
255 <REFSECT1 ID="R1-SPI-SPIFINISH-1">
256 <REFSECT1INFO>
257 <DATE>1997-12-24</DATE>
258 </REFSECT1INFO>
259 <TITLE>Description
260 </TITLE>
261 <PARA>
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.
264 </para>
265 <PARA>
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.
270 </PARA>
271 </REFSECT1>
272 <REFSECT1 ID="R1-SPI-SPIFINISH-2">
273 <TITLE>Usage
274 </TITLE>
275 <PARA>
276    <Function>SPI_finish</Function> <Emphasis>must</Emphasis> be called as a final step by a connected procedure
277  or you may get
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)).
280
281 </PARA>
282 </REFSECT1>
283 <REFSECT1 ID="R1-SPI-SPIFINISH-3">
284 <TITLE>Algorithm
285 </TITLE>
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.
291 </PARA>
292 </REFSECT1>
293 <!--
294 <REFSECT1 ID="R1-SPI-SPIFINISH-4">
295 <TITLE>Structures
296 </TITLE>
297 <PARA>None
298 </PARA>
299 </REFSECT1>
300 -->
301 </REFENTRY>
302
303 <!-- *********************************************** -->
304 <!-- *********************************************** -->
305 <!-- *********************************************** -->
306
307 <REFENTRY ID="SPI-SPIEXEC">
308 <REFMETA>
309 <REFENTRYTITLE>SPI_exec</REFENTRYTITLE>
310 <REFMISCINFO>SPI - Connection Management</REFMISCINFO>
311 </REFMETA>
312 <REFNAMEDIV>
313 <REFNAME>SPI_exec
314 </REFNAME>
315 <REFPURPOSE>
316    Creates an execution plan (parser+planner+optimizer) and executes a query.
317 </REFPURPOSE>
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>
320 </REFNAMEDIV>
321 <REFSYNOPSISDIV>
322 <REFSYNOPSISDIVINFO>
323 <DATE>1997-12-24</DATE>
324 </REFSYNOPSISDIVINFO>
325 <SYNOPSIS>
326 SPI_exec(<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>)
327 </SYNOPSIS>
328
329 <REFSECT2 ID="R2-SPI-SPIEXEC-1">
330 <REFSECT2INFO>
331 <DATE>1997-12-24</DATE>
332 </REFSECT2INFO>
333 <TITLE>Inputs
334 </TITLE>
335 <VARIABLELIST>
336 <VARLISTENTRY>
337 <TERM>
338 char *<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
339 </TERM>
340 <LISTITEM>
341 <PARA>
342 String containing query plan
343 </PARA>
344 </LISTITEM>
345 </VARLISTENTRY>
346 <VARLISTENTRY>
347 <TERM>
348 int <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>
349 </TERM>
350 <LISTITEM>
351 <PARA>
352 Maximum number of tuples to return
353 </PARA>
354 </LISTITEM>
355 </VARLISTENTRY>
356 </VARIABLELIST>
357 </REFSECT2>
358
359 <REFSECT2 ID="R2-SPI-SPIEXEC-2">
360 <REFSECT2INFO>
361 <DATE>1997-12-24</DATE>
362 </REFSECT2INFO>
363 <TITLE>Outputs
364 </TITLE>
365 <VARIABLELIST>
366 <VARLISTENTRY>
367 <TERM>int
368 </TERM>
369 <LISTITEM>
370 <PARA>
371 <SimpleList>
372 <Member>
373    <ReturnValue>SPI_OK_EXEC</ReturnValue> if properly disconnected
374 </Member>
375 <Member>
376    <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if called from an un-connected procedure
377 </Member>
378 <Member>
379    <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0.
380 </Member>
381 <Member>
382    <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is unconnected.
383 </Member>
384 <Member>
385    <ReturnValue>SPI_ERROR_COPY</ReturnValue> if COPY TO/FROM stdin.
386 </Member>
387 <Member>
388    <ReturnValue>SPI_ERROR_CURSOR</ReturnValue> if DECLARE/CLOSE CURSOR, FETCH.
389 </Member>
390 <Member>
391    <ReturnValue>SPI_ERROR_TRANSACTION</ReturnValue> if BEGIN/ABORT/END.
392 </Member>
393 <Member>
394    <ReturnValue>SPI_ERROR_OPUNKNOWN</ReturnValue> if type of query is unknown (this shouldn't occur).
395 </Member>
396 </SimpleList>
397 </para>
398 <Para>
399    If execution of your query was successful then one of the following
400    (non-negative) values will be returned:
401 <SimpleList>
402 <Member>
403    <ReturnValue>SPI_OK_UTILITY</ReturnValue> if some utility (e.g. CREATE TABLE ...) was executed
404 </Member>
405 <Member>
406    <ReturnValue>SPI_OK_SELECT</ReturnValue> if SELECT (but not SELECT ... INTO!) was executed
407 </Member>
408 <Member>
409    <ReturnValue>SPI_OK_SELINTO</ReturnValue> if SELECT ... INTO was executed
410 </Member>
411 <Member>
412    <ReturnValue>SPI_OK_INSERT</ReturnValue> if INSERT (or INSERT ... SELECT) was executed
413 </Member>
414 <Member>
415    <ReturnValue>SPI_OK_DELETE</ReturnValue> if DELETE was executed
416 </Member>
417 <Member>
418    <ReturnValue>SPI_OK_UPDATE</ReturnValue> if UPDATE was executed
419 </Member>
420 </SimpleList>
421 </PARA>
422 </LISTITEM>
423 </VARLISTENTRY>
424 </VARIABLELIST>
425 </REFSECT2>
426 </REFSYNOPSISDIV>
427
428 <REFSECT1 ID="R1-SPI-SPIEXEC-1">
429 <REFSECT1INFO>
430 <DATE>1997-12-24</DATE>
431 </REFSECT1INFO>
432 <TITLE>Description
433 </TITLE>
434 <PARA>
435 <FUNCTION>SPI_exec</FUNCTION> creates an execution plan (parser+planner+optimizer)
436  and executes the query for <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> tuples.
437
438 </PARA>
439 </REFSECT1>
440 <REFSECT1 ID="R1-SPI-SPIEXEC-2">
441 <TITLE>Usage
442 </TITLE>
443 <PARA>
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,
448
449 <ProgramListing>
450 SPI_exec ("INSERT INTO tab SELECT * FROM tab", 5);
451 </ProgramListing>
452
453 will allow at most 5 tuples to be inserted into table.
454
455    If execution of your query was successful then a non-negative value will be returned.
456
457 <Note>
458 <Para>
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
461    executed.
462 </Para>
463 </Note>
464 </para>
465 <Para>
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>).
468
469    If <ReturnValue>SPI_OK_SELECT</ReturnValue> returned and SPI_processed &gt; 0 then you may use global
470    pointer SPITupleTable *SPI_tuptable to access the selected tuples:
471
472    Also NOTE, that <Function>SPI_finish</Function> frees and makes all SPITupleTables
473    unusable! (See Memory management).
474 </Para>
475
476 <Para>
477    <Function>SPI_exec</Function> may return one of the following (negative) values:
478 <SimpleList>
479 <Member>
480    <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if query is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> < 0.
481 </Member>
482 <Member>
483    <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is unconnected.
484 </Member>
485 <Member>
486    <ReturnValue>SPI_ERROR_COPY</ReturnValue> if COPY TO/FROM stdin.
487 </Member>
488 <Member>
489    <ReturnValue>SPI_ERROR_CURSOR</ReturnValue> if DECLARE/CLOSE CURSOR, FETCH.
490 </Member>
491 <Member>
492    <ReturnValue>SPI_ERROR_TRANSACTION</ReturnValue> if BEGIN/ABORT/END.
493 </Member>
494 <Member>
495    <ReturnValue>SPI_ERROR_OPUNKNOWN</ReturnValue> if type of query is unknown (this shouldn't occur).
496 </Member>
497 </SimpleList>
498
499 </PARA>
500 </REFSECT1>
501 <REFSECT1 ID="R1-SPI-SPIEXEC-3">
502 <TITLE>Algorithm
503 </TITLE>
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.
508 </PARA>
509 </REFSECT1>
510 <!--
511 <REFSECT1 ID="R1-SPI-SPIEXEC-4">
512 <TITLE>Structures
513 </TITLE>
514 <PARA>
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.
517
518 <Para>
519    Structure SPITupleTable is defined in spi.h:
520 <ProgramListing>
521    typedef struct
522    {
523        uint32      alloced;        /* # of alloced vals */
524        uint32      free;           /* # of free vals */
525        TupleDesc   tupdesc;        /* tuple descriptor */
526        HeapTuple  *vals;           /* tuples */
527    } SPITupleTable;
528 </ProgramListing>
529
530 <Para>
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
533    tuples.
534
535 <Para>
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.
539
540 <Para>
541    Also NOTE, that <Function>SPI_finish</Function> frees and makes all SPITupleTables
542    unusable! (See Memory management).
543 </PARA>
544 </REFSECT1>
545 -->
546 </REFENTRY>
547
548 <!-- *********************************************** -->
549 <!-- *********************************************** -->
550 <!-- *********************************************** -->
551
552 <REFENTRY ID="SPI-SPIPREPARE">
553 <REFMETA>
554 <REFENTRYTITLE>SPI_prepare</REFENTRYTITLE>
555 <REFMISCINFO>SPI - Plan Preparation</REFMISCINFO>
556 </REFMETA>
557 <REFNAMEDIV>
558 <REFNAME>SPI_prepare
559 </REFNAME>
560 <REFPURPOSE>
561    Connects your procedure to the SPI manager.
562 </REFPURPOSE>
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>
565 </REFNAMEDIV>
566 <REFSYNOPSISDIV>
567 <REFSYNOPSISDIVINFO>
568 <DATE>1997-12-24</DATE>
569 </REFSYNOPSISDIVINFO>
570 <SYNOPSIS>
571 SPI_prepare(<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">nargs</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">argtypes</REPLACEABLE>)
572 </SYNOPSIS>
573
574 <REFSECT2 ID="R2-SPI-SPIPREPARE-1">
575 <REFSECT2INFO>
576 <DATE>1997-12-24</DATE>
577 </REFSECT2INFO>
578 <TITLE>Inputs
579 </TITLE>
580 <VARIABLELIST>
581 <VARLISTENTRY>
582 <TERM>
583 <REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
584 </TERM>
585 <LISTITEM>
586 <PARA>
587 Query string
588 </PARA>
589 </LISTITEM>
590 </VARLISTENTRY>
591 <VARLISTENTRY>
592 <TERM>
593 <REPLACEABLE CLASS="PARAMETER">nargs</REPLACEABLE>
594 </TERM>
595 <LISTITEM>
596 <PARA>
597 Number of input parameters ($1 ... $nargs - as in SQL-functions)
598 </PARA>
599 </LISTITEM>
600 </VARLISTENTRY>
601 <VARLISTENTRY>
602 <TERM>
603 <REPLACEABLE CLASS="PARAMETER">argtypes</REPLACEABLE>
604 </TERM>
605 <LISTITEM>
606 <PARA>
607 Pointer list of type <Acronym>OID</Acronym>s to input arguments
608 </PARA>
609 </LISTITEM>
610 </VARLISTENTRY>
611 </VARIABLELIST>
612 </REFSECT2>
613
614 <REFSECT2 ID="R2-SPI-SPIPREPARE-2">
615 <REFSECT2INFO>
616 <DATE>1997-12-24</DATE>
617 </REFSECT2INFO>
618 <TITLE>Outputs
619 </TITLE>
620 <VARIABLELIST>
621 <VARLISTENTRY>
622 <TERM>void *
623 </TERM>
624 <LISTITEM>
625 <PARA>
626 Pointer to an execution plan (parser+planner+optimizer)
627 </PARA>
628 </LISTITEM>
629 </VARLISTENTRY>
630 </VARIABLELIST>
631 </REFSECT2>
632 </REFSYNOPSISDIV>
633
634 <REFSECT1 ID="R1-SPI-SPIPREPARE-1">
635 <REFSECT1INFO>
636 <DATE>1997-12-24</DATE>
637 </REFSECT1INFO>
638 <TITLE>Description
639 </TITLE>
640 <PARA>
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.
644
645 </PARA>
646 </REFSECT1>
647 <REFSECT1 ID="R1-SPI-SPIPREPARE-2">
648 <TITLE>Usage
649 </TITLE>
650 <PARA>
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.
653 </para>
654 <Para>
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.
657 </para>
658 <Para>
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>.
662 </para>
663 <Para>
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
668    is NULL.
669
670 </PARA>
671 </REFSECT1>
672 <!--
673 <REFSECT1 ID="R1-SPI-SPIPREPARE-3">
674 <TITLE>Algorithm
675 </TITLE>
676 <PARA><FUNCTION>SPI_prepare</FUNCTION> performs the following:
677 TBD
678 </PARA>
679 </REFSECT1>
680 -->
681 <!--
682 <REFSECT1 ID="R1-SPI-SPIPREPARE-4">
683 <TITLE>Structures
684 </TITLE>
685 <PARA>None
686 </PARA>
687 </REFSECT1>
688 -->
689 </REFENTRY>
690
691 <!-- *********************************************** -->
692 <!-- *********************************************** -->
693 <!-- *********************************************** -->
694
695 <REFENTRY ID="SPI-SPISAVEPLAN">
696 <REFMETA>
697 <REFENTRYTITLE>SPI_saveplan</REFENTRYTITLE>
698 <REFMISCINFO>SPI - Plan Storage</REFMISCINFO>
699 </REFMETA>
700 <REFNAMEDIV>
701 <REFNAME>SPI_saveplan
702 </REFNAME>
703 <REFPURPOSE>
704    Saves a passed plan
705 </REFPURPOSE>
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>
708 </REFNAMEDIV>
709 <REFSYNOPSISDIV>
710 <REFSYNOPSISDIVINFO>
711 <DATE>1997-12-24</DATE>
712 </REFSYNOPSISDIVINFO>
713 <SYNOPSIS>
714 SPI_saveplan(<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>)
715 </SYNOPSIS>
716
717 <REFSECT2 ID="R2-SPI-SPISAVEPLAN-1">
718 <REFSECT2INFO>
719 <DATE>1997-12-24</DATE>
720 </REFSECT2INFO>
721 <TITLE>Inputs
722 </TITLE>
723 <VARIABLELIST>
724 <VARLISTENTRY>
725 <TERM>
726 void *<REPLACEABLE CLASS="PARAMETER">query</REPLACEABLE>
727 </TERM>
728 <LISTITEM>
729 <PARA>
730 Passed plan
731 </PARA>
732 </LISTITEM>
733 </VARLISTENTRY>
734 </VARIABLELIST>
735 </REFSECT2>
736
737 <REFSECT2 ID="R2-SPI-SPISAVEPLAN-2">
738 <REFSECT2INFO>
739 <DATE>1997-12-24</DATE>
740 </REFSECT2INFO>
741 <TITLE>Outputs
742 </TITLE>
743 <VARIABLELIST>
744 <VARLISTENTRY>
745 <TERM>void *
746 </TERM>
747 <LISTITEM>
748 <PARA>
749 Execution plan location. NULL if unsuccessful.
750 </PARA>
751 </LISTITEM>
752 </VARLISTENTRY>
753 <VARLISTENTRY>
754 <TERM>SPI_result
755 </TERM>
756 <LISTITEM>
757 <PARA>
758 <SimpleList>
759 <Member>
760    <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if plan is NULL
761 </Member>
762 <Member>
763    <ReturnValue>SPI_ERROR_UNCONNECTED</ReturnValue> if procedure is un-connected
764 </Member>
765 </SimpleList>
766 </PARA>
767 </LISTITEM>
768 </VARLISTENTRY>
769 </VARIABLELIST>
770 </REFSECT2>
771 </REFSYNOPSISDIV>
772
773 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-1">
774 <REFSECT1INFO>
775 <DATE>1997-12-24</DATE>
776 </REFSECT1INFO>
777 <TITLE>Description
778 </TITLE>
779 <PARA>
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.
783 </para>
784 <Para>
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
788    in future versions.
789
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.
793 </PARA>
794 </REFSECT1>
795 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-2">
796 <TITLE>Usage
797 </TITLE>
798 <Para>
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).
804
805 <Note>
806 <Para>
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.
810 </Para>
811 </Note>
812
813 </PARA>
814 </REFSECT1>
815 <!--
816 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-3">
817 <TITLE>Algorithm
818 </TITLE>
819 <PARA><FUNCTION>SPI_saveplan</FUNCTION> performs the following:
820 TBD
821 </PARA>
822 </REFSECT1>
823 -->
824 <!--
825 <REFSECT1 ID="R1-SPI-SPISAVEPLAN-4">
826 <TITLE>Structures
827 </TITLE>
828 <PARA>None
829 </PARA>
830 </REFSECT1>
831 -->
832 </REFENTRY>
833
834 <!-- *********************************************** -->
835 <!-- *********************************************** -->
836 <!-- *********************************************** -->
837
838 <REFENTRY ID="SPI-SPIEXECP">
839 <REFMETA>
840 <REFENTRYTITLE>SPI_execp</REFENTRYTITLE>
841 <REFMISCINFO>SPI - Plan Execution</REFMISCINFO>
842 </REFMETA>
843 <REFNAMEDIV>
844 <REFNAME>SPI_execp
845 </REFNAME>
846 <REFPURPOSE>
847 Executes a plan from <Function>SPI_saveplan</Function>
848 </REFPURPOSE>
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>
851 </REFNAMEDIV>
852 <REFSYNOPSISDIV>
853 <REFSYNOPSISDIVINFO>
854 <DATE>1997-12-24</DATE>
855 </REFSYNOPSISDIVINFO>
856 <SYNOPSIS>
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>)
861 </SYNOPSIS>
862
863 <REFSECT2 ID="R2-SPI-SPIEXECP-1">
864 <REFSECT2INFO>
865 <DATE>1997-12-24</DATE>
866 </REFSECT2INFO>
867 <TITLE>Inputs
868 </TITLE>
869 <VARIABLELIST>
870 <VARLISTENTRY>
871 <TERM>
872 void *<REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
873 </TERM>
874 <LISTITEM>
875 <PARA>
876 Execution plan
877 </PARA>
878 </LISTITEM>
879 </VARLISTENTRY>
880 <VARLISTENTRY>
881 <TERM>
882 Datum *<REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
883 </TERM>
884 <LISTITEM>
885 <PARA>
886 Actual parameter values
887 </PARA>
888 </LISTITEM>
889 </VARLISTENTRY>
890 <VARLISTENTRY>
891 <TERM>
892 char *<REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
893 </TERM>
894 <LISTITEM>
895 <PARA>
896 Array describing what parameters get NULLs
897 <SimpleList>
898 <Member><literal>n</literal> indicates NULL allowed</Member>
899 <Member>A space indicates NULL not allowed</Member>
900 </SimpleList>
901 </PARA>
902 </LISTITEM>
903 </VARLISTENTRY>
904 <VARLISTENTRY>
905 <TERM>
906 int <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE>
907 </TERM>
908 <LISTITEM>
909 <PARA>
910 Number of tuples for which plan is to be executed
911 </PARA>
912 </LISTITEM>
913 </VARLISTENTRY>
914 </VARIABLELIST>
915 </REFSECT2>
916
917 <REFSECT2 ID="R2-SPI-SPIEXECP-2">
918 <REFSECT2INFO>
919 <DATE>1997-12-24</DATE>
920 </REFSECT2INFO>
921 <TITLE>Outputs
922 </TITLE>
923 <VARIABLELIST>
924 <VARLISTENTRY>
925 <TERM>int
926 </TERM>
927 <LISTITEM>
928 <PARA>
929    Returns the same value as <Function>SPI_exec</Function> as well as
930 <SimpleList>
931 <Member>
932  <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue>
933  if <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
934  is NULL or <REPLACEABLE CLASS="PARAMETER">tcount</REPLACEABLE> &lt; 0
935 </Member>
936 <Member>
937    <ReturnValue>SPI_ERROR_PARAM</ReturnValue>
938  if <REPLACEABLE CLASS="PARAMETER">values</REPLACEABLE>
939  is NULL
940  and <REPLACEABLE CLASS="PARAMETER">plan</REPLACEABLE>
941  was prepared with some parameters.
942 </Member>
943 </SimpleList>
944 </para>
945 </LISTITEM>
946 </VARLISTENTRY>
947 <VARLISTENTRY>
948 <TERM>SPI_tuptable
949 </TERM>
950 <LISTITEM>
951 <PARA>
952 initialized as in
953    <Function>SPI_exec</Function> if successful
954 </PARA>
955 </LISTITEM>
956 </VARLISTENTRY>
957 <VARLISTENTRY>
958 <TERM>SPI_processed
959 </TERM>
960 <LISTITEM>
961 <PARA>
962 initialized as in
963    <Function>SPI_exec</Function> if successful
964 </para>
965 </listitem>
966 </VARLISTENTRY>
967 </VARIABLELIST>
968 </REFSECT2>
969 </REFSYNOPSISDIV>
970
971 <REFSECT1 ID="R1-SPI-SPIEXECP-1">
972 <REFSECT1INFO>
973 <DATE>1997-12-24</DATE>
974 </REFSECT1INFO>
975 <TITLE>Description
976 </TITLE>
977 <PARA>
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.
981 </para>
982 <Para>
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
986    in future versions.
987
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.
991 </PARA>
992 </REFSECT1>
993 <REFSECT1 ID="R1-SPI-SPIEXECP-2">
994 <TITLE>Usage
995 </TITLE>
996 <Para>
997    If <REPLACEABLE CLASS="PARAMETER">nulls</REPLACEABLE>
998 is NULL then 
999    <Function>SPI_execp</Function> 
1000 assumes that all values (if any) are NOT NULL.
1001
1002 <Note>
1003 <Para>
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.
1007 </Para>
1008 </Note>
1009
1010 </PARA>
1011 </REFSECT1>
1012 <!--
1013 <REFSECT1 ID="R1-SPI-SPIEXECP-3">
1014 <TITLE>Algorithm
1015 </TITLE>
1016 <PARA><FUNCTION>SPI_execp</FUNCTION> performs the following:
1017 TBD
1018 </PARA>
1019 </REFSECT1>
1020 -->
1021 <!--
1022 <REFSECT1 ID="R1-SPI-SPIEXECP-4">
1023 <TITLE>Structures
1024 </TITLE>
1025 <PARA>None
1026 </PARA>
1027 </REFSECT1>
1028 -->
1029 </REFENTRY>
1030
1031 </Sect1>
1032
1033 <Sect1 id="spi-interface-support">
1034 <Title>Interface Support Functions</Title>
1035
1036 <Para>
1037 All functions described below may be used by connected and unconnected
1038 procedures.
1039 </Para>
1040
1041 <!-- *********************************************** -->
1042 <!-- *********************************************** -->
1043 <!-- *********************************************** -->
1044
1045 <REFENTRY ID="SPI-SPICOPYTUPLE">
1046 <REFMETA>
1047 <REFENTRYTITLE>SPI_copytuple</REFENTRYTITLE>
1048 <REFMISCINFO>SPI - Tuple Copy</REFMISCINFO>
1049 </REFMETA>
1050 <REFNAMEDIV>
1051 <REFNAME>SPI_copytuple
1052 </REFNAME>
1053 <REFPURPOSE>
1054 Makes copy of tuple in upper Executor context
1055 </REFPURPOSE>
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>
1058 </REFNAMEDIV>
1059 <REFSYNOPSISDIV>
1060 <REFSYNOPSISDIVINFO>
1061 <DATE>1997-12-24</DATE>
1062 </REFSYNOPSISDIVINFO>
1063 <SYNOPSIS>
1064 SPI_copytuple(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>)
1065 </SYNOPSIS>
1066
1067 <REFSECT2 ID="R2-SPI-SPICOPYTUPLE-1">
1068 <REFSECT2INFO>
1069 <DATE>1997-12-24</DATE>
1070 </REFSECT2INFO>
1071 <TITLE>Inputs
1072 </TITLE>
1073 <VARIABLELIST>
1074 <VARLISTENTRY>
1075 <TERM>
1076 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1077 </TERM>
1078 <LISTITEM>
1079 <PARA>
1080 Input tuple to be copied
1081 </PARA>
1082 </LISTITEM>
1083 </VARLISTENTRY>
1084 </VARIABLELIST>
1085 </REFSECT2>
1086
1087 <REFSECT2 ID="R2-SPI-SPICOPYTUPLE-2">
1088 <REFSECT2INFO>
1089 <DATE>1997-12-24</DATE>
1090 </REFSECT2INFO>
1091 <TITLE>Outputs
1092 </TITLE>
1093 <VARIABLELIST>
1094 <VARLISTENTRY>
1095 <TERM>
1096 HeapTuple
1097 </TERM>
1098 <LISTITEM>
1099 <PARA>
1100 Copied tuple
1101 <SimpleList>
1102 <Member>
1103  <ReturnValue>non-NULL</ReturnValue>
1104  if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1105  is not NULL and the copy was successful
1106 </Member>
1107 <Member>
1108    <ReturnValue>NULL</ReturnValue>
1109  only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1110  is NULL
1111 </Member>
1112 </SimpleList>
1113 </para>
1114 </LISTITEM>
1115 </VARLISTENTRY>
1116 </VARIABLELIST>
1117 </REFSECT2>
1118 </REFSYNOPSISDIV>
1119
1120 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-1">
1121 <REFSECT1INFO>
1122 <DATE>1997-12-24</DATE>
1123 </REFSECT1INFO>
1124 <TITLE>Description
1125 </TITLE>
1126 <PARA>
1127 <FUNCTION>SPI_copytuple</FUNCTION> 
1128    makes a copy of tuple in upper Executor context. See the section on Memory Management.
1129 </PARA>
1130 </REFSECT1>
1131 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-2">
1132 <TITLE>Usage
1133 </TITLE>
1134 <Para>
1135 TBD
1136 </PARA>
1137 </REFSECT1>
1138 <!--
1139 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-3">
1140 <TITLE>Algorithm
1141 </TITLE>
1142 <PARA>
1143 </PARA>
1144 </REFSECT1>
1145 -->
1146 <!--
1147 <REFSECT1 ID="R1-SPI-SPICOPYTUPLE-4">
1148 <TITLE>Structures
1149 </TITLE>
1150 <PARA>None
1151 </PARA>
1152 </REFSECT1>
1153 -->
1154 </REFENTRY>
1155
1156 <!-- *********************************************** -->
1157 <!-- *********************************************** -->
1158 <!-- *********************************************** -->
1159
1160 <REFENTRY ID="SPI-SPICOPYTUPLEDESC">
1161 <REFMETA>
1162 <REFENTRYTITLE>SPI_copytupledesc</REFENTRYTITLE>
1163 <REFMISCINFO>SPI - Tuple Descriptor Copy</REFMISCINFO>
1164 </REFMETA>
1165 <REFNAMEDIV>
1166 <REFNAME>SPI_copytupledesc
1167 </REFNAME>
1168 <REFPURPOSE>
1169 Makes copy of tuple descriptor in upper Executor context
1170 </REFPURPOSE>
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>
1173 </REFNAMEDIV>
1174 <REFSYNOPSISDIV>
1175 <REFSYNOPSISDIVINFO>
1176 <DATE>2001-08-02</DATE>
1177 </REFSYNOPSISDIVINFO>
1178 <SYNOPSIS>
1179 SPI_copytupledesc(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>)
1180 </SYNOPSIS>
1181
1182 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-1">
1183 <REFSECT2INFO>
1184 <DATE>2001-08-02</DATE>
1185 </REFSECT2INFO>
1186 <TITLE>Inputs
1187 </TITLE>
1188 <VARIABLELIST>
1189 <VARLISTENTRY>
1190 <TERM>
1191 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1192 </TERM>
1193 <LISTITEM>
1194 <PARA>
1195 Input tuple descriptor to be copied
1196 </PARA>
1197 </LISTITEM>
1198 </VARLISTENTRY>
1199 </VARIABLELIST>
1200 </REFSECT2>
1201
1202 <REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-2">
1203 <REFSECT2INFO>
1204 <DATE>2001-08-02</DATE>
1205 </REFSECT2INFO>
1206 <TITLE>Outputs
1207 </TITLE>
1208 <VARIABLELIST>
1209 <VARLISTENTRY>
1210 <TERM>
1211 TupleDesc
1212 </TERM>
1213 <LISTITEM>
1214 <PARA>
1215 Copied tuple descriptor
1216 <SimpleList>
1217 <Member>
1218  <ReturnValue>non-NULL</ReturnValue>
1219  if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1220  is not NULL and the copy was successful
1221 </Member>
1222 <Member>
1223    <ReturnValue>NULL</ReturnValue>
1224  only if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1225  is NULL
1226 </Member>
1227 </SimpleList>
1228 </para>
1229 </LISTITEM>
1230 </VARLISTENTRY>
1231 </VARIABLELIST>
1232 </REFSECT2>
1233 </REFSYNOPSISDIV>
1234
1235 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-1">
1236 <REFSECT1INFO>
1237 <DATE>2001-08-02</DATE>
1238 </REFSECT1INFO>
1239 <TITLE>Description
1240 </TITLE>
1241 <PARA>
1242 <FUNCTION>SPI_copytupledesc</FUNCTION> 
1243    makes a copy of tupdesc in upper Executor context. See the section on Memory Management.
1244 </PARA>
1245 </REFSECT1>
1246 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-2">
1247 <TITLE>Usage
1248 </TITLE>
1249 <Para>
1250 TBD
1251 </PARA>
1252 </REFSECT1>
1253 <!--
1254 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-3">
1255 <TITLE>Algorithm
1256 </TITLE>
1257 <PARA>
1258 </PARA>
1259 </REFSECT1>
1260 -->
1261 <!--
1262 <REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-4">
1263 <TITLE>Structures
1264 </TITLE>
1265 <PARA>None
1266 </PARA>
1267 </REFSECT1>
1268 -->
1269 </REFENTRY>
1270
1271 <!-- *********************************************** -->
1272 <!-- *********************************************** -->
1273 <!-- *********************************************** -->
1274
1275 <REFENTRY ID="SPI-SPIMODIFYTUPLE">
1276 <REFMETA>
1277 <REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
1278 <REFMISCINFO>SPI - Tuple Modify</REFMISCINFO>
1279 </REFMETA>
1280 <REFNAMEDIV>
1281 <REFNAME>SPI_modifytuple
1282 </REFNAME>
1283 <REFPURPOSE>
1284 Modifies tuple of relation
1285 </REFPURPOSE>
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>
1288 </REFNAMEDIV>
1289 <REFSYNOPSISDIV>
1290 <REFSYNOPSISDIVINFO>
1291 <DATE>1997-12-24</DATE>
1292 </REFSYNOPSISDIVINFO>
1293 <SYNOPSIS>
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>)
1296 </SYNOPSIS>
1297
1298 <REFSECT2 ID="R2-SPI-SPIMODIFYTUPLE-1">
1299 <REFSECT2INFO>
1300 <DATE>1997-12-24</DATE>
1301 </REFSECT2INFO>
1302 <TITLE>Inputs
1303 </TITLE>
1304 <VARIABLELIST>
1305 <VARLISTENTRY>
1306 <TERM>
1307 Relation <REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>
1308 </TERM>
1309 <LISTITEM>
1310 <PARA>
1311 </PARA>
1312 </LISTITEM>
1313 </VARLISTENTRY>
1314 <VARLISTENTRY>
1315 <TERM>
1316 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1317 </TERM>
1318 <LISTITEM>
1319 <PARA>
1320 Input tuple to be modified
1321 </PARA>
1322 </LISTITEM>
1323 </VARLISTENTRY>
1324 <VARLISTENTRY>
1325 <TERM>
1326 int <REPLACEABLE CLASS="PARAMETER">nattrs</REPLACEABLE>
1327 </TERM>
1328 <LISTITEM>
1329 <PARA>
1330 Number of attribute numbers in attnum
1331 </PARA>
1332 </LISTITEM>
1333 </VARLISTENTRY>
1334 <VARLISTENTRY>
1335 <TERM>
1336 int * <REPLACEABLE CLASS="PARAMETER">attnum</REPLACEABLE>
1337 </TERM>
1338 <LISTITEM>
1339 <PARA>
1340 Array of numbers of the attributes that are to be changed
1341 </PARA>
1342 </LISTITEM>
1343 </VARLISTENTRY>
1344 <VARLISTENTRY>
1345 <TERM>
1346 Datum * <REPLACEABLE CLASS="PARAMETER">Values</REPLACEABLE>
1347 </TERM>
1348 <LISTITEM>
1349 <PARA>
1350 New values for the attributes specified
1351 </PARA>
1352 </LISTITEM>
1353 </VARLISTENTRY>
1354 <VARLISTENTRY>
1355 <TERM>
1356 char * <REPLACEABLE CLASS="PARAMETER">Nulls</REPLACEABLE>
1357 </TERM>
1358 <LISTITEM>
1359 <PARA>
1360 Which attributes are NULL, if any
1361 </PARA>
1362 </LISTITEM>
1363 </VARLISTENTRY>
1364 </VARIABLELIST>
1365 </REFSECT2>
1366
1367 <REFSECT2 ID="R2-SPI-SPIMODIFYTUPLE-2">
1368 <REFSECT2INFO>
1369 <DATE>1997-12-24</DATE>
1370 </REFSECT2INFO>
1371 <TITLE>Outputs
1372 </TITLE>
1373 <VARIABLELIST>
1374 <VARLISTENTRY>
1375 <TERM>
1376 HeapTuple
1377 </TERM>
1378 <LISTITEM>
1379 <PARA>
1380 New tuple with modifications
1381 <SimpleList>
1382 <Member>
1383  <ReturnValue>non-NULL</ReturnValue>
1384  if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1385  is not NULL and the modify was successful
1386 </Member>
1387 <Member>
1388    <ReturnValue>NULL</ReturnValue>
1389  only if <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1390  is NULL
1391 </Member>
1392 </SimpleList>
1393 </para>
1394 </LISTITEM>
1395 </VARLISTENTRY>
1396 <VARLISTENTRY>
1397 <TERM>
1398 SPI_result
1399 </TERM>
1400 <LISTITEM>
1401 <PARA>
1402 <SimpleList>
1403 <Member>
1404    <ReturnValue>SPI_ERROR_ARGUMENT</ReturnValue> if rel is NULL or tuple is NULL or natts &le; 0 or
1405    attnum is NULL or Values is NULL.
1406 </Member>
1407 <Member>
1408    <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> if there is an invalid 
1409    attribute number in attnum (attnum &le; 0 or &gt; number of
1410    attributes in tuple)
1411 </Member>
1412 </SimpleList>
1413 </para>
1414 </LISTITEM>
1415 </VARLISTENTRY>
1416 </VARIABLELIST>
1417 </REFSECT2>
1418 </REFSYNOPSISDIV>
1419
1420 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-1">
1421 <REFSECT1INFO>
1422 <DATE>1997-12-24</DATE>
1423 </REFSECT1INFO>
1424 <TITLE>Description
1425 </TITLE>
1426 <PARA>
1427 <FUNCTION>SPI_modifytuple</FUNCTION> 
1428 Modifies a tuple in upper Executor context. See the section on Memory Management.
1429 </PARA>
1430 </REFSECT1>
1431 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-2">
1432 <TITLE>Usage
1433 </TITLE>
1434 <Para>
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
1437 is not changed.
1438 </PARA>
1439 </REFSECT1>
1440 <!--
1441 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-3">
1442 <TITLE>Algorithm
1443 </TITLE>
1444 <PARA>
1445 </PARA>
1446 </REFSECT1>
1447 -->
1448 <!--
1449 <REFSECT1 ID="R1-SPI-SPIMODIFYTUPLE-4">
1450 <TITLE>Structures
1451 </TITLE>
1452 <PARA>None
1453 </PARA>
1454 </REFSECT1>
1455 -->
1456 </REFENTRY>
1457
1458 <!-- *********************************************** -->
1459 <!-- *********************************************** -->
1460 <!-- *********************************************** -->
1461
1462 <REFENTRY ID="SPI-SPIFNUMBER">
1463 <REFMETA>
1464 <REFENTRYTITLE>SPI_fnumber</REFENTRYTITLE>
1465 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1466 </REFMETA>
1467 <REFNAMEDIV>
1468 <REFNAME>SPI_fnumber
1469 </REFNAME>
1470 <REFPURPOSE>
1471 Finds the attribute number for specified attribute
1472 </REFPURPOSE>
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>
1475 </REFNAMEDIV>
1476 <REFSYNOPSISDIV>
1477 <REFSYNOPSISDIVINFO>
1478 <DATE>1997-12-24</DATE>
1479 </REFSYNOPSISDIVINFO>
1480 <SYNOPSIS>
1481 SPI_fnumber(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>)
1482 </SYNOPSIS>
1483
1484 <REFSECT2 ID="R2-SPI-SPIFNUMBER-1">
1485 <REFSECT2INFO>
1486 <DATE>1997-12-24</DATE>
1487 </REFSECT2INFO>
1488 <TITLE>Inputs
1489 </TITLE>
1490 <VARIABLELIST>
1491 <VARLISTENTRY>
1492 <TERM>
1493 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1494 </TERM>
1495 <LISTITEM>
1496 <PARA>
1497 Input tuple description
1498 </PARA>
1499 </LISTITEM>
1500 </VARLISTENTRY>
1501 <VARLISTENTRY>
1502 <TERM>
1503 char * <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>
1504 </TERM>
1505 <LISTITEM>
1506 <PARA>
1507 Field name
1508 </PARA>
1509 </LISTITEM>
1510 </VARLISTENTRY>
1511 </VARIABLELIST>
1512 </REFSECT2>
1513
1514 <REFSECT2 ID="R2-SPI-SPIFNUMBER-2">
1515 <REFSECT2INFO>
1516 <DATE>1997-12-24</DATE>
1517 </REFSECT2INFO>
1518 <TITLE>Outputs
1519 </TITLE>
1520 <VARIABLELIST>
1521 <VARLISTENTRY>
1522 <TERM>
1523 int
1524 </TERM>
1525 <LISTITEM>
1526 <PARA>
1527 Attribute number
1528 <SimpleList>
1529 <Member>
1530 Valid one-based index number of attribute
1531 </Member>
1532 <Member>
1533 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> if the named attribute is not found
1534 </Member>
1535 </SimpleList>
1536 </para>
1537 </LISTITEM>
1538 </VARLISTENTRY>
1539 </VARIABLELIST>
1540 </REFSECT2>
1541 </REFSYNOPSISDIV>
1542
1543 <REFSECT1 ID="R1-SPI-SPIFNUMBER-1">
1544 <REFSECT1INFO>
1545 <DATE>1997-12-24</DATE>
1546 </REFSECT1INFO>
1547 <TITLE>Description
1548 </TITLE>
1549 <PARA>
1550 <FUNCTION>SPI_fnumber</FUNCTION> 
1551    returns the attribute number for the attribute with name in fname.
1552 </PARA>
1553 </REFSECT1>
1554 <REFSECT1 ID="R1-SPI-SPIFNUMBER-2">
1555 <TITLE>Usage
1556 </TITLE>
1557 <Para>
1558 Attribute numbers are 1 based.
1559 </PARA>
1560 </REFSECT1>
1561 <!--
1562 <REFSECT1 ID="R1-SPI-SPIFNUMBER-3">
1563 <TITLE>Algorithm
1564 </TITLE>
1565 <PARA>
1566 </PARA>
1567 </REFSECT1>
1568 -->
1569 <!--
1570 <REFSECT1 ID="R1-SPI-SPIFNUMBER-4">
1571 <TITLE>Structures
1572 </TITLE>
1573 <PARA>None
1574 </PARA>
1575 </REFSECT1>
1576 -->
1577 </REFENTRY>
1578
1579 <!-- *********************************************** -->
1580 <!-- *********************************************** -->
1581 <!-- *********************************************** -->
1582
1583 <REFENTRY ID="SPI-SPIFNAME">
1584 <REFMETA>
1585 <REFENTRYTITLE>SPI_fname</REFENTRYTITLE>
1586 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1587 </REFMETA>
1588 <REFNAMEDIV>
1589 <REFNAME>SPI_fname
1590 </REFNAME>
1591 <REFPURPOSE>
1592 Finds the attribute name for the specified attribute
1593 </REFPURPOSE>
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>
1596 </REFNAMEDIV>
1597 <REFSYNOPSISDIV>
1598 <REFSYNOPSISDIVINFO>
1599 <DATE>1997-12-24</DATE>
1600 </REFSYNOPSISDIVINFO>
1601 <SYNOPSIS>
1602 SPI_fname(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fname</REPLACEABLE>)
1603 </SYNOPSIS>
1604
1605 <REFSECT2 ID="R2-SPI-SPIFNAME-1">
1606 <REFSECT2INFO>
1607 <DATE>1997-12-24</DATE>
1608 </REFSECT2INFO>
1609 <TITLE>Inputs
1610 </TITLE>
1611 <VARIABLELIST>
1612 <VARLISTENTRY>
1613 <TERM>
1614 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1615 </TERM>
1616 <LISTITEM>
1617 <PARA>
1618 Input tuple description
1619 </PARA>
1620 </LISTITEM>
1621 </VARLISTENTRY>
1622 <VARLISTENTRY>
1623 <TERM>
1624 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1625 </TERM>
1626 <LISTITEM>
1627 <PARA>
1628 Attribute number
1629 </PARA>
1630 </LISTITEM>
1631 </VARLISTENTRY>
1632 </VARIABLELIST>
1633 </REFSECT2>
1634
1635 <REFSECT2 ID="R2-SPI-SPIFNAME-2">
1636 <REFSECT2INFO>
1637 <DATE>1997-12-24</DATE>
1638 </REFSECT2INFO>
1639 <TITLE>Outputs
1640 </TITLE>
1641 <VARIABLELIST>
1642 <VARLISTENTRY>
1643 <TERM>
1644 char *
1645 </TERM>
1646 <LISTITEM>
1647 <PARA>
1648 Attribute name
1649 <SimpleList>
1650 <Member>
1651 NULL if fnumber is out of range
1652 </Member>
1653 <Member>
1654 SPI_result set to
1655 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue> on error
1656 </Member>
1657 </SimpleList>
1658 </para>
1659 </LISTITEM>
1660 </VARLISTENTRY>
1661 </VARIABLELIST>
1662 </REFSECT2>
1663 </REFSYNOPSISDIV>
1664
1665 <REFSECT1 ID="R1-SPI-SPIFNAME-1">
1666 <REFSECT1INFO>
1667 <DATE>1997-12-24</DATE>
1668 </REFSECT1INFO>
1669 <TITLE>Description
1670 </TITLE>
1671 <PARA>
1672 <FUNCTION>SPI_fname</FUNCTION> 
1673    returns the attribute name for the specified attribute.
1674 </PARA>
1675 </REFSECT1>
1676 <REFSECT1 ID="R1-SPI-SPIFNAME-2">
1677 <TITLE>Usage
1678 </TITLE>
1679 <Para>
1680 Attribute numbers are 1 based.
1681 </PARA>
1682 </REFSECT1>
1683 <REFSECT1 ID="R1-SPI-SPIFNAME-3">
1684 <TITLE>Algorithm
1685 </TITLE>
1686 <PARA>
1687 Returns a newly-allocated copy of the attribute name.
1688 </PARA>
1689 </REFSECT1>
1690 <!--
1691 <REFSECT1 ID="R1-SPI-SPIFNAME-4">
1692 <TITLE>Structures
1693 </TITLE>
1694 <PARA>None
1695 </PARA>
1696 </REFSECT1>
1697 -->
1698 </REFENTRY>
1699
1700 <!-- *********************************************** -->
1701 <!-- *********************************************** -->
1702 <!-- *********************************************** -->
1703
1704 <REFENTRY ID="SPI-SPIGETVALUE">
1705 <REFMETA>
1706 <REFENTRYTITLE>SPI_getvalue</REFENTRYTITLE>
1707 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1708 </REFMETA>
1709 <REFNAMEDIV>
1710 <REFNAME>SPI_getvalue
1711 </REFNAME>
1712 <REFPURPOSE>
1713 Returns the string value of the specified attribute
1714 </REFPURPOSE>
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>
1717 </REFNAMEDIV>
1718 <REFSYNOPSISDIV>
1719 <REFSYNOPSISDIVINFO>
1720 <DATE>1997-12-24</DATE>
1721 </REFSYNOPSISDIVINFO>
1722 <SYNOPSIS>
1723 SPI_getvalue(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
1724 </SYNOPSIS>
1725
1726 <REFSECT2 ID="R2-SPI-SPIGETVALUE-1">
1727 <REFSECT2INFO>
1728 <DATE>1997-12-24</DATE>
1729 </REFSECT2INFO>
1730 <TITLE>Inputs
1731 </TITLE>
1732 <VARIABLELIST>
1733 <VARLISTENTRY>
1734 <TERM>
1735 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1736 </TERM>
1737 <LISTITEM>
1738 <PARA>
1739 Input tuple to be examined
1740 </PARA>
1741 </LISTITEM>
1742 </VARLISTENTRY>
1743 <VARLISTENTRY>
1744 <TERM>
1745 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1746 </TERM>
1747 <LISTITEM>
1748 <PARA>
1749 Input tuple description
1750 </PARA>
1751 </LISTITEM>
1752 </VARLISTENTRY>
1753 <VARLISTENTRY>
1754 <TERM>
1755 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1756 </TERM>
1757 <LISTITEM>
1758 <PARA>
1759 Attribute number
1760 </PARA>
1761 </LISTITEM>
1762 </VARLISTENTRY>
1763 </VARIABLELIST>
1764 </REFSECT2>
1765
1766 <REFSECT2 ID="R2-SPI-SPIGETVALUE-2">
1767 <REFSECT2INFO>
1768 <DATE>1997-12-24</DATE>
1769 </REFSECT2INFO>
1770 <TITLE>Outputs
1771 </TITLE>
1772 <VARIABLELIST>
1773 <VARLISTENTRY>
1774 <TERM>
1775 char *
1776 </TERM>
1777 <LISTITEM>
1778 <PARA>
1779 Attribute value or NULL if
1780 <SimpleList>
1781 <Member>
1782 attribute is NULL
1783 </Member>
1784 <Member>
1785 fnumber is out of range
1786 (SPI_result set to
1787 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>)
1788 </Member>
1789 <Member>
1790 no output function available
1791 (SPI_result set to
1792 <ReturnValue>SPI_ERROR_NOOUTFUNC</ReturnValue>)
1793 </Member>
1794 </SimpleList>
1795 </para>
1796 </LISTITEM>
1797 </VARLISTENTRY>
1798 </VARIABLELIST>
1799 </REFSECT2>
1800 </REFSYNOPSISDIV>
1801
1802 <REFSECT1 ID="R1-SPI-SPIGETVALUE-1">
1803 <REFSECT1INFO>
1804 <DATE>1997-12-24</DATE>
1805 </REFSECT1INFO>
1806 <TITLE>Description
1807 </TITLE>
1808 <PARA>
1809 <FUNCTION>SPI_getvalue</FUNCTION> 
1810    returns an external (string) representation of the value of the specified attribute.
1811 </PARA>
1812 </REFSECT1>
1813 <REFSECT1 ID="R1-SPI-SPIGETVALUE-2">
1814 <TITLE>Usage
1815 </TITLE>
1816 <Para>
1817 Attribute numbers are 1 based.
1818 </PARA>
1819 </REFSECT1>
1820 <REFSECT1 ID="R1-SPI-SPIGETVALUE-3">
1821 <TITLE>Algorithm
1822 </TITLE>
1823 <PARA>
1824 Allocates memory as required by the value.
1825 </PARA>
1826 </REFSECT1>
1827 <!--
1828 <REFSECT1 ID="R1-SPI-SPIGETVALUE-4">
1829 <TITLE>Structures
1830 </TITLE>
1831 <PARA>None
1832 </PARA>
1833 </REFSECT1>
1834 -->
1835 </REFENTRY>
1836
1837 <!-- *********************************************** -->
1838 <!-- *********************************************** -->
1839 <!-- *********************************************** -->
1840
1841 <REFENTRY ID="SPI-SPIGETBINVAL">
1842 <REFMETA>
1843 <REFENTRYTITLE>SPI_getbinval</REFENTRYTITLE>
1844 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1845 </REFMETA>
1846 <REFNAMEDIV>
1847 <REFNAME>SPI_getbinval
1848 </REFNAME>
1849 <REFPURPOSE>
1850 Returns the binary value of the specified attribute
1851 </REFPURPOSE>
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>
1854 </REFNAMEDIV>
1855 <REFSYNOPSISDIV>
1856 <REFSYNOPSISDIVINFO>
1857 <DATE>1997-12-24</DATE>
1858 </REFSYNOPSISDIVINFO>
1859 <SYNOPSIS>
1860 SPI_getbinval(<REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">isnull</REPLACEABLE>)
1861 </SYNOPSIS>
1862
1863 <REFSECT2 ID="R2-SPI-SPIGETBINVAL-1">
1864 <REFSECT2INFO>
1865 <DATE>1997-12-24</DATE>
1866 </REFSECT2INFO>
1867 <TITLE>Inputs
1868 </TITLE>
1869 <VARIABLELIST>
1870 <VARLISTENTRY>
1871 <TERM>
1872 HeapTuple <REPLACEABLE CLASS="PARAMETER">tuple</REPLACEABLE>
1873 </TERM>
1874 <LISTITEM>
1875 <PARA>
1876 Input tuple to be examined
1877 </PARA>
1878 </LISTITEM>
1879 </VARLISTENTRY>
1880 <VARLISTENTRY>
1881 <TERM>
1882 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
1883 </TERM>
1884 <LISTITEM>
1885 <PARA>
1886 Input tuple description
1887 </PARA>
1888 </LISTITEM>
1889 </VARLISTENTRY>
1890 <VARLISTENTRY>
1891 <TERM>
1892 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
1893 </TERM>
1894 <LISTITEM>
1895 <PARA>
1896 Attribute number
1897 </PARA>
1898 </LISTITEM>
1899 </VARLISTENTRY>
1900 </VARIABLELIST>
1901 </REFSECT2>
1902
1903 <REFSECT2 ID="R2-SPI-SPIGETBINVAL-2">
1904 <REFSECT2INFO>
1905 <DATE>1997-12-24</DATE>
1906 </REFSECT2INFO>
1907 <TITLE>Outputs
1908 </TITLE>
1909 <VARIABLELIST>
1910 <VARLISTENTRY>
1911 <TERM>
1912 Datum
1913 </TERM>
1914 <LISTITEM>
1915 <PARA>
1916 Attribute binary value
1917 </PARA>
1918 </LISTITEM>
1919 </VARLISTENTRY>
1920 <VARLISTENTRY>
1921 <TERM>
1922 bool * <REPLACEABLE CLASS="PARAMETER">isnull</REPLACEABLE>
1923 </TERM>
1924 <LISTITEM>
1925 <PARA>
1926 flag for null value in attribute
1927 </PARA>
1928 </LISTITEM>
1929 </VARLISTENTRY>
1930 <VARLISTENTRY>
1931 <TERM>
1932 SPI_result
1933 </TERM>
1934 <LISTITEM>
1935 <PARA>
1936 <SimpleList>
1937 <Member>
1938 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
1939 </Member>
1940 </SimpleList>
1941 </PARA>
1942 </LISTITEM>
1943 </VARLISTENTRY>
1944 </VARIABLELIST>
1945 </REFSECT2>
1946 </REFSYNOPSISDIV>
1947
1948 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-1">
1949 <REFSECT1INFO>
1950 <DATE>1997-12-24</DATE>
1951 </REFSECT1INFO>
1952 <TITLE>Description
1953 </TITLE>
1954 <PARA>
1955 <FUNCTION>SPI_getbinval</FUNCTION> 
1956    returns the binary value of the specified attribute.
1957 </PARA>
1958 </REFSECT1>
1959 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-2">
1960 <TITLE>Usage
1961 </TITLE>
1962 <Para>
1963 Attribute numbers are 1 based.
1964 </PARA>
1965 </REFSECT1>
1966 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-3">
1967 <TITLE>Algorithm
1968 </TITLE>
1969 <PARA>
1970 Does not allocate new space for the binary value.
1971 </PARA>
1972 </REFSECT1>
1973 <!--
1974 <REFSECT1 ID="R1-SPI-SPIGETBINVAL-4">
1975 <TITLE>Structures
1976 </TITLE>
1977 <PARA>None
1978 </PARA>
1979 </REFSECT1>
1980 -->
1981 </REFENTRY>
1982
1983 <!-- *********************************************** -->
1984 <!-- *********************************************** -->
1985 <!-- *********************************************** -->
1986
1987 <REFENTRY ID="SPI-SPIGETTYPE">
1988 <REFMETA>
1989 <REFENTRYTITLE>SPI_gettype</REFENTRYTITLE>
1990 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
1991 </REFMETA>
1992 <REFNAMEDIV>
1993 <REFNAME>SPI_gettype
1994 </REFNAME>
1995 <REFPURPOSE>
1996 Returns the type name of the specified attribute
1997 </REFPURPOSE>
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>
2000 </REFNAMEDIV>
2001 <REFSYNOPSISDIV>
2002 <REFSYNOPSISDIVINFO>
2003 <DATE>1997-12-24</DATE>
2004 </REFSYNOPSISDIVINFO>
2005 <SYNOPSIS>
2006 SPI_gettype(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
2007 </SYNOPSIS>
2008
2009 <REFSECT2 ID="R2-SPI-SPIGETTYPE-1">
2010 <REFSECT2INFO>
2011 <DATE>1997-12-24</DATE>
2012 </REFSECT2INFO>
2013 <TITLE>Inputs
2014 </TITLE>
2015 <VARIABLELIST>
2016 <VARLISTENTRY>
2017 <TERM>
2018 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2019 </TERM>
2020 <LISTITEM>
2021 <PARA>
2022 Input tuple description
2023 </PARA>
2024 </LISTITEM>
2025 </VARLISTENTRY>
2026 <VARLISTENTRY>
2027 <TERM>
2028 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2029 </TERM>
2030 <LISTITEM>
2031 <PARA>
2032 Attribute number
2033 </PARA>
2034 </LISTITEM>
2035 </VARLISTENTRY>
2036 </VARIABLELIST>
2037 </REFSECT2>
2038
2039 <REFSECT2 ID="R2-SPI-SPIGETTYPE-2">
2040 <REFSECT2INFO>
2041 <DATE>1997-12-24</DATE>
2042 </REFSECT2INFO>
2043 <TITLE>Outputs
2044 </TITLE>
2045 <VARIABLELIST>
2046 <VARLISTENTRY>
2047 <TERM>
2048 char *
2049 </TERM>
2050 <LISTITEM>
2051 <PARA>
2052 The type name for the specified attribute number
2053 </PARA>
2054 </LISTITEM>
2055 </VARLISTENTRY>
2056 <VARLISTENTRY>
2057 <TERM>
2058 SPI_result
2059 </TERM>
2060 <LISTITEM>
2061 <PARA>
2062 <SimpleList>
2063 <Member>
2064 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2065 </Member>
2066 </SimpleList>
2067 </PARA>
2068 </LISTITEM>
2069 </VARLISTENTRY>
2070 </VARIABLELIST>
2071 </REFSECT2>
2072 </REFSYNOPSISDIV>
2073
2074 <REFSECT1 ID="R1-SPI-SPIGETTYPE-1">
2075 <REFSECT1INFO>
2076 <DATE>1997-12-24</DATE>
2077 </REFSECT1INFO>
2078 <TITLE>Description
2079 </TITLE>
2080 <PARA>
2081 <FUNCTION>SPI_gettype</FUNCTION> 
2082    returns a copy of the type name for the specified attribute.
2083 </PARA>
2084 </REFSECT1>
2085 <REFSECT1 ID="R1-SPI-SPIGETTYPE-2">
2086 <TITLE>Usage
2087 </TITLE>
2088 <Para>
2089 Attribute numbers are 1 based.
2090 </PARA>
2091 </REFSECT1>
2092 <REFSECT1 ID="R1-SPI-SPIGETTYPE-3">
2093 <TITLE>Algorithm
2094 </TITLE>
2095 <PARA>
2096 Does not allocate new space for the binary value.
2097 </PARA>
2098 </REFSECT1>
2099 <!--
2100 <REFSECT1 ID="R1-SPI-SPIGETTYPE-4">
2101 <TITLE>Structures
2102 </TITLE>
2103 <PARA>None
2104 </PARA>
2105 </REFSECT1>
2106 -->
2107 </REFENTRY>
2108
2109 <!-- *********************************************** -->
2110 <!-- *********************************************** -->
2111 <!-- *********************************************** -->
2112
2113 <REFENTRY ID="SPI-SPIGETTYPEID">
2114 <REFMETA>
2115 <REFENTRYTITLE>SPI_gettypeid</REFENTRYTITLE>
2116 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2117 </REFMETA>
2118 <REFNAMEDIV>
2119 <REFNAME>SPI_gettypeid
2120 </REFNAME>
2121 <REFPURPOSE>
2122 Returns the type <Acronym>OID</Acronym> of the specified attribute
2123 </REFPURPOSE>
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>
2126 </REFNAMEDIV>
2127 <REFSYNOPSISDIV>
2128 <REFSYNOPSISDIVINFO>
2129 <DATE>1997-12-24</DATE>
2130 </REFSYNOPSISDIVINFO>
2131 <SYNOPSIS>
2132 SPI_gettypeid(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>)
2133 </SYNOPSIS>
2134
2135 <REFSECT2 ID="R2-SPI-SPIGETTYPEID-1">
2136 <REFSECT2INFO>
2137 <DATE>1997-12-24</DATE>
2138 </REFSECT2INFO>
2139 <TITLE>Inputs
2140 </TITLE>
2141 <VARIABLELIST>
2142 <VARLISTENTRY>
2143 <TERM>
2144 TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
2145 </TERM>
2146 <LISTITEM>
2147 <PARA>
2148 Input tuple description
2149 </PARA>
2150 </LISTITEM>
2151 </VARLISTENTRY>
2152 <VARLISTENTRY>
2153 <TERM>
2154 int <REPLACEABLE CLASS="PARAMETER">fnumber</REPLACEABLE>
2155 </TERM>
2156 <LISTITEM>
2157 <PARA>
2158 Attribute number
2159 </PARA>
2160 </LISTITEM>
2161 </VARLISTENTRY>
2162 </VARIABLELIST>
2163 </REFSECT2>
2164
2165 <REFSECT2 ID="R2-SPI-SPIGETTYPEID-2">
2166 <REFSECT2INFO>
2167 <DATE>1997-12-24</DATE>
2168 </REFSECT2INFO>
2169 <TITLE>Outputs
2170 </TITLE>
2171 <VARIABLELIST>
2172 <VARLISTENTRY>
2173 <TERM>
2174 <Acronym>OID</Acronym>
2175 </TERM>
2176 <LISTITEM>
2177 <PARA>
2178 The type <Acronym>OID</Acronym> for the specified attribute number
2179 </PARA>
2180 </LISTITEM>
2181 </VARLISTENTRY>
2182 <VARLISTENTRY>
2183 <TERM>
2184 SPI_result
2185 </TERM>
2186 <LISTITEM>
2187 <PARA>
2188 <SimpleList>
2189 <Member>
2190 <ReturnValue>SPI_ERROR_NOATTRIBUTE</ReturnValue>
2191 </Member>
2192 </SimpleList>
2193 </PARA>
2194 </LISTITEM>
2195 </VARLISTENTRY>
2196 </VARIABLELIST>
2197 </REFSECT2>
2198 </REFSYNOPSISDIV>
2199
2200 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-1">
2201 <REFSECT1INFO>
2202 <DATE>1997-12-24</DATE>
2203 </REFSECT1INFO>
2204 <TITLE>Description
2205 </TITLE>
2206 <PARA>
2207 <FUNCTION>SPI_gettypeid</FUNCTION> 
2208    returns the type <Acronym>OID</Acronym> for the specified attribute.
2209 </PARA>
2210 </REFSECT1>
2211 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-2">
2212 <TITLE>Usage
2213 </TITLE>
2214 <Para>
2215 Attribute numbers are 1 based.
2216 </PARA>
2217 </REFSECT1>
2218 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-3">
2219 <TITLE>Algorithm
2220 </TITLE>
2221 <PARA>
2222 TBD
2223 </PARA>
2224 </REFSECT1>
2225 <!--
2226 <REFSECT1 ID="R1-SPI-SPIGETTYPEID-4">
2227 <TITLE>Structures
2228 </TITLE>
2229 <PARA>None
2230 </PARA>
2231 </REFSECT1>
2232 -->
2233 </REFENTRY>
2234
2235 <!-- *********************************************** -->
2236 <!-- *********************************************** -->
2237 <!-- *********************************************** -->
2238
2239 <REFENTRY ID="SPI-SPIGETRELNAME">
2240 <REFMETA>
2241 <REFENTRYTITLE>SPI_getrelname</REFENTRYTITLE>
2242 <REFMISCINFO>SPI - Tuple Information</REFMISCINFO>
2243 </REFMETA>
2244 <REFNAMEDIV>
2245 <REFNAME>SPI_getrelname
2246 </REFNAME>
2247 <REFPURPOSE>
2248 Returns the name of the specified relation
2249 </REFPURPOSE>
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>
2252 </REFNAMEDIV>
2253 <REFSYNOPSISDIV>
2254 <REFSYNOPSISDIVINFO>
2255 <DATE>1997-12-24</DATE>
2256 </REFSYNOPSISDIVINFO>
2257 <SYNOPSIS>
2258 SPI_getrelname(<REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>)
2259 </SYNOPSIS>
2260
2261 <REFSECT2 ID="R2-SPI-SPIGETRELNAME-1">
2262 <REFSECT2INFO>
2263 <DATE>1997-12-24</DATE>
2264 </REFSECT2INFO>
2265 <TITLE>Inputs
2266 </TITLE>
2267 <VARIABLELIST>
2268 <VARLISTENTRY>
2269 <TERM>
2270 Relation <REPLACEABLE CLASS="PARAMETER">rel</REPLACEABLE>
2271 </TERM>
2272 <LISTITEM>
2273 <PARA>
2274 Input relation
2275 </PARA>
2276 </LISTITEM>
2277 </VARLISTENTRY>
2278 </VARIABLELIST>
2279 </REFSECT2>
2280
2281 <REFSECT2 ID="R2-SPI-SPIGETRELNAME-2">
2282 <REFSECT2INFO>
2283 <DATE>1997-12-24</DATE>
2284 </REFSECT2INFO>
2285 <TITLE>Outputs
2286 </TITLE>
2287 <VARIABLELIST>
2288 <VARLISTENTRY>
2289 <TERM>
2290 char *
2291 </TERM>
2292 <LISTITEM>
2293 <PARA>
2294 The name of the specified relation
2295 </PARA>
2296 </LISTITEM>
2297 </VARLISTENTRY>
2298 </VARIABLELIST>
2299 </REFSECT2>
2300 </REFSYNOPSISDIV>
2301
2302 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-1">
2303 <REFSECT1INFO>
2304 <DATE>1997-12-24</DATE>
2305 </REFSECT1INFO>
2306 <TITLE>Description
2307 </TITLE>
2308 <PARA>
2309 <FUNCTION>SPI_getrelname</FUNCTION> 
2310    returns the name of the specified relation.
2311 </PARA>
2312 </REFSECT1>
2313 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-2">
2314 <TITLE>Usage
2315 </TITLE>
2316 <Para>
2317 TBD
2318 </PARA>
2319 </REFSECT1>
2320 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-3">
2321 <TITLE>Algorithm
2322 </TITLE>
2323 <PARA>
2324 Copies the relation name into new storage.
2325 </PARA>
2326 </REFSECT1>
2327 <!--
2328 <REFSECT1 ID="R1-SPI-SPIGETRELNAME-4">
2329 <TITLE>Structures
2330 </TITLE>
2331 <PARA>None
2332 </PARA>
2333 </REFSECT1>
2334 -->
2335 </REFENTRY>
2336
2337 <!-- *********************************************** -->
2338 <!-- *********************************************** -->
2339 <!-- *********************************************** -->
2340
2341 <REFENTRY ID="SPI-SPIPALLOC">
2342 <REFMETA>
2343 <REFENTRYTITLE>SPI_palloc</REFENTRYTITLE>
2344 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
2345 </REFMETA>
2346 <REFNAMEDIV>
2347 <REFNAME>SPI_palloc
2348 </REFNAME>
2349 <REFPURPOSE>
2350 Allocates memory in upper Executor context
2351 </REFPURPOSE>
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>
2354 </REFNAMEDIV>
2355 <REFSYNOPSISDIV>
2356 <REFSYNOPSISDIVINFO>
2357 <DATE>1997-12-24</DATE>
2358 </REFSYNOPSISDIVINFO>
2359 <SYNOPSIS>
2360 SPI_palloc(<REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)
2361 </SYNOPSIS>
2362
2363 <REFSECT2 ID="R2-SPI-SPIPALLOC-1">
2364 <REFSECT2INFO>
2365 <DATE>1997-12-24</DATE>
2366 </REFSECT2INFO>
2367 <TITLE>Inputs
2368 </TITLE>
2369 <VARIABLELIST>
2370 <VARLISTENTRY>
2371 <TERM>
2372 Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>
2373 </TERM>
2374 <LISTITEM>
2375 <PARA>
2376 Octet size of storage to allocate
2377 </PARA>
2378 </LISTITEM>
2379 </VARLISTENTRY>
2380 </VARIABLELIST>
2381 </REFSECT2>
2382
2383 <REFSECT2 ID="R2-SPI-SPIPALLOC-2">
2384 <REFSECT2INFO>
2385 <DATE>1997-12-24</DATE>
2386 </REFSECT2INFO>
2387 <TITLE>Outputs
2388 </TITLE>
2389 <VARIABLELIST>
2390 <VARLISTENTRY>
2391 <TERM>
2392 void *
2393 </TERM>
2394 <LISTITEM>
2395 <PARA>
2396 New storage space of specified size
2397 </PARA>
2398 </LISTITEM>
2399 </VARLISTENTRY>
2400 </VARIABLELIST>
2401 </REFSECT2>
2402 </REFSYNOPSISDIV>
2403
2404 <REFSECT1 ID="R1-SPI-SPIPALLOC-1">
2405 <REFSECT1INFO>
2406 <DATE>1997-12-24</DATE>
2407 </REFSECT1INFO>
2408 <TITLE>Description
2409 </TITLE>
2410 <PARA>
2411 <FUNCTION>SPI_palloc</FUNCTION> 
2412    allocates memory in upper Executor context. See section on memory management.
2413 </PARA>
2414 </REFSECT1>
2415 <REFSECT1 ID="R1-SPI-SPIPALLOC-2">
2416 <TITLE>Usage
2417 </TITLE>
2418 <Para>
2419 TBD
2420 </PARA>
2421 </REFSECT1>
2422 <!--
2423 <REFSECT1 ID="R1-SPI-SPIPALLOC-3">
2424 <TITLE>Algorithm
2425 </TITLE>
2426 <PARA>
2427 TBD
2428 </PARA>
2429 </REFSECT1>
2430 -->
2431 <!--
2432 <REFSECT1 ID="R1-SPI-SPIPALLOC-4">
2433 <TITLE>Structures
2434 </TITLE>
2435 <PARA>None
2436 </PARA>
2437 </REFSECT1>
2438 -->
2439 </REFENTRY>
2440
2441 <!-- *********************************************** -->
2442 <!-- *********************************************** -->
2443 <!-- *********************************************** -->
2444
2445 <REFENTRY ID="SPI-SPIREPALLOC">
2446 <REFMETA>
2447 <REFENTRYTITLE>SPI_repalloc</REFENTRYTITLE>
2448 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
2449 </REFMETA>
2450 <REFNAMEDIV>
2451 <REFNAME>SPI_repalloc
2452 </REFNAME>
2453 <REFPURPOSE>
2454 Re-allocates memory in upper Executor context
2455 </REFPURPOSE>
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>
2458 </REFNAMEDIV>
2459 <REFSYNOPSISDIV>
2460 <REFSYNOPSISDIVINFO>
2461 <DATE>1997-12-24</DATE>
2462 </REFSYNOPSISDIVINFO>
2463 <SYNOPSIS>
2464 SPI_repalloc(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>, <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>)
2465 </SYNOPSIS>
2466
2467 <REFSECT2 ID="R2-SPI-SPIREPALLOC-1">
2468 <REFSECT2INFO>
2469 <DATE>1997-12-24</DATE>
2470 </REFSECT2INFO>
2471 <TITLE>Inputs
2472 </TITLE>
2473 <VARIABLELIST>
2474 <VARLISTENTRY>
2475 <TERM>
2476 void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
2477 </TERM>
2478 <LISTITEM>
2479 <PARA>
2480 Pointer to existing storage
2481 </PARA>
2482 </LISTITEM>
2483 </VARLISTENTRY>
2484 <VARLISTENTRY>
2485 <TERM>
2486 Size <REPLACEABLE CLASS="PARAMETER">size</REPLACEABLE>
2487 </TERM>
2488 <LISTITEM>
2489 <PARA>
2490 Octet size of storage to allocate
2491 </PARA>
2492 </LISTITEM>
2493 </VARLISTENTRY>
2494 </VARIABLELIST>
2495 </REFSECT2>
2496
2497 <REFSECT2 ID="R2-SPI-SPIREPALLOC-2">
2498 <REFSECT2INFO>
2499 <DATE>1997-12-24</DATE>
2500 </REFSECT2INFO>
2501 <TITLE>Outputs
2502 </TITLE>
2503 <VARIABLELIST>
2504 <VARLISTENTRY>
2505 <TERM>
2506 void *
2507 </TERM>
2508 <LISTITEM>
2509 <PARA>
2510 New storage space of specified size with contents copied from existing area
2511 </PARA>
2512 </LISTITEM>
2513 </VARLISTENTRY>
2514 </VARIABLELIST>
2515 </REFSECT2>
2516 </REFSYNOPSISDIV>
2517
2518 <REFSECT1 ID="R1-SPI-SPIREPALLOC-1">
2519 <REFSECT1INFO>
2520 <DATE>1997-12-24</DATE>
2521 </REFSECT1INFO>
2522 <TITLE>Description
2523 </TITLE>
2524 <PARA>
2525 <FUNCTION>SPI_repalloc</FUNCTION> 
2526    re-allocates memory in upper Executor context. See section on memory management.
2527 </PARA>
2528 </REFSECT1>
2529 <REFSECT1 ID="R1-SPI-SPIREPALLOC-2">
2530 <TITLE>Usage
2531 </TITLE>
2532 <Para>
2533 TBD
2534 </PARA>
2535 </REFSECT1>
2536 <!--
2537 <REFSECT1 ID="R1-SPI-SPIREPALLOC-3">
2538 <TITLE>Algorithm
2539 </TITLE>
2540 <PARA>
2541 TBD
2542 </PARA>
2543 </REFSECT1>
2544 -->
2545 <!--
2546 <REFSECT1 ID="R1-SPI-SPIREPALLOC-4">
2547 <TITLE>Structures
2548 </TITLE>
2549 <PARA>None
2550 </PARA>
2551 </REFSECT1>
2552 -->
2553 </REFENTRY>
2554
2555 <!-- *********************************************** -->
2556 <!-- *********************************************** -->
2557 <!-- *********************************************** -->
2558
2559 <REFENTRY ID="SPI-SPIPFREE">
2560 <REFMETA>
2561 <REFENTRYTITLE>SPI_pfree</REFENTRYTITLE>
2562 <REFMISCINFO>SPI - Memory Management</REFMISCINFO>
2563 </REFMETA>
2564 <REFNAMEDIV>
2565 <REFNAME>SPI_pfree
2566 </REFNAME>
2567 <REFPURPOSE>
2568 Frees memory from upper Executor context
2569 </REFPURPOSE>
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>
2572 </REFNAMEDIV>
2573 <REFSYNOPSISDIV>
2574 <REFSYNOPSISDIVINFO>
2575 <DATE>1997-12-24</DATE>
2576 </REFSYNOPSISDIVINFO>
2577 <SYNOPSIS>
2578 SPI_pfree(<REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>)
2579 </SYNOPSIS>
2580
2581 <REFSECT2 ID="R2-SPI-SPIPFREE-1">
2582 <REFSECT2INFO>
2583 <DATE>1997-12-24</DATE>
2584 </REFSECT2INFO>
2585 <TITLE>Inputs
2586 </TITLE>
2587 <VARIABLELIST>
2588 <VARLISTENTRY>
2589 <TERM>
2590 void * <REPLACEABLE CLASS="PARAMETER">pointer</REPLACEABLE>
2591 </TERM>
2592 <LISTITEM>
2593 <PARA>
2594 Pointer to existing storage
2595 </PARA>
2596 </LISTITEM>
2597 </VARLISTENTRY>
2598 </VARIABLELIST>
2599 </REFSECT2>
2600
2601 <REFSECT2 ID="R2-SPI-SPIPFREE-2">
2602 <REFSECT2INFO>
2603 <DATE>1997-12-24</DATE>
2604 </REFSECT2INFO>
2605 <TITLE>Outputs
2606 </TITLE>
2607 <VARIABLELIST>
2608 <VARLISTENTRY>
2609 <TERM>
2610 None
2611 </TERM>
2612 <LISTITEM>
2613 <PARA>
2614 </PARA>
2615 </LISTITEM>
2616 </VARLISTENTRY>
2617 </VARIABLELIST>
2618 </REFSECT2>
2619 </REFSYNOPSISDIV>
2620
2621 <REFSECT1 ID="R1-SPI-SPIPFREE-1">
2622 <REFSECT1INFO>
2623 <DATE>1997-12-24</DATE>
2624 </REFSECT1INFO>
2625 <TITLE>Description
2626 </TITLE>
2627 <PARA>
2628 <FUNCTION>SPI_pfree</FUNCTION> 
2629    frees memory in upper Executor context. See section on memory management.
2630 </PARA>
2631 </REFSECT1>
2632 <REFSECT1 ID="R1-SPI-SPIPFREE-2">
2633 <TITLE>Usage
2634 </TITLE>
2635 <Para>
2636 TBD
2637 </PARA>
2638 </REFSECT1>
2639 <!--
2640 <REFSECT1 ID="R1-SPI-SPIPFREE-3">
2641 <TITLE>Algorithm
2642 </TITLE>
2643 <PARA>
2644 TBD
2645 </PARA>
2646 </REFSECT1>
2647 -->
2648 <!--
2649 <REFSECT1 ID="R1-SPI-SPIPFREE-4">
2650 <TITLE>Structures
2651 </TITLE>
2652 <PARA>None
2653 </PARA>
2654 </REFSECT1>
2655 -->
2656 </REFENTRY>
2657
2658 </Sect1>
2659
2660 <Sect1 id="spi-memory">
2661 <Title>Memory Management</Title>
2662
2663 <Para>
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.
2670 </Para>
2671
2672 <Para>
2673    Creation and switching between memory contexts are subject of SPI manager
2674 memory management.
2675 </Para>
2676
2677 <Para>
2678
2679    SPI procedures deal with two memory contexts: upper Executor memory
2680 context and procedure memory context (if connected). 
2681 </Para>
2682
2683 <Para>
2684
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.
2689 </Para>
2690
2691 <Para>
2692
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.
2701 </Para>
2702
2703 <Para>
2704
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!
2708 </Para>
2709
2710 <Para>
2711
2712    If you want to return something to the upper Executor then you have to
2713 allocate memory for this in the upper context!
2714 </Para>
2715
2716 <Para>
2717
2718    SPI has no ability to automatically free allocations in the upper Executor
2719 context!
2720 </Para>
2721
2722 <Para>
2723
2724    SPI automatically frees memory allocated during execution of a query when
2725 this query is done!
2726 </Para>
2727
2728 </Sect1>
2729
2730 <Sect1 id="spi-visibility">
2731 <Title>Visibility of Data Changes</Title>
2732
2733 <Para>
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
2737
2738    INSERT INTO a SELECT * FROM a
2739
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.
2743 </Para>
2744
2745 <Para>
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.
2749 </Para>
2750 </Sect1>
2751
2752 <Sect1 id="spi-examples">
2753 <Title>Examples</Title>
2754
2755 <Para>
2756    This example of SPI usage demonstrates the visibility rule.
2757    There are more complex examples in src/test/regress/regress.c and
2758 in contrib/spi.
2759 </Para>
2760
2761 <Para>
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
2765 executed:
2766
2767 <ProgramListing>
2768 #include "executor/spi.h"   /* this is what you need to work with SPI */
2769
2770 int execq(text *sql, int cnt);
2771
2772 int
2773 execq(text *sql, int cnt)
2774 {
2775     char *query;
2776     int ret;
2777     int proc;
2778
2779     /* Convert given TEXT object to a C string */
2780     query = DatumGetCString(DirectFunctionCall1(textout,
2781                                                 PointerGetDatum(sql)));
2782
2783     SPI_connect();
2784     
2785     ret = SPI_exec(query, cnt);
2786     
2787     proc = SPI_processed;
2788     /*
2789      * If this is SELECT and some tuple(s) fetched -
2790      * returns tuples to the caller via elog (NOTICE).
2791      */
2792     if ( ret == SPI_OK_SELECT && SPI_processed > 0 )
2793     {
2794         TupleDesc tupdesc = SPI_tuptable->tupdesc;
2795         SPITupleTable *tuptable = SPI_tuptable;
2796         char buf[8192];
2797         int i,j;
2798         
2799         for (j = 0; j < proc; j++)
2800         {
2801             HeapTuple tuple = tuptable->vals[j];
2802             
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);
2808         }
2809     }
2810
2811     SPI_finish();
2812
2813     pfree(query);
2814
2815     return (proc);
2816 }
2817 </ProgramListing>
2818 </Para>
2819
2820 <Para>
2821    Now, compile and create the function:
2822
2823 <ProgramListing>
2824 CREATE FUNCTION execq (TEXT, INT4) RETURNS INT4 AS '...path_to_so' LANGUAGE 'c';
2825 </ProgramListing>
2826
2827 <ProgramListing>
2828 vac=> SELECT execq('CREATE TABLE a (x INT4)', 0);
2829 execq
2830 -----
2831     0
2832 (1 row)
2833
2834 vac=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)',0));
2835 INSERT 167631 1
2836 vac=> select execq('SELECT * FROM a',0);
2837 NOTICE:EXECQ:  0 <<< inserted by execq
2838
2839 NOTICE:EXECQ:  1 <<< value returned by execq and inserted by upper INSERT
2840
2841 execq
2842 -----
2843     2
2844 (1 row)
2845
2846 vac=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a',1);
2847 execq
2848 -----
2849     1
2850 (1 row)
2851
2852 vac=> SELECT execq('SELECT * FROM a', 10);
2853 NOTICE:EXECQ:  0 
2854
2855 NOTICE:EXECQ:  1 
2856
2857 NOTICE:EXECQ:  2 <<< 0 + 2, only one tuple inserted - as specified
2858
2859 execq
2860 -----
2861     3            <<< 10 is max value only, 3 is real # of tuples
2862 (1 row)
2863
2864 vac=> DELETE FROM a;
2865 DELETE 3
2866 vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
2867 INSERT 167712 1
2868 vac=> SELECT * FROM a;
2869 x
2870 -
2871 1                <<< no tuples in a (0) + 1
2872 (1 row)
2873
2874 vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
2875 NOTICE:EXECQ:  0 
2876 INSERT 167713 1
2877 vac=> SELECT * FROM a;
2878 x
2879 -
2880 1
2881 2                <<< there was single tuple in a + 1
2882 (2 rows)
2883
2884 --   This demonstrates data changes visibility rule:
2885
2886 vac=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
2887 NOTICE:EXECQ:  1 
2888 NOTICE:EXECQ:  2 
2889 NOTICE:EXECQ:  1 
2890 NOTICE:EXECQ:  2 
2891 NOTICE:EXECQ:  2 
2892 INSERT 0 2
2893 vac=> SELECT * FROM a;
2894 x
2895 -
2896 1
2897 2
2898 2                <<< 2 tuples * 1 (x in first tuple)
2899 6                <<< 3 tuples (2 + 1 just inserted) * 2 (x in second tuple)
2900 (4 rows)             ^^^^^^^^ 
2901                      tuples visible to execq() in different invocations
2902 </ProgramListing>
2903 </Para>
2904 </Sect1>
2905 </Chapter>