Add a SPI_copytupledesc function that parallels SPI_copytuple --- ie,
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 2 Aug 2001 18:08:43 +0000 (18:08 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 2 Aug 2001 18:08:43 +0000 (18:08 +0000)
it copies the tupdesc into upper-executor memory.  This is necessary
for returning tuple descriptors without leaking all of lower exec memory.

doc/src/sgml/spi.sgml
src/backend/executor/spi.c
src/include/executor/spi.h

index 6cdd50230d9ee4318b539160560f4188116e199c..72e1a813cbb935c97b7f43c9be985e1641b6e4c0 100644 (file)
@@ -1229,6 +1229,121 @@ TBD
 <!-- *********************************************** -->
 <!-- *********************************************** -->
 
+<REFENTRY ID="SPI-SPICOPYTUPLEDESC">
+<REFMETA>
+<REFENTRYTITLE>SPI_copytupledesc</REFENTRYTITLE>
+<REFMISCINFO>SPI - Tuple Descriptor Copy</REFMISCINFO>
+</REFMETA>
+<REFNAMEDIV>
+<REFNAME>SPI_copytupledesc
+</REFNAME>
+<REFPURPOSE>
+Makes copy of tuple descriptor in upper Executor context
+</REFPURPOSE>
+<INDEXTERM ID="IX-SPI-SPICOPYTUPLEDESC-1"><PRIMARY>SPI</PRIMARY><SECONDARY>copying tuple descriptors</SECONDARY></INDEXTERM>
+<INDEXTERM ID="IX-SPI-SPICOPYTUPLEDESC-2"><PRIMARY>SPI_copytupledesc</PRIMARY></INDEXTERM>
+</REFNAMEDIV>
+<REFSYNOPSISDIV>
+<REFSYNOPSISDIVINFO>
+<DATE>2001-08-02</DATE>
+</REFSYNOPSISDIVINFO>
+<SYNOPSIS>
+SPI_copytupledesc(<REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>)
+</SYNOPSIS>
+
+<REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-1">
+<REFSECT2INFO>
+<DATE>2001-08-02</DATE>
+</REFSECT2INFO>
+<TITLE>Inputs
+</TITLE>
+<VARIABLELIST>
+<VARLISTENTRY>
+<TERM>
+TupleDesc <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
+</TERM>
+<LISTITEM>
+<PARA>
+Input tuple descriptor to be copied
+</PARA>
+</LISTITEM>
+</VARLISTENTRY>
+</VARIABLELIST>
+</REFSECT2>
+
+<REFSECT2 ID="R2-SPI-SPICOPYTUPLEDESC-2">
+<REFSECT2INFO>
+<DATE>2001-08-02</DATE>
+</REFSECT2INFO>
+<TITLE>Outputs
+</TITLE>
+<VARIABLELIST>
+<VARLISTENTRY>
+<TERM>
+TupleDesc
+</TERM>
+<LISTITEM>
+<PARA>
+Copied tuple descriptor
+<SimpleList>
+<Member>
+ <ReturnValue>non-NULL</ReturnValue>
+ if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
+ is not NULL and the copy was successful
+</Member>
+<Member>
+   <ReturnValue>NULL</ReturnValue>
+ only if <REPLACEABLE CLASS="PARAMETER">tupdesc</REPLACEABLE>
+ is NULL
+</Member>
+</SimpleList>
+</para>
+</LISTITEM>
+</VARLISTENTRY>
+</VARIABLELIST>
+</REFSECT2>
+</REFSYNOPSISDIV>
+
+<REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-1">
+<REFSECT1INFO>
+<DATE>2001-08-02</DATE>
+</REFSECT1INFO>
+<TITLE>Description
+</TITLE>
+<PARA>
+<FUNCTION>SPI_copytupledesc</FUNCTION> 
+   makes a copy of tupdesc in upper Executor context. See the section on Memory Management.
+</PARA>
+</REFSECT1>
+<REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-2">
+<TITLE>Usage
+</TITLE>
+<Para>
+TBD
+</PARA>
+</REFSECT1>
+<!--
+<REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-3">
+<TITLE>Algorithm
+</TITLE>
+<PARA>
+</PARA>
+</REFSECT1>
+-->
+<!--
+<REFSECT1 ID="R1-SPI-SPICOPYTUPLEDESC-4">
+<TITLE>Structures
+</TITLE>
+<PARA>None
+</PARA>
+</REFSECT1>
+-->
+</REFENTRY>
+
+<!-- *********************************************** -->
+<!-- *********************************************** -->
+<!-- *********************************************** -->
+
 <REFENTRY ID="SPI-SPIMODIFYTUPLE">
 <REFMETA>
 <REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
@@ -2647,10 +2762,13 @@ made in this context.
 
 <Para>
 
-   After <Function>SPI_connect</Function> is called current context is the procedure's one.  All
-allocations made via <Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility functions (except
-for <Function>SPI_copytuple</Function>, <Function>SPI_modifytuple</Function>,
- <Function>SPI_palloc</Function> and <Function>SPI_repalloc</Function>) are
+   After <Function>SPI_connect</Function> is called current context is the
+   procedure's one.  All allocations made via
+<Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility
+functions (except for <Function>SPI_copytuple</Function>,
+<Function>SPI_copytupledesc</Function>,
+<Function>SPI_modifytuple</Function>,
+<Function>SPI_palloc</Function> and <Function>SPI_repalloc</Function>) are
 made in this context.
 </Para>
 
index 7b4030d580a58cb6379559eff70c015d97d99342..8c6420ae4ccfab712bf16a600a54f6ba7c5f5d53 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.56 2001/08/02 16:05:23 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.57 2001/08/02 18:08:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -333,6 +333,33 @@ SPI_copytuple(HeapTuple tuple)
        return ctuple;
 }
 
