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 @@ ...@@ -3,7 +3,7 @@
* spi.c * spi.c
* Server Programming Interface * 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) ...@@ -397,10 +397,13 @@ SPI_fname(TupleDesc tupdesc, int fnumber)
char * char *
SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
{ {
Datum val; Datum origval,
val,
result;
bool isnull; bool isnull;
Oid foutoid, Oid foutoid,
typelem; typelem;
bool typisvarlena;
SPI_result = 0; SPI_result = 0;
if (tuple->t_data->t_natts < fnumber || fnumber <= 0) if (tuple->t_data->t_natts < fnumber || fnumber <= 0)
...@@ -409,20 +412,35 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber) ...@@ -409,20 +412,35 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
return NULL; return NULL;
} }
val = heap_getattr(tuple, fnumber, tupdesc, &isnull); origval = heap_getattr(tuple, fnumber, tupdesc, &isnull);
if (isnull) if (isnull)
return NULL; return NULL;
if (!getTypeOutAndElem((Oid) tupdesc->attrs[fnumber - 1]->atttypid, if (!getTypeOutputInfo(tupdesc->attrs[fnumber - 1]->atttypid,
&foutoid, &typelem)) &foutoid, &typelem, &typisvarlena))
{ {
SPI_result = SPI_ERROR_NOOUTFUNC; SPI_result = SPI_ERROR_NOOUTFUNC;
return NULL; return NULL;
} }
return DatumGetCString(OidFunctionCall3(foutoid, /*
val, * If we have a toasted datum, forcibly detoast it here to avoid memory
ObjectIdGetDatum(typelem), * leakage inside the type's output routine.
Int32GetDatum(tupdesc->attrs[fnumber - 1]->atttypmod))); */
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 Datum
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -69,9 +69,6 @@ donothingCleanup(DestReceiver *self)
static DestReceiver donothingDR = { static DestReceiver donothingDR = {
donothingReceive, donothingSetup, donothingCleanup donothingReceive, donothingSetup, donothingCleanup
}; };
static DestReceiver printtup_internalDR = {
printtup_internal, donothingSetup, donothingCleanup
};
static DestReceiver debugtupDR = { static DestReceiver debugtupDR = {
debugtup, donothingSetup, donothingCleanup debugtup, donothingSetup, donothingCleanup
}; };
...@@ -180,11 +177,10 @@ DestToFunction(CommandDest dest) ...@@ -180,11 +177,10 @@ DestToFunction(CommandDest dest)
switch (dest) switch (dest)
{ {
case Remote: case Remote:
/* printtup wants a dynamically allocated DestReceiver */ return printtup_create_DR(false);
return printtup_create_DR();
case RemoteInternal: case RemoteInternal:
return &printtup_internalDR; return printtup_create_DR(true);
case Debug: case Debug:
return &debugtupDR; return &debugtupDR;
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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 @@ ...@@ -16,17 +16,17 @@
#include "tcop/dest.h" #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 showatts(char *name, TupleDesc attinfo);
extern void debugtup(HeapTuple tuple, TupleDesc typeinfo, extern void debugtup(HeapTuple tuple, TupleDesc typeinfo,
DestReceiver *self); DestReceiver *self);
extern void printtup_internal(HeapTuple tuple, TupleDesc typeinfo,
DestReceiver *self);
/* XXX this one is really in executor/spi.c */ /* XXX this one is really in executor/spi.c */
extern void spi_printtup(HeapTuple tuple, TupleDesc tupdesc, 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 */ #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