diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2018-10-02 14:43:01 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2018-10-02 14:43:09 -0400 |
commit | 6e35939febf83069430fedda6f89ab1fbe0f9e10 (patch) | |
tree | 7fcafdbda90ec0a6e3e788ab5a5f7252c7ebee47 /src/backend/executor/execUtils.c | |
parent | cc2905e963e950d01cd2cb6c860638ce9506c63d (diff) | |
download | postgresql-6e35939febf83069430fedda6f89ab1fbe0f9e10.tar.gz postgresql-6e35939febf83069430fedda6f89ab1fbe0f9e10.zip |
Change rewriter/planner/executor/plancache to depend on RTE rellockmode.
Instead of recomputing the required lock levels in all these places,
just use what commit fdba460a2 made the parser store in the RTE fields.
This already simplifies the code measurably in these places, and
follow-on changes will remove a bunch of no-longer-needed infrastructure.
In a few cases, this change causes us to acquire a higher lock level
than we did before. This is OK primarily because said higher lock level
should've been acquired already at query parse time; thus, we're saving
a useless extra trip through the shared lock manager to acquire a lesser
lock alongside the original lock. The only known exception to this is
that re-execution of a previously planned SELECT FOR UPDATE/SHARE query,
for a table that uses ROW_MARK_REFERENCE or ROW_MARK_COPY methods, might
have gotten only AccessShareLock before. Now it will get RowShareLock
like the first execution did, which seems fine.
While there's more to do, push it in this state anyway, to let the
buildfarm help verify that nothing bad happened.
Amit Langote, reviewed by David Rowley and Jesper Pedersen,
and whacked around a bit more by me
Discussion: https://postgr.es/m/468c85d9-540e-66a2-1dde-fec2b741e688@lab.ntt.co.jp
Diffstat (limited to 'src/backend/executor/execUtils.c')
-rw-r--r-- | src/backend/executor/execUtils.c | 43 |
1 files changed, 8 insertions, 35 deletions
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index da84d5df442..a4058c0f61d 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -641,10 +641,6 @@ ExecRelationIsTargetRelation(EState *estate, Index scanrelid) * * 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 @@ -654,37 +650,9 @@ ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags) Oid reloid; LOCKMODE lockmode; - /* - * 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. - * - * 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 = RowExclusiveLock; - else - { - /* Keep this check in sync with InitPlan! */ - ExecRowMark *erm = ExecFindRowMark(estate, scanrelid, true); - - 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); + lockmode = rt_fetch(scanrelid, estate->es_range_table)->rellockmode; rel = heap_open(reloid, lockmode); /* @@ -912,6 +880,7 @@ ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate) if (!is_result_rel) { PlanRowMark *rc = NULL; + LOCKMODE lockmode; foreach(l, stmt->rowMarks) { @@ -923,9 +892,13 @@ ExecLockNonLeafAppendTables(List *partitioned_rels, EState *estate) } if (rc && RowMarkRequiresRowShareLock(rc->markType)) - LockRelationOid(relid, RowShareLock); + lockmode = RowShareLock; else - LockRelationOid(relid, AccessShareLock); + lockmode = AccessShareLock; + + Assert(lockmode == rt_fetch(rti, estate->es_range_table)->rellockmode); + + LockRelationOid(relid, lockmode); } } } |