Add a SPI_copytupledesc function that parallels SPI_copytuple --- ie,
it copies the tupdesc into upper-executor memory. This is necessary for returning tuple descriptors without leaking all of lower exec memory.
This commit is contained in:
parent
ba4d223cd9
commit
f59f3c8899
@ -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">
|
<REFENTRY ID="SPI-SPIMODIFYTUPLE">
|
||||||
<REFMETA>
|
<REFMETA>
|
||||||
<REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
|
<REFENTRYTITLE>SPI_modifytuple</REFENTRYTITLE>
|
||||||
@ -2647,10 +2762,13 @@ made in this context.
|
|||||||
|
|
||||||
<Para>
|
<Para>
|
||||||
|
|
||||||
After <Function>SPI_connect</Function> is called current context is the procedure's one. All
|
After <Function>SPI_connect</Function> is called current context is the
|
||||||
allocations made via <Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility functions (except
|
procedure's one. All allocations made via
|
||||||
for <Function>SPI_copytuple</Function>, <Function>SPI_modifytuple</Function>,
|
<Function>palloc</Function>/<Function>repalloc</Function> or by SPI utility
|
||||||
<Function>SPI_palloc</Function> and <Function>SPI_repalloc</Function>) are
|
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.
|
made in this context.
|
||||||
</Para>
|
</Para>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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
|
HeapTuple
|
||||||
SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
|
SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
|
||||||
Datum *Values, char *Nulls)
|
Datum *Values, char *Nulls)
|
||||||
@ -1232,7 +1259,7 @@ _SPI_end_call(bool procmem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_SPI_checktuples()
|
_SPI_checktuples(void)
|
||||||
{
|
{
|
||||||
uint32 processed = _SPI_current->processed;
|
uint32 processed = _SPI_current->processed;
|
||||||
SPITupleTable *tuptable = _SPI_current->tuptable;
|
SPITupleTable *tuptable = _SPI_current->tuptable;
|
||||||
@ -1244,8 +1271,8 @@ _SPI_checktuples()
|
|||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* some tuples were processed */
|
|
||||||
{
|
{
|
||||||
|
/* some tuples were processed */
|
||||||
if (tuptable == NULL) /* spi_printtup was not called */
|
if (tuptable == NULL) /* spi_printtup was not called */
|
||||||
failed = true;
|
failed = true;
|
||||||
else if (processed != (tuptable->alloced - tuptable->free))
|
else if (processed != (tuptable->alloced - tuptable->free))
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* spi.h
|
* 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 */
|
HeapTuple *vals; /* tuples */
|
||||||
} SPITupleTable;
|
} SPITupleTable;
|
||||||
|
|
||||||
#define SPI_ERROR_CONNECT -1
|
#define SPI_ERROR_CONNECT (-1)
|
||||||
#define SPI_ERROR_COPY -2
|
#define SPI_ERROR_COPY (-2)
|
||||||
#define SPI_ERROR_OPUNKNOWN -3
|
#define SPI_ERROR_OPUNKNOWN (-3)
|
||||||
#define SPI_ERROR_UNCONNECTED -4
|
#define SPI_ERROR_UNCONNECTED (-4)
|
||||||
#define SPI_ERROR_CURSOR -5
|
#define SPI_ERROR_CURSOR (-5)
|
||||||
#define SPI_ERROR_ARGUMENT -6
|
#define SPI_ERROR_ARGUMENT (-6)
|
||||||
#define SPI_ERROR_PARAM -7
|
#define SPI_ERROR_PARAM (-7)
|
||||||
#define SPI_ERROR_TRANSACTION -8
|
#define SPI_ERROR_TRANSACTION (-8)
|
||||||
#define SPI_ERROR_NOATTRIBUTE -9
|
#define SPI_ERROR_NOATTRIBUTE (-9)
|
||||||
#define SPI_ERROR_NOOUTFUNC -10
|
#define SPI_ERROR_NOOUTFUNC (-10)
|
||||||
#define SPI_ERROR_TYPUNKNOWN -11
|
#define SPI_ERROR_TYPUNKNOWN (-11)
|
||||||
|
|
||||||
#define SPI_OK_CONNECT 1
|
#define SPI_OK_CONNECT 1
|
||||||
#define SPI_OK_FINISH 2
|
#define SPI_OK_FINISH 2
|
||||||
@ -87,6 +88,7 @@ extern void *SPI_saveplan(void *plan);
|
|||||||
extern int SPI_freeplan(void *plan);
|
extern int SPI_freeplan(void *plan);
|
||||||
|
|
||||||
extern HeapTuple SPI_copytuple(HeapTuple tuple);
|
extern HeapTuple SPI_copytuple(HeapTuple tuple);
|
||||||
|
extern TupleDesc SPI_copytupledesc(TupleDesc tupdesc);
|
||||||
extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
|
extern HeapTuple SPI_modifytuple(Relation rel, HeapTuple tuple, int natts,
|
||||||
int *attnum, Datum *Values, char *Nulls);
|
int *attnum, Datum *Values, char *Nulls);
|
||||||
extern int SPI_fnumber(TupleDesc tupdesc, char *fname);
|
extern int SPI_fnumber(TupleDesc tupdesc, char *fname);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user