aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-12-03 05:51:03 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-12-03 05:51:03 +0000
commita98871b7ac601b4ebe6ba050b1f9cbfdd5d71ded (patch)
tree14a0b7c6a91cf05fc5556a6dcb00246ff11b0e6a /src/backend/executor
parent1cf65140d07527e01c56164caefb5eb0c8106480 (diff)
downloadpostgresql-a98871b7ac601b4ebe6ba050b1f9cbfdd5d71ded.tar.gz
postgresql-a98871b7ac601b4ebe6ba050b1f9cbfdd5d71ded.zip
Tweak indexscan machinery to avoid taking an AccessShareLock on an index
if we already have a stronger lock due to the index's table being the update target table of the query. Same optimization I applied earlier at the table level. There doesn't seem to be much interest in the more radical idea of not locking indexes at all, so do what we can ...
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execUtils.c24
-rw-r--r--src/backend/executor/nodeBitmapIndexscan.c13
-rw-r--r--src/backend/executor/nodeIndexscan.c12
3 files changed, 42 insertions, 7 deletions
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index c814b971472..500ff0f4f27 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.130 2005/12/02 20:03:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.131 2005/12/03 05:51:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -694,6 +694,28 @@ ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
*/
/* ----------------------------------------------------------------
+ * ExecRelationIsTargetRelation
+ *
+ * Detect whether a relation (identified by rangetable index)
+ * is one of the target relations of the query.
+ * ----------------------------------------------------------------
+ */
+bool
+ExecRelationIsTargetRelation(EState *estate, Index scanrelid)
+{
+ ResultRelInfo *resultRelInfos;
+ int i;
+
+ resultRelInfos = estate->es_result_relations;
+ for (i = 0; i < estate->es_num_result_relations; i++)
+ {
+ if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
+ return true;
+ }
+ return false;
+}
+
+/* ----------------------------------------------------------------
* ExecOpenScanRelation
*
* Open the heap relation to be scanned by a base-level scan plan node.
diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c
index 4217de39522..114de29ba8e 100644
--- a/src/backend/executor/nodeBitmapIndexscan.c
+++ b/src/backend/executor/nodeBitmapIndexscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.13 2005/12/02 20:03:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.14 2005/12/03 05:51:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -214,6 +214,7 @@ BitmapIndexScanState *
ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
{
BitmapIndexScanState *indexstate;
+ bool relistarget;
/*
* create state structure
@@ -294,13 +295,19 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
indexstate->ss.ss_currentScanDesc = NULL;
/*
- * open the index relation and initialize relation and scan descriptors.
+ * 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.
+ * and unlocks. (We rely on having a lock on the parent table to
+ * ensure the index won't go away!) Furthermore, if the parent table
+ * is one of the target relations of the query, then InitPlan already
+ * opened and write-locked the index, so we can tell the index machinery
+ * not to bother getting an extra lock.
*/
indexstate->biss_RelationDesc = index_open(node->indexid);
+ relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid);
indexstate->biss_ScanDesc =
index_beginscan_multi(indexstate->biss_RelationDesc,
+ !relistarget,
estate->es_snapshot,
indexstate->biss_NumScanKeys,
indexstate->biss_ScanKeys);
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 4beecfbd57f..94495b4bc71 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.108 2005/12/02 20:03:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.109 2005/12/03 05:51:02 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -461,6 +461,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
{
IndexScanState *indexstate;
Relation currentRelation;
+ bool relistarget;
/*
* create state structure
@@ -557,14 +558,19 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
ExecAssignScanType(&indexstate->ss, RelationGetDescr(currentRelation), false);
/*
- * open the index relation and initialize relation and scan descriptors.
+ * 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 a lock on the parent table to
- * ensure the index won't go away!)
+ * ensure the index won't go away!) Furthermore, if the parent table
+ * is one of the target relations of the query, then InitPlan already
+ * opened and write-locked the index, so we can tell the index machinery
+ * not to bother getting an extra lock.
*/
indexstate->iss_RelationDesc = index_open(node->indexid);
+ relistarget = ExecRelationIsTargetRelation(estate, node->scan.scanrelid);
indexstate->iss_ScanDesc = index_beginscan(currentRelation,
indexstate->iss_RelationDesc,
+ !relistarget,
estate->es_snapshot,
indexstate->iss_NumScanKeys,
indexstate->iss_ScanKeys);