summaryrefslogtreecommitdiff
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.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 3d6a3801c06..a72cffeb6e5 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -43,6 +43,7 @@
#include "executor/executor.h"
#include "nodes/nodeFuncs.h"
#include "parser/parsetree.h"
+#include "storage/lmgr.h"
#include "utils/memutils.h"
#include "utils/rel.h"
@@ -953,3 +954,58 @@ ShutdownExprContext(ExprContext *econtext, bool isCommit)
MemoryContextSwitchTo(oldcontext);
}
+
+/*
+ * ExecLockNonLeafAppendTables
+ *
+ * Locks, if necessary, the tables indicated by the RT indexes contained in
+ * the partitioned_rels list. These are the non-leaf tables in the partition
+ * tree controlled by a given Append or MergeAppend node.
+ */
+void
+ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate)
+{
+ PlannedStmt *stmt = estate->es_plannedstmt;
+ ListCell *lc;
+
+ foreach(lc, partitioned_rels)
+ {
+ ListCell *l;
+ Index rti = lfirst_int(lc);
+ bool is_result_rel = false;
+ Oid relid = getrelid(rti, estate->es_range_table);
+
+ /* If this is a result relation, already locked in InitPlan */
+ foreach(l, stmt->nonleafResultRelations)
+ {
+ if (rti == lfirst_int(l))
+ {
+ is_result_rel = true;
+ break;
+ }
+ }
+
+ /*
+ * Not a result relation; check if there is a RowMark that requires
+ * taking a RowShareLock on this rel.
+ */
+ if (!is_result_rel)
+ {
+ PlanRowMark *rc = NULL;
+
+ foreach(l, stmt->rowMarks)
+ {
+ if (((PlanRowMark *) lfirst(l))->rti == rti)
+ {
+ rc = lfirst(l);
+ break;
+ }
+ }
+
+ if (rc && RowMarkRequiresRowShareLock(rc->markType))
+ LockRelationOid(relid, RowShareLock);
+ else
+ LockRelationOid(relid, AccessShareLock);
+ }
+ }
+}