diff options
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r-- | src/backend/parser/analyze.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index fb6c44c11c8..bd78e949853 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -2358,7 +2358,7 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, allrels = makeNode(LockingClause); allrels->lockedRels = NIL; /* indicates all rels */ allrels->strength = lc->strength; - allrels->noWait = lc->noWait; + allrels->waitPolicy = lc->waitPolicy; if (lockedRels == NIL) { @@ -2372,13 +2372,13 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, switch (rte->rtekind) { case RTE_RELATION: - applyLockingClause(qry, i, - lc->strength, lc->noWait, pushedDown); + applyLockingClause(qry, i, lc->strength, lc->waitPolicy, + pushedDown); rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; break; case RTE_SUBQUERY: - applyLockingClause(qry, i, - lc->strength, lc->noWait, pushedDown); + applyLockingClause(qry, i, lc->strength, lc->waitPolicy, + pushedDown); /* * FOR UPDATE/SHARE of subquery is propagated to all of @@ -2424,15 +2424,13 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, switch (rte->rtekind) { case RTE_RELATION: - applyLockingClause(qry, i, - lc->strength, lc->noWait, - pushedDown); + applyLockingClause(qry, i, lc->strength, + lc->waitPolicy, pushedDown); rte->requiredPerms |= ACL_SELECT_FOR_UPDATE; break; case RTE_SUBQUERY: - applyLockingClause(qry, i, - lc->strength, lc->noWait, - pushedDown); + applyLockingClause(qry, i, lc->strength, + lc->waitPolicy, pushedDown); /* see comment above */ transformLockingClause(pstate, rte->subquery, allrels, true); @@ -2499,7 +2497,8 @@ transformLockingClause(ParseState *pstate, Query *qry, LockingClause *lc, */ void applyLockingClause(Query *qry, Index rtindex, - LockClauseStrength strength, bool noWait, bool pushedDown) + LockClauseStrength strength, LockWaitPolicy waitPolicy, + bool pushedDown) { RowMarkClause *rc; @@ -2516,15 +2515,20 @@ applyLockingClause(Query *qry, Index rtindex, * a shared and exclusive lock at the same time; it'll end up being * exclusive anyway.) * - * We also consider that NOWAIT wins if it's specified both ways. This - * is a bit more debatable but raising an error doesn't seem helpful. - * (Consider for instance SELECT FOR UPDATE NOWAIT from a view that - * internally contains a plain FOR UPDATE spec.) + * Similarly, if the same RTE is specified with more than one lock wait + * policy, consider that NOWAIT wins over SKIP LOCKED, which in turn + * wins over waiting for the lock (the default). This is a bit more + * debatable but raising an error doesn't seem helpful. (Consider for + * instance SELECT FOR UPDATE NOWAIT from a view that internally + * contains a plain FOR UPDATE spec.) Having NOWAIT win over SKIP + * LOCKED is reasonable since the former throws an error in case of + * coming across a locked tuple, which may be undesirable in some cases + * but it seems better than silently returning inconsistent results. * * And of course pushedDown becomes false if any clause is explicit. */ rc->strength = Max(rc->strength, strength); - rc->noWait |= noWait; + rc->waitPolicy = Max(rc->waitPolicy, waitPolicy); rc->pushedDown &= pushedDown; return; } @@ -2533,7 +2537,7 @@ applyLockingClause(Query *qry, Index rtindex, rc = makeNode(RowMarkClause); rc->rti = rtindex; rc->strength = strength; - rc->noWait = noWait; + rc->waitPolicy = waitPolicy; rc->pushedDown = pushedDown; qry->rowMarks = lappend(qry->rowMarks, rc); } |