From 2dbdba86db809d7eaa36cee9a0e00a83627a17ca Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 19 Apr 2001 04:29:02 +0000
Subject: [PATCH] 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.

---
 src/backend/executor/execQual.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 7cd678963a3..84aa271629b 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);
 	}
 
-- 
GitLab