aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execUtils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execUtils.c')
-rw-r--r--src/backend/executor/execUtils.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 5221624fc7d..c814b971472 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.129 2005/11/23 20:27:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execUtils.c,v 1.130 2005/12/02 20:03:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -24,6 +24,9 @@
* ExecAssignResultType
* etc
*
+ * ExecOpenScanRelation Common code for scan node init routines.
+ * ExecCloseScanRelation
+ *
* ExecOpenIndices \
* ExecCloseIndices | referenced by InitPlan, EndPlan,
* ExecInsertIndexTuples / ExecInsert, ExecUpdate
@@ -45,6 +48,7 @@
#include "catalog/pg_index.h"
#include "executor/execdebug.h"
#include "miscadmin.h"
+#include "parser/parsetree.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/memutils.h"
@@ -685,6 +689,90 @@ ExecAssignScanTypeFromOuterPlan(ScanState *scanstate)
/* ----------------------------------------------------------------
+ * Scan node support
+ * ----------------------------------------------------------------
+ */
+
+/* ----------------------------------------------------------------
+ * ExecOpenScanRelation
+ *
+ * Open the heap relation to be scanned by a base-level scan plan node.
+ * This should be called during the node's ExecInit routine.
+ *
+ * By default, this acquires AccessShareLock on the relation. However,
+ * if the relation was already locked by InitPlan, we don't need to acquire
+ * any additional lock. This saves trips to the shared lock manager.
+ * ----------------------------------------------------------------
+ */
+Relation
+ExecOpenScanRelation(EState *estate, Index scanrelid)
+{
+ RangeTblEntry *rtentry;
+ Oid reloid;
+ LOCKMODE lockmode;
+ ResultRelInfo *resultRelInfos;
+ int i;
+
+ /*
+ * First determine the lock type we need. Scan to see if target relation
+ * is either a result relation or a FOR UPDATE/FOR SHARE relation.
+ */
+ lockmode = AccessShareLock;
+ resultRelInfos = estate->es_result_relations;
+ for (i = 0; i < estate->es_num_result_relations; i++)
+ {
+ if (resultRelInfos[i].ri_RangeTableIndex == scanrelid)
+ {
+ lockmode = NoLock;
+ break;
+ }
+ }
+
+ if (lockmode == AccessShareLock)
+ {
+ ListCell *l;
+
+ foreach(l, estate->es_rowMarks)
+ {
+ ExecRowMark *erm = lfirst(l);
+
+ if (erm->rti == scanrelid)
+ {
+ lockmode = NoLock;
+ break;
+ }
+ }
+ }
+
+ /* OK, open the relation and acquire lock as needed */
+ rtentry = rt_fetch(scanrelid, estate->es_range_table);
+ reloid = rtentry->relid;
+
+ return heap_open(reloid, lockmode);
+}
+
+/* ----------------------------------------------------------------
+ * ExecCloseScanRelation
+ *
+ * Close the heap relation scanned by a base-level scan plan node.
+ * This should be called during the node's ExecEnd routine.
+ *
+ * Currently, we do not release the lock acquired by ExecOpenScanRelation.
+ * This lock should be held till end of transaction. (There is a faction
+ * that considers this too much locking, however.)
+ *
+ * If we did want to release the lock, we'd have to repeat the logic in
+ * ExecOpenScanRelation in order to figure out what to release.
+ * ----------------------------------------------------------------
+ */
+void
+ExecCloseScanRelation(Relation scanrel)
+{
+ heap_close(scanrel, NoLock);
+}
+
+
+/* ----------------------------------------------------------------
* ExecInsertIndexTuples support
* ----------------------------------------------------------------
*/
@@ -760,7 +848,7 @@ ExecOpenIndices(ResultRelInfo *resultRelInfo)
*
* If the index AM is not safe for concurrent updates, obtain an
* exclusive lock on the index to lock out other updaters as well as
- * readers (index_beginscan places AccessShareLock).
+ * readers (index_beginscan places AccessShareLock on the index).
*
* If there are multiple not-concurrent-safe indexes, all backends
* must lock the indexes in the same order or we will get deadlocks