Commit 217d1566 authored by Tom Lane's avatar Tom Lane

Make tuple receive/print routines TOAST-aware. Formerly, printtup would

leak memory when printing a toasted attribute, and printtup_internal
didn't work at all...
parent f5371fee
This diff is collapsed.
......@@ -3,7 +3,7 @@
* spi.c
* Server Programming Interface
*
* $Id: spi.c,v 1.49 2000/11/16 22:30:22 tgl Exp $
* $Id: spi.c,v 1.50 2000/12/01 22:10:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -397,10 +397,13 @@ SPI_fname(TupleDesc tupdesc, int fnumber)
char *
SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
{
Datum val;
Datum origval,
val,
result;
bool isnull;
Oid foutoid,
typelem;
bool typisvarlena;
SPI_result = 0;
if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
......@@ -409,20 +412,35 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
return NULL;
}
val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
origval = heap_getattr(tuple, fnumber, tupdesc, &isnull);
if (isnull)
return NULL;
if (!getTypeOutAndElem((Oid) tupdesc->attrs[fnumber - 1]->atttypid,
&foutoid, &typelem))
if (!getTypeOutputInfo(tupdesc->attrs[fnumber - 1]->atttypid,
&foutoid, &typelem, &typisvarlena))
{
SPI_result = SPI_ERROR_NOOUTFUNC;
return NULL;
}
return DatumGetCString(OidFunctionCall3(foutoid,
val,
ObjectIdGetDatum(typelem),
Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod)));
/*
* If we have a toasted datum, forcibly detoast it here to avoid memory
* leakage inside the type's output routine.
*/
if (typisvarlena)
val = PointerGetDatum(PG_DETOAST_DATUM(origval));
else
val = origval;
result = OidFunctionCall3(foutoid,
val,
ObjectIdGetDatum(typelem),
Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod));
/* Clean up detoasted copy, if any */
if (val != origval)
pfree(DatumGetPointer(val));
return DatumGetCString(result);
}
Datum
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.40 2000/10/22 22:14:55 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.41 2000/12/01 22:10:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -69,9 +69,6 @@ donothingCleanup(DestReceiver *self)
static DestReceiver donothingDR = {
donothingReceive, donothingSetup, donothingCleanup
};
static DestReceiver printtup_internalDR = {
printtup_internal, donothingSetup, donothingCleanup
};
static DestReceiver debugtupDR = {
debugtup, donothingSetup, donothingCleanup
};
......@@ -180,11 +177,10 @@ DestToFunction(CommandDest dest)
switch (dest)
{
case Remote:
/* printtup wants a dynamically allocated DestReceiver */
return printtup_create_DR();
return printtup_create_DR(false);
case RemoteInternal:
return &printtup_internalDR;
return printtup_create_DR(true);
case Debug:
return &debugtupDR;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: printtup.h,v 1.12 2000/01/26 05:57:50 momjian Exp $
* $Id: printtup.h,v 1.13 2000/12/01 22:10:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -16,17 +16,17 @@
#include "tcop/dest.h"
extern DestReceiver *printtup_create_DR(void);
extern DestReceiver *printtup_create_DR(bool isBinary);
extern void showatts(char *name, TupleDesc attinfo);
extern void debugtup(HeapTuple tuple, TupleDesc typeinfo,
DestReceiver *self);
extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo,
DestReceiver *self);
DestReceiver *self);
/* XXX this one is really in executor/spi.c */
extern void spi_printtup(HeapTuple tuple, TupleDesc tupdesc,
DestReceiver *self);
DestReceiver *self);
extern int getTypeOutAndElem(Oid type, Oid *typOutput, Oid *typElem);
extern bool getTypeOutputInfo(Oid type, Oid *typOutput, Oid *typElem,
bool *typIsVarlena);
#endif /* PRINTTUP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment