From ace71981220b8cae863e8a99b5b14b85cf19ba90 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 21 Mar 2018 22:00:24 +0000 Subject: [PATCH v1 2/2] Add skip-locked option to RangeVarGetRelidExtended(). --- src/backend/catalog/namespace.c | 15 ++++++++++++++- src/include/catalog/namespace.h | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index edd229d..72e069e 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -210,6 +210,13 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, * RELID_MISSING_OK, otherwise raise an error. * * If the flags contain RELID_NOWAIT, throw an error if we'd have to wait for a lock. + * If the flags contain RELID_SKIP_LOCKED, return InvalidOid if we'd have to wait for + * a lock. The flags cannot contain both RELID_NOWAIT and RELID_SKIP_LOCKED + * together. + * + * Note that if RELID_MISSING_OK and RELID_SKIP_LOCKED are both specified, a return + * value of InvalidOid could either mean the relation is missing or it could not be + * locked. * * Callback allows caller to check permissions or acquire additional locks * prior to grabbing the relation lock. @@ -225,6 +232,9 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, bool retry = false; bool missing_ok = ((flags & RELID_MISSING_OK) != 0); + /* verify that conflicting options are not specified */ + Assert((flags & (RELID_NOWAIT | RELID_SKIP_LOCKED)) != (RELID_NOWAIT | RELID_SKIP_LOCKED)); + /* * We check the catalog name and then ignore it. */ @@ -362,10 +372,13 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, */ if (!OidIsValid(relId)) AcceptInvalidationMessages(); - else if ((flags & RELID_NOWAIT) == 0) + else if ((flags & (RELID_NOWAIT | RELID_SKIP_LOCKED)) == 0) LockRelationOid(relId, lockmode); else if (!ConditionalLockRelationOid(relId, lockmode)) { + if ((flags & RELID_SKIP_LOCKED) != 0) + return InvalidOid; + if (relation->schemaname) ereport(ERROR, (errcode(ERRCODE_LOCK_NOT_AVAILABLE), diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h index 22f8667..cca99cd 100644 --- a/src/include/catalog/namespace.h +++ b/src/include/catalog/namespace.h @@ -50,7 +50,8 @@ typedef struct OverrideSearchPath typedef enum RelidOption { RELID_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */ - RELID_NOWAIT = 1 << 1 /* error if relation cannot be locked */ + RELID_NOWAIT = 1 << 1, /* error if relation cannot be locked */ + RELID_SKIP_LOCKED = 1 << 2 /* skip if relation cannot be locked */ } RelidOption; typedef void (*RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, -- 2.7.3.AMZN