From: Tom Lane Date: Thu, 19 Apr 2001 04:29:02 +0000 (+0000) Subject: Kluge solution for Alex Pilosov's report of problems with whole-tuple X-Git-Tag: REL9_0_0~20761 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=2dbdba86db809d7eaa36cee9a0e00a83627a17ca;p=pg-rex%2Fsyncrep.git Kluge solution for Alex Pilosov's report of problems with whole-tuple function arguments in join queries: copy the tuples into TransactionCommandContext so they don't get recycled too soon. This is horrid, but not any worse than 7.0 or before, which also leaked such tuples until end of query. A proper fix will require allowing tuple datums to be physically stored inside larger tuple datums, which opens up a bunch of issues that can't realistically be solved for 7.1.1. --- diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 7cd678963a..84aa271629 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.85 2001/03/23 04:49:53 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.86 2001/04/19 04:29:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -333,21 +333,32 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull) /* * If the attribute number is invalid, then we are supposed to return - * the entire tuple, we give back a whole slot so that callers know - * what the tuple looks like. XXX why copy? Couldn't we just give - * back the existing slot? + * the entire tuple; we give back a whole slot so that callers know + * what the tuple looks like. + * + * XXX this is a horrid crock: since the pointer to the slot might + * live longer than the current evaluation context, we are forced to + * copy the tuple and slot into a long-lived context --- we use + * TransactionCommandContext which should be safe enough. This + * represents a serious memory leak if many such tuples are processed + * in one command, however. We ought to redesign the representation + * of whole-tuple datums so that this is not necessary. + * + * We assume it's OK to point to the existing tupleDescriptor, rather + * than copy that too. */ if (attnum == InvalidAttrNumber) { - TupleTableSlot *tempSlot = MakeTupleTableSlot(); - TupleDesc td; + MemoryContext oldContext; + TupleTableSlot *tempSlot; HeapTuple tup; + oldContext = MemoryContextSwitchTo(TransactionCommandContext); + tempSlot = MakeTupleTableSlot(); tup = heap_copytuple(heapTuple); - td = CreateTupleDescCopy(tuple_type); - - ExecSetSlotDescriptor(tempSlot, td, true); ExecStoreTuple(tup, tempSlot, InvalidBuffer, true); + ExecSetSlotDescriptor(tempSlot, tuple_type, false); + MemoryContextSwitchTo(oldContext); return PointerGetDatum(tempSlot); }