From de1dfc12092de69910405a23260761bf58fa2375 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 2 Dec 2005 01:29:55 +0000
Subject: [PATCH] Rearrange code in ExecInitBitmapHeapScan so that we don't
 initialize the child plan nodes until we have acquired lock on the relation
 to scan. The relative order of initialization of plan nodes isn't real
 important in other cases, but it's critical here because one is supposed to
 lock a relation before its indexes, not vice versa.  The original coding was
 at least vulnerable to deadlock against DROP INDEX, and perhaps worse things.

---
 src/backend/executor/nodeBitmapHeapscan.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 16b0453023f..37bd42d9d73 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -21,7 +21,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.6 2005/11/26 03:03:07 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.7 2005/12/02 01:29:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -508,11 +508,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate)
 		ExecInitExpr((Expr *) node->bitmapqualorig,
 					 (PlanState *) scanstate);
 
-	/*
-	 * initialize child nodes
-	 */
-	outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate);
-
 #define BITMAPHEAPSCAN_NSLOTS 2
 
 	/*
@@ -562,6 +557,15 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate)
 	ExecAssignResultTypeFromTL(&scanstate->ss.ps);
 	ExecAssignScanProjectionInfo(&scanstate->ss);
 
+	/*
+	 * initialize child nodes
+	 *
+	 * We do this last because the child nodes will open indexscans on our
+	 * relation's indexes, and we want to be sure we have acquired a lock
+	 * on the relation first.
+	 */
+	outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate);
+
 	/*
 	 * all done.
 	 */
-- 
GitLab