diff options
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execMain.c | 11 | ||||
-rw-r--r-- | src/backend/executor/execUtils.c | 20 |
2 files changed, 27 insertions, 4 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 5443cbf67db..2b7cf263803 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -864,6 +864,7 @@ InitPlan(QueryDesc *queryDesc, int eflags) Relation resultRelation; resultRelationOid = getrelid(resultRelationIndex, rangeTable); + Assert(rt_fetch(resultRelationIndex, rangeTable)->rellockmode == RowExclusiveLock); resultRelation = heap_open(resultRelationOid, RowExclusiveLock); InitResultRelInfo(resultRelInfo, @@ -904,6 +905,7 @@ InitPlan(QueryDesc *queryDesc, int eflags) Relation resultRelDesc; resultRelOid = getrelid(resultRelIndex, rangeTable); + Assert(rt_fetch(resultRelIndex, rangeTable)->rellockmode == RowExclusiveLock); resultRelDesc = heap_open(resultRelOid, RowExclusiveLock); InitResultRelInfo(resultRelInfo, resultRelDesc, @@ -924,8 +926,11 @@ InitPlan(QueryDesc *queryDesc, int eflags) /* We locked the roots above. */ if (!list_member_int(plannedstmt->rootResultRelations, resultRelIndex)) + { + Assert(rt_fetch(resultRelIndex, rangeTable)->rellockmode == RowExclusiveLock); LockRelationOid(getrelid(resultRelIndex, rangeTable), RowExclusiveLock); + } } } } @@ -955,6 +960,7 @@ InitPlan(QueryDesc *queryDesc, int eflags) { PlanRowMark *rc = (PlanRowMark *) lfirst(l); Oid relid; + LOCKMODE rellockmode; Relation relation; ExecRowMark *erm; @@ -964,6 +970,7 @@ InitPlan(QueryDesc *queryDesc, int eflags) /* get relation's OID (will produce InvalidOid if subquery) */ relid = getrelid(rc->rti, rangeTable); + rellockmode = rt_fetch(rc->rti, rangeTable)->rellockmode; /* * If you change the conditions under which rel locks are acquired @@ -975,9 +982,13 @@ InitPlan(QueryDesc *queryDesc, int eflags) case ROW_MARK_NOKEYEXCLUSIVE: case ROW_MARK_SHARE: case ROW_MARK_KEYSHARE: + Assert(rellockmode == RowShareLock); relation = heap_open(relid, RowShareLock); break; case ROW_MARK_REFERENCE: + /* RTE might be a query target table */ + Assert(rellockmode == AccessShareLock || + rellockmode == RowExclusiveLock); relation = heap_open(relid, AccessShareLock); break; case ROW_MARK_COPY: diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 5b3eaec80bc..da84d5df442 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -657,20 +657,32 @@ ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags) /* * Determine the lock type we need. First, scan to see if target relation * is a result relation. If not, check if it's a FOR UPDATE/FOR SHARE - * relation. In either of those cases, we got the lock already. + * relation. + * + * Note: we may have already gotten the desired lock type, but for now + * don't try to optimize; this logic is going away soon anyhow. */ lockmode = AccessShareLock; if (ExecRelationIsTargetRelation(estate, scanrelid)) - lockmode = NoLock; + lockmode = RowExclusiveLock; else { /* Keep this check in sync with InitPlan! */ ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true); - if (erm != NULL && erm->relation != NULL) - lockmode = NoLock; + if (erm != NULL) + { + if (erm->markType == ROW_MARK_REFERENCE || + erm->markType == ROW_MARK_COPY) + lockmode = AccessShareLock; + else + lockmode = RowShareLock; + } } + /* lockmode per above logic must not be more than we previously acquired */ + Assert(lockmode <= rt_fetch(scanrelid, estate->es_range_table)->rellockmode); + /* Open the relation and acquire lock as needed */ reloid = getrelid(scanrelid, estate->es_range_table); rel = heap_open(reloid, lockmode); |