Commit 2dbdba86 authored by Tom Lane's avatar Tom Lane

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.
parent b9be04e6
......@@ -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);
}
......
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