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/rewrite/rewriteHandler.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/rewrite/rewriteHandler.c')
-rw-r--r-- | src/backend/rewrite/rewriteHandler.c | 30 |
1 files changed, 10 insertions, 20 deletions
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 42cec2aeae8..43815d26ff5 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -87,17 +87,14 @@ static Bitmapset *adjust_view_column_set(Bitmapset *cols, List *targetlist); * AcquireRewriteLocks - * Acquire suitable locks on all the relations mentioned in the Query. * These locks will ensure that the relation schemas don't change under us - * while we are rewriting and planning the query. + * while we are rewriting, planning, and executing the query. * * Caution: this may modify the querytree, therefore caller should usually * have done a copyObject() to make a writable copy of the querytree in the * current memory context. * - * forExecute indicates that the query is about to be executed. - * If so, we'll acquire RowExclusiveLock on the query's resultRelation, - * RowShareLock on any relation accessed FOR [KEY] UPDATE/SHARE, and - * AccessShareLock on all other relations mentioned. - * + * forExecute indicates that the query is about to be executed. If so, + * we'll acquire the lock modes specified in the RTE rellockmode fields. * If forExecute is false, AccessShareLock is acquired on all relations. * This case is suitable for ruleutils.c, for example, where we only need * schema stability and we don't intend to actually modify any relations. @@ -162,31 +159,24 @@ AcquireRewriteLocks(Query *parsetree, /* * Grab the appropriate lock type for the relation, and do not - * release it until end of transaction. This protects the - * rewriter and planner against schema changes mid-query. + * release it until end of transaction. This protects the + * rewriter, planner, and executor against schema changes + * mid-query. * - * Assuming forExecute is true, this logic must match what the - * executor will do, else we risk lock-upgrade deadlocks. + * If forExecute is false, ignore rellockmode and just use + * AccessShareLock. */ if (!forExecute) lockmode = AccessShareLock; - else if (rt_index == parsetree->resultRelation) - lockmode = RowExclusiveLock; else if (forUpdatePushedDown) { - lockmode = RowShareLock; /* Upgrade RTE's lock mode to reflect pushed-down lock */ if (rte->rellockmode == AccessShareLock) rte->rellockmode = RowShareLock; + lockmode = rte->rellockmode; } - else if (get_parse_rowmark(parsetree, rt_index) != NULL) - lockmode = RowShareLock; else - lockmode = AccessShareLock; - - Assert(!forExecute || lockmode == rte->rellockmode || - (lockmode == AccessShareLock && - rte->rellockmode == RowExclusiveLock)); + lockmode = rte->rellockmode; rel = heap_open(rte->relid, lockmode); |