diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml index 6cdd50230d9ee4318b539160560f4188116e199c..72e1a813cbb935c97b7f43c9be985e1641b6e4c0 100644 --- a/doc/src/sgml/spi.sgml +++ b/doc/src/sgml/spi.sgml @@ -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> diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index 7b4030d580a58cb6379559eff70c015d97d99342..8c6420ae4ccfab712bf16a600a54f6ba7c5f5d53 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -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)) diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h index 3a7c7807942ab4376183a35f8ad0b564986a562e..bef68bc7a6e52b39da61270fb4cf0c55d9f48e11 100644 --- a/src/include/executor/spi.h +++ b/src/include/executor/spi.h @@ -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);