aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-12-01 22:10:31 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-12-01 22:10:31 +0000
commit217d1566bf12c9a6e48b1da1e93e886c4ed618aa (patch)
tree48869c53c6c15cd4c3076e9b836c2503244b0ce8 /src/backend/executor
parentf5371feef9ea4af23284c0f56d8a28cbf1de2a7f (diff)
downloadpostgresql-217d1566bf12c9a6e48b1da1e93e886c4ed618aa.tar.gz
postgresql-217d1566bf12c9a6e48b1da1e93e886c4ed618aa.zip
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...
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/spi.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 74a5dc44415..b309dc5022e 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -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