v2-0002-Add-skip-locked-option-to-RangeVarGetRelidExtende.patch

application/octet-stream

Filename: v2-0002-Add-skip-locked-option-to-RangeVarGetRelidExtende.patch
Type: application/octet-stream
Part: 1
Message: Re: Change RangeVarGetRelidExtended() to take flags argument?

Patch

Format: format-patch
Series: patch v2-0002
Subject: Add skip-locked option to RangeVarGetRelidExtended().
File+
src/backend/catalog/namespace.c 22 6
src/include/catalog/namespace.h 2 1
From eb349b58ab8ebaa30c7bd0892393c3f062d7c0e0 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <bossartn@amazon.com>
Date: Fri, 30 Mar 2018 16:34:40 +0000
Subject: [PATCH v2 2/2] Add skip-locked option to RangeVarGetRelidExtended().

---
 src/backend/catalog/namespace.c | 28 ++++++++++++++++++++++------
 src/include/catalog/namespace.h |  3 ++-
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index d3eef63d5e..55ac8b55d7 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) == 0 || (flags & RELID_SKIP_LOCKED) == 0);
+
 	/*
 	 * We check the catalog name and then ignore it.
 	 */
@@ -362,20 +372,24 @@ 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))
 		{
+			int			elevel = ((flags & RELID_SKIP_LOCKED) != 0) ? DEBUG1 : ERROR;
+
 			if (relation->schemaname)
-				ereport(ERROR,
+				ereport(elevel,
 						(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
 						 errmsg("could not obtain lock on relation \"%s.%s\"",
 								relation->schemaname, relation->relname)));
 			else
-				ereport(ERROR,
+				ereport(elevel,
 						(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
 						 errmsg("could not obtain lock on relation \"%s\"",
 								relation->relname)));
+
+			return InvalidOid;
 		}
 
 		/*
@@ -393,15 +407,17 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
 		oldRelId = relId;
 	}
 
-	if (!OidIsValid(relId) && !missing_ok)
+	if (!OidIsValid(relId))
 	{
+		int			elevel = missing_ok ? DEBUG1 : ERROR;
+
 		if (relation->schemaname)
-			ereport(ERROR,
+			ereport(elevel,
 					(errcode(ERRCODE_UNDEFINED_TABLE),
 					 errmsg("relation \"%s.%s\" does not exist",
 							relation->schemaname, relation->relname)));
 		else
-			ereport(ERROR,
+			ereport(elevel,
 					(errcode(ERRCODE_UNDEFINED_TABLE),
 					 errmsg("relation \"%s\" does not exist",
 							relation->relname)));
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 60f110b639..6347a97c53 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.16.2