]> granicus.if.org Git - postgresql/commitdiff
Adjust nodeBitmapIndexscan.c to not keep the index open across calls,
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Apr 2005 18:16:38 +0000 (18:16 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Apr 2005 18:16:38 +0000 (18:16 +0000)
but just to open and close it during MultiExecBitmapIndexScan.  This
avoids acquiring duplicate resources (eg, multiple locks on the same
relation) in a tree with many bitmap scans.  Also, don't bother to
lock the parent heap at all here, since we must be underneath a
BitmapHeapScan node that will be holding a suitable lock.

src/backend/executor/nodeBitmapIndexscan.c
src/include/nodes/execnodes.h

index 34aa3b89854a1e971eabdaaa1fb45108b67d76df..73acd0c95205ff90200d898a9efbeb9f8df75da4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.5 2005/04/24 17:32:46 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.6 2005/04/24 18:16:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,6 +41,8 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
 {
 #define MAX_TIDS       1024
        TIDBitmap  *tbm;
+       Oid                     indxid;
+       Relation        indexRelation;
        IndexScanDesc scandesc;
        ItemPointerData tids[MAX_TIDS];
        int32           ntids;
@@ -58,9 +60,22 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
                ExecReScan((PlanState *) node, NULL);
 
        /*
-        * extract necessary information from index scan node
+        * We do not open or lock the base relation here.  We assume that an
+        * ancestor BitmapHeapScan node is holding AccessShareLock on the
+        * heap relation throughout the execution of the plan tree.
         */
-       scandesc = node->biss_ScanDesc;
+
+       /*
+        * open the index relation and initialize relation and scan
+        * descriptors.  Note we acquire no locks here; the index machinery
+        * does its own locks and unlocks.
+        */
+       indxid = ((BitmapIndexScan *) node->ss.ps.plan)->indxid;
+       indexRelation = index_open(indxid);
+       scandesc = index_beginscan_multi(indexRelation,
+                                                                        node->ss.ps.state->es_snapshot,
+                                                                        node->biss_NumScanKeys,
+                                                                        node->biss_ScanKeys);
 
        /*
         * Prepare the result bitmap.  Normally we just create a new one to pass
@@ -98,6 +113,12 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
                CHECK_FOR_INTERRUPTS();
        }
 
+       /*
+        * close the index relation
+        */
+       index_endscan(scandesc);
+       index_close(indexRelation);
+
        /* must provide our own instrumentation support */
        if (node->ss.ps.instrument)
                InstrStopNodeMulti(node->ss.ps.instrument, nTuples);
@@ -109,11 +130,7 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
  *             ExecBitmapIndexReScan(node)
  *
  *             Recalculates the value of the scan keys whose value depends on
- *             information known at runtime and rescans the indexed relation.
- *             Updating the scan key was formerly done separately in
- *             ExecUpdateIndexScanKeys. Integrating it into ReScan makes
- *             rescans of indices and relations/general streams more uniform.
- *
+ *             information known at runtime.
  * ----------------------------------------------------------------
  */
 void
@@ -121,12 +138,10 @@ ExecBitmapIndexReScan(BitmapIndexScanState *node, ExprContext *exprCtxt)
 {
        ExprContext *econtext;
        ExprState **runtimeKeyInfo;
-       Index           scanrelid;
 
        econtext = node->biss_RuntimeContext;           /* context for runtime
                                                                                                 * keys */
        runtimeKeyInfo = node->biss_RuntimeKeyInfo;
-       scanrelid = ((BitmapIndexScan *) node->ss.ps.plan)->scan.scanrelid;
 
        if (econtext)
        {
@@ -194,8 +209,6 @@ ExecBitmapIndexReScan(BitmapIndexScanState *node, ExprContext *exprCtxt)
 
                node->biss_RuntimeKeysReady = true;
        }
-
-       index_rescan(node->biss_ScanDesc, node->biss_ScanKeys);
 }
 
 /* ----------------------------------------------------------------
@@ -205,13 +218,6 @@ ExecBitmapIndexReScan(BitmapIndexScanState *node, ExprContext *exprCtxt)
 void
 ExecEndBitmapIndexScan(BitmapIndexScanState *node)
 {
-       Relation        relation;
-
-       /*
-        * extract information from the node
-        */
-       relation = node->ss.ss_currentRelation;
-
        /*
         * Free the exprcontext ... now dead code, see ExecFreeExprContext
         */
@@ -219,44 +225,12 @@ ExecEndBitmapIndexScan(BitmapIndexScanState *node)
        if (node->biss_RuntimeContext)
                FreeExprContext(node->biss_RuntimeContext);
 #endif
-
-       /*
-        * close the index relation
-        */
-       if (node->biss_ScanDesc != NULL)
-               index_endscan(node->biss_ScanDesc);
-
-       if (node->biss_RelationDesc != NULL)
-               index_close(node->biss_RelationDesc);
-
-       /*
-        * close the heap relation.
-        *
-        * Currently, we do not release the AccessShareLock acquired by
-        * ExecInitBitmapIndexScan.  This lock should be held till end of
-        * transaction. (There is a faction that considers this too much
-        * locking, however.)
-        */
-       heap_close(relation, NoLock);
 }
 
 /* ----------------------------------------------------------------
  *             ExecInitBitmapIndexScan
  *
- *             Initializes the index scan's state information, creates
- *             scan keys, and opens the base and index relations.
- *
- *             Note: index scans have 2 sets of state information because
- *                       we have to keep track of the base relation and the
- *                       index relations.
- *
- * old comments
- *             Creates the run-time state information for the node and
- *             sets the relation id to contain relevant descriptors.
- *
- *             Parameters:
- *               node: BitmapIndexNode node produced by the planner.
- *               estate: the execution state initialized in InitPlan.
+ *             Initializes the index scan's state information.
  * ----------------------------------------------------------------
  */
 BitmapIndexScanState *
@@ -265,10 +239,6 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
        BitmapIndexScanState *indexstate;
        ExprState **runtimeKeyInfo;
        bool            have_runtime_keys;
-       RangeTblEntry *rtentry;
-       Index           relid;
-       Oid                     reloid;
-       Relation        currentRelation;
 
        /*
         * create state structure
@@ -306,8 +276,6 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
        indexstate->biss_RuntimeKeyInfo = NULL;
        indexstate->biss_RuntimeContext = NULL;
        indexstate->biss_RuntimeKeysReady = false;
-       indexstate->biss_RelationDesc = NULL;
-       indexstate->biss_ScanDesc = NULL;
 
        CXT1_printf("ExecInitBitmapIndexScan: context is %d\n", CurrentMemoryContext);
 
@@ -459,7 +427,6 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
                runtimeKeyInfo = run_keys;
        }
 
-
        /*
         * If all of our keys have the form (var op const), then we have no
         * runtime keys so we store NULL in the runtime key info. Otherwise
@@ -489,30 +456,9 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
                        pfree(runtimeKeyInfo);
        }
 
-       /*
-        * open the base relation and acquire AccessShareLock on it.
-        */
-       relid = node->scan.scanrelid;
-       rtentry = rt_fetch(relid, estate->es_range_table);
-       reloid = rtentry->relid;
-
-       currentRelation = heap_open(reloid, AccessShareLock);
-
-       indexstate->ss.ss_currentRelation = currentRelation;
-       indexstate->ss.ss_currentScanDesc = NULL;       /* no heap scan here */
-
-       /*
-        * open the index relation and initialize relation and scan
-        * descriptors.  Note we acquire no locks here; the index machinery
-        * does its own locks and unlocks.      (We rely on having AccessShareLock
-        * on the parent table to ensure the index won't go away!)
-        */
-       indexstate->biss_RelationDesc = index_open(node->indxid);
-       indexstate->biss_ScanDesc =
-               index_beginscan_multi(indexstate->biss_RelationDesc,
-                                                         estate->es_snapshot,
-                                                         indexstate->biss_NumScanKeys,
-                                                         indexstate->biss_ScanKeys);
+       /* We don't keep the table or index open across calls */
+       indexstate->ss.ss_currentRelation = NULL;
+       indexstate->ss.ss_currentScanDesc = NULL;
 
        /*
         * all done.
index 01c50747620fab3b059b817c82840c3b2c556cc5..4a3af3cece0ef908e708f041065dd4095b107da0 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.127 2005/04/20 15:48:36 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.128 2005/04/24 18:16:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -908,8 +908,6 @@ typedef struct IndexScanState
  *                                                that will be evaluated at runtime
  *             RuntimeContext     expr context for evaling runtime Skeys
  *             RuntimeKeysReady   true if runtime Skeys have been computed
- *             RelationDesc       relation descriptor
- *             ScanDesc                   scan descriptor
  * ----------------
  */
 typedef struct BitmapIndexScanState
@@ -921,8 +919,6 @@ typedef struct BitmapIndexScanState
        ExprState **biss_RuntimeKeyInfo;
        ExprContext *biss_RuntimeContext;
        bool            biss_RuntimeKeysReady;
-       Relation        biss_RelationDesc;
-       IndexScanDesc biss_ScanDesc;
 } BitmapIndexScanState;
 
 /* ----------------