From 891039c15f0d0a0a7adba71a7ceb77fa74bb3b9c Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 7 Apr 2000 00:30:41 +0000
Subject: [PATCH] Partial fix for EvalPlanQual bugs reported by Magnus
 Hagander, 3-Apr. Ensure that outer tuple link needed for inner indexscan qual
 evaluation gets set in the EvalPlanQual case.  This stops coredump, but we
 still have resource leaks due to failure to clean up EvalPlanQual properly...

---
 src/backend/executor/nodeIndexscan.c | 21 ++++++++-------
 src/backend/executor/nodeTidscan.c   | 39 ++++++++++++----------------
 2 files changed, 27 insertions(+), 33 deletions(-)

diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index b1d1c578f38..16fcd225a8e 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.47 2000/02/18 09:29:57 inoue Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.48 2000/04/07 00:30:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -338,6 +338,11 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
 	if (ScanDirectionIsBackward(node->indxorderdir))
 		indexstate->iss_IndexPtr = numIndices;
 
+	/* If we are being passed an outer tuple, save it for runtime key calc */
+	if (exprCtxt != NULL)
+		node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple =
+			exprCtxt->ecxt_outertuple;
+
 	/* If this is re-scanning of PlanQual ... */
 	if (estate->es_evTuple != NULL &&
 		estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
@@ -346,12 +351,6 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
 		return;
 	}
 
-	/* it's possible in subselects */
-	if (exprCtxt == NULL)
-		exprCtxt = node->scan.scanstate->cstate.cs_ExprContext;
-
-	node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple = exprCtxt->ecxt_outertuple;
-
 	/*
 	 * get the index qualifications and recalculate the appropriate values
 	 */
@@ -379,14 +378,16 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
 				{
 					clause = nth(j, qual);
 					scanexpr = (run_keys[j] == RIGHT_OP) ?
-						(Node *) get_rightop(clause) : (Node *) get_leftop(clause);
-
+						(Node *) get_rightop(clause) :
+						(Node *) get_leftop(clause);
 					/*
 					 * pass in isDone but ignore it.  We don't iterate in
 					 * quals
 					 */
 					scanvalue = (Datum)
-						ExecEvalExpr(scanexpr, exprCtxt, &isNull, &isDone);
+						ExecEvalExpr(scanexpr,
+								node->scan.scanstate->cstate.cs_ExprContext,
+									 &isNull, &isDone);
 					scan_keys[j].sk_argument = scanvalue;
 					if (isNull)
 						scan_keys[j].sk_flags |= SK_ISNULL;
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 36159ad4abe..7d9c6748637 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.4 2000/01/26 05:56:24 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.5 2000/04/07 00:30:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -109,8 +109,10 @@ TidNext(TidScan *node)
 		if (estate->es_evTupleNull[node->scan.scanrelid - 1])
 			return slot;		/* return empty slot */
 		
+		/* probably ought to use ExecStoreTuple here... */
 		slot->val = estate->es_evTuple[node->scan.scanrelid - 1];
 		slot->ttc_shouldFree = false;
+
 		/* Flag for the next call that no more tuples */
 		estate->es_evTupleNull[node->scan.scanrelid - 1] = true;
 		return (slot);
@@ -255,7 +257,6 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent)
 {
 	EState		*estate;
 	TidScanState	*tidstate;
-	Plan		*outerPlan;
 	ItemPointer	*tidList;
 
 	tidstate = node->tidstate;
@@ -263,30 +264,22 @@ ExecTidReScan(TidScan *node, ExprContext *exprCtxt, Plan *parent)
 	tidstate->tss_TidPtr = -1;
 	tidList = tidstate->tss_TidList;
 
-	if ((outerPlan = outerPlan((Plan *) node)) != NULL)
+	/* If we are being passed an outer tuple, save it for runtime key calc */
+	if (exprCtxt != NULL)
+		node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple =
+			exprCtxt->ecxt_outertuple;
+
+	/* If this is re-scanning of PlanQual ... */
+	if (estate->es_evTuple != NULL &&
+		estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
 	{
-		/* we are scanning a subplan */
-		outerPlan = outerPlan((Plan *) node);
-		ExecReScan(outerPlan, exprCtxt, parent);
+		estate->es_evTupleNull[node->scan.scanrelid - 1] = false;
+		return;
 	}
-	else
-	/* otherwise, we are scanning a relation */
-	{
-		/* If this is re-scanning of PlanQual ... */
-		if (estate->es_evTuple != NULL &&
-			estate->es_evTuple[node->scan.scanrelid - 1] != NULL)
-		{
-			estate->es_evTupleNull[node->scan.scanrelid - 1] = false;
-			return;
-		}
 
-		/* it's possible in subselects */
-		if (exprCtxt == NULL)
-			exprCtxt = node->scan.scanstate->cstate.cs_ExprContext;
-
-		node->scan.scanstate->cstate.cs_ExprContext->ecxt_outertuple = exprCtxt->ecxt_outertuple;
-		tidstate->tss_NumTids = TidListCreate(node->tideval, exprCtxt, tidList);
-	}
+	tidstate->tss_NumTids = TidListCreate(node->tideval,
+									node->scan.scanstate->cstate.cs_ExprContext,
+										  tidList);
 
 	/* ----------------
 	 *	perhaps return something meaningful
-- 
GitLab