+TupleDesc
+SPI_copytupledesc(TupleDesc tupdesc)
+{
+       MemoryContext oldcxt = NULL;
+       TupleDesc       ctupdesc;
+
+       if (tupdesc == NULL)
+       {
+               SPI_result = SPI_ERROR_ARGUMENT;
+               return NULL;
+       }
+
+       if (_SPI_curid + 1 == _SPI_connected)           /* connected */
+       {
+               if (_SPI_current != &(_SPI_stack[_SPI_curid + 1]))
+                       elog(FATAL, "SPI: stack corrupted");
+               oldcxt = MemoryContextSwitchTo(_SPI_current->savedcxt);
+       }
+
+       ctupdesc = CreateTupleDescCopy(tupdesc);
+
+       if (oldcxt)
+               MemoryContextSwitchTo(oldcxt);
+
+       return ctupdesc;
+}
+
 HeapTuple
 SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
                                Datum *Values, char *Nulls)
@@ -1232,7 +1259,7 @@ _SPI_end_call(bool procmem)
 }
 
 static bool
-_SPI_checktuples()
+_SPI_checktuples(void)
 {
        uint32          processed = _SPI_current->processed;
        SPITupleTable *tuptable = _SPI_current->tuptable;
@@ -1244,8 +1271,8 @@ _SPI_checktuples()
                        failed = true;
        }
        else
-/* some tuples were processed */
        {
+               /* some tuples were processed */
                if (tuptable == NULL)   /* spi_printtup was not called */
                        failed = true;
                else if (processed != (tuptable->alloced - tuptable->free))
index 3a7c7807942ab4376183a35f8ad0b564986a562e..bef68bc7a6e52b39da61270fb4cf0c55d9f48e11 100644 (file)
@@ -2,6 +2,7 @@
  *
  * spi.h
  *
+ * $Id: spi.h,v 1.28 2001/08/02 18:08:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,17 +49,17 @@ typedef struct
        HeapTuple  *vals;                       /* tuples */
 } SPITupleTable;
 
-#define SPI_ERROR_CONNECT              -1
-#define SPI_ERROR_COPY                 -2
-#define SPI_ERROR_OPUNKNOWN            -3
-#define SPI_ERROR_UNCONNECTED  -4
-#define SPI_ERROR_CURSOR               -5
-#define SPI_ERROR_ARGUMENT             -6
-#define SPI_ERROR_PARAM                        -7
-#define SPI_ERROR_TRANSACTION  -8
-#define SPI_ERROR_NOATTRIBUTE  -9
-#define SPI_ERROR_NOOUTFUNC            -10
-#define SPI_ERROR_TYPUNKNOWN   -11
+#define SPI_ERROR_CONNECT              (-1)
+#define SPI_ERROR_COPY                 (-2)
+#define SPI_ERROR_OPUNKNOWN            (-3)
+#define SPI_ERROR_UNCONNECTED  (-4)
+#define SPI_ERROR_CURSOR               (-5)
+#define SPI_ERROR_ARGUMENT             (-6)
+#define SPI_ERROR_PARAM                        (-7)
+#define SPI_ERROR_TRANSACTION  (-8)
+#define SPI_ERROR_NOATTRIBUTE  (-9)
+#define SPI_ERROR_NOOUTFUNC            (-10)
+#define SPI_ERROR_TYPUNKNOWN   (-11)
 
 #define SPI_OK_CONNECT                 1
 #define SPI_OK_FINISH                  2
@@ -87,6 +88,7 @@ extern void *SPI_saveplan(void *plan);
 extern int  SPI_freeplan(void *plan);
 
 extern HeapTuple SPI_copytuple(HeapTuple tuple);
+extern TupleDesc SPI_copytupledesc(TupleDesc tupdesc);
 extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
                                int *attnum, Datum *Values, char *Nulls);
 extern int     SPI_fnumber(TupleDesc tupdesc, char *fname);