Combine options for RangeVarGetRelidExtended() into a flags argument.

A followup patch will add a SKIP_LOCKED option. To avoid introducing
evermore arguments, breaking existing callers each time, introduce a
flags argument. This'll no doubt break a few external users...

Also change the MISSING_OK behaviour so a DEBUG1 debug message is
emitted when a relation is not found.

Author: Nathan Bossart
Reviewed-By: Michael Paquier and Andres Freund
Discussion: https://postgr.es/m/20180306005349.b65whmvj7z6hbe2y@alap3.anarazel.de
This commit is contained in:
Andres Freund 2018-03-30 16:33:42 -07:00
parent 9a895462d9
commit d87510a524
12 changed files with 45 additions and 32 deletions

View File

@ -206,23 +206,25 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
* Given a RangeVar describing an existing relation, * Given a RangeVar describing an existing relation,
* select the proper namespace and look up the relation OID. * select the proper namespace and look up the relation OID.
* *
* If the schema or relation is not found, return InvalidOid if missing_ok * If the schema or relation is not found, return InvalidOid if flags contains
* = true, otherwise raise an error. * RVR_MISSING_OK, otherwise raise an error.
* *
* If nowait = true, throw an error if we'd have to wait for a lock. * If flags contains RVR_NOWAIT, throw an error if we'd have to wait for a
* lock.
* *
* Callback allows caller to check permissions or acquire additional locks * Callback allows caller to check permissions or acquire additional locks
* prior to grabbing the relation lock. * prior to grabbing the relation lock.
*/ */
Oid Oid
RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
bool missing_ok, bool nowait, uint32 flags,
RangeVarGetRelidCallback callback, void *callback_arg) RangeVarGetRelidCallback callback, void *callback_arg)
{ {
uint64 inval_count; uint64 inval_count;
Oid relId; Oid relId;
Oid oldRelId = InvalidOid; Oid oldRelId = InvalidOid;
bool retry = false; bool retry = false;
bool missing_ok = (flags & RVR_MISSING_OK) != 0;
/* /*
* We check the catalog name and then ignore it. * We check the catalog name and then ignore it.
@ -361,7 +363,7 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
*/ */
if (!OidIsValid(relId)) if (!OidIsValid(relId))
AcceptInvalidationMessages(); AcceptInvalidationMessages();
else if (!nowait) else if (!(flags & RVR_NOWAIT))
LockRelationOid(relId, lockmode); LockRelationOid(relId, lockmode);
else if (!ConditionalLockRelationOid(relId, lockmode)) else if (!ConditionalLockRelationOid(relId, lockmode))
{ {
@ -392,15 +394,17 @@ RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode,
oldRelId = relId; oldRelId = relId;
} }
if (!OidIsValid(relId) && !missing_ok) if (!OidIsValid(relId))
{ {
int elevel = missing_ok ? DEBUG1 : ERROR;
if (relation->schemaname) if (relation->schemaname)
ereport(ERROR, ereport(elevel,
(errcode(ERRCODE_UNDEFINED_TABLE), (errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s.%s\" does not exist", errmsg("relation \"%s.%s\" does not exist",
relation->schemaname, relation->relname))); relation->schemaname, relation->relname)));
else else
ereport(ERROR, ereport(elevel,
(errcode(ERRCODE_UNDEFINED_TABLE), (errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("relation \"%s\" does not exist", errmsg("relation \"%s\" does not exist",
relation->relname))); relation->relname)));

View File

@ -115,7 +115,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel)
/* Find, lock, and check permissions on the table */ /* Find, lock, and check permissions on the table */
tableOid = RangeVarGetRelidExtended(stmt->relation, tableOid = RangeVarGetRelidExtended(stmt->relation,
AccessExclusiveLock, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackOwnsTable, NULL); RangeVarCallbackOwnsTable, NULL);
rel = heap_open(tableOid, NoLock); rel = heap_open(tableOid, NoLock);

View File

@ -2091,7 +2091,7 @@ ReindexIndex(RangeVar *indexRelation, int options)
* used here must match the index lock obtained in reindex_index(). * used here must match the index lock obtained in reindex_index().
*/ */
indOid = RangeVarGetRelidExtended(indexRelation, AccessExclusiveLock, indOid = RangeVarGetRelidExtended(indexRelation, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackForReindexIndex, RangeVarCallbackForReindexIndex,
(void *) &heapOid); (void *) &heapOid);
@ -2183,7 +2183,7 @@ ReindexTable(RangeVar *relation, int options)
Oid heapOid; Oid heapOid;
/* The lock level used here should match reindex_relation(). */ /* The lock level used here should match reindex_relation(). */
heapOid = RangeVarGetRelidExtended(relation, ShareLock, false, false, heapOid = RangeVarGetRelidExtended(relation, ShareLock, 0,
RangeVarCallbackOwnsTable, NULL); RangeVarCallbackOwnsTable, NULL);
if (!reindex_relation(heapOid, if (!reindex_relation(heapOid,

View File

@ -61,8 +61,8 @@ LockTableCommand(LockStmt *lockstmt)
bool recurse = rv->inh; bool recurse = rv->inh;
Oid reloid; Oid reloid;
reloid = RangeVarGetRelidExtended(rv, lockstmt->mode, false, reloid = RangeVarGetRelidExtended(rv, lockstmt->mode,
lockstmt->nowait, lockstmt->nowait ? RVR_NOWAIT : 0,
RangeVarCallbackForLockTable, RangeVarCallbackForLockTable,
(void *) &lockstmt->mode); (void *) &lockstmt->mode);

View File

@ -161,7 +161,7 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
* Get a lock until end of transaction. * Get a lock until end of transaction.
*/ */
matviewOid = RangeVarGetRelidExtended(stmt->relation, matviewOid = RangeVarGetRelidExtended(stmt->relation,
lockmode, false, false, lockmode, 0,
RangeVarCallbackOwnsTable, NULL); RangeVarCallbackOwnsTable, NULL);
matviewRel = heap_open(matviewOid, NoLock); matviewRel = heap_open(matviewOid, NoLock);

View File

@ -743,7 +743,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
/* Get id of table. Also handles permissions checks. */ /* Get id of table. Also handles permissions checks. */
table_id = RangeVarGetRelidExtended(stmt->table, AccessExclusiveLock, table_id = RangeVarGetRelidExtended(stmt->table, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackForPolicy, RangeVarCallbackForPolicy,
(void *) stmt); (void *) stmt);
@ -915,7 +915,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
/* Get id of table. Also handles permissions checks. */ /* Get id of table. Also handles permissions checks. */
table_id = RangeVarGetRelidExtended(stmt->table, AccessExclusiveLock, table_id = RangeVarGetRelidExtended(stmt->table, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackForPolicy, RangeVarCallbackForPolicy,
(void *) stmt); (void *) stmt);
@ -1215,7 +1215,7 @@ rename_policy(RenameStmt *stmt)
/* Get id of table. Also handles permissions checks. */ /* Get id of table. Also handles permissions checks. */
table_id = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, table_id = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackForPolicy, RangeVarCallbackForPolicy,
(void *) stmt); (void *) stmt);

View File

@ -432,8 +432,7 @@ AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
/* Open and lock sequence, and check for ownership along the way. */ /* Open and lock sequence, and check for ownership along the way. */
relid = RangeVarGetRelidExtended(stmt->sequence, relid = RangeVarGetRelidExtended(stmt->sequence,
ShareRowExclusiveLock, ShareRowExclusiveLock,
stmt->missing_ok, stmt->missing_ok ? RVR_MISSING_OK : 0,
false,
RangeVarCallbackOwnsRelation, RangeVarCallbackOwnsRelation,
NULL); NULL);
if (relid == InvalidOid) if (relid == InvalidOid)

View File

@ -1159,8 +1159,7 @@ RemoveRelations(DropStmt *drop)
state.heapOid = InvalidOid; state.heapOid = InvalidOid;
state.partParentOid = InvalidOid; state.partParentOid = InvalidOid;
state.concurrent = drop->concurrent; state.concurrent = drop->concurrent;
relOid = RangeVarGetRelidExtended(rel, lockmode, true, relOid = RangeVarGetRelidExtended(rel, lockmode, RVR_MISSING_OK,
false,
RangeVarCallbackForDropRelation, RangeVarCallbackForDropRelation,
(void *) &state); (void *) &state);
@ -2793,7 +2792,7 @@ renameatt(RenameStmt *stmt)
/* lock level taken here should match renameatt_internal */ /* lock level taken here should match renameatt_internal */
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
stmt->missing_ok, false, stmt->missing_ok ? RVR_MISSING_OK : 0,
RangeVarCallbackForRenameAttribute, RangeVarCallbackForRenameAttribute,
NULL); NULL);
@ -2945,7 +2944,7 @@ RenameConstraint(RenameStmt *stmt)
{ {
/* lock level taken here should match rename_constraint_internal */ /* lock level taken here should match rename_constraint_internal */
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
stmt->missing_ok, false, stmt->missing_ok ? RVR_MISSING_OK : 0,
RangeVarCallbackForRenameAttribute, RangeVarCallbackForRenameAttribute,
NULL); NULL);
if (!OidIsValid(relid)) if (!OidIsValid(relid))
@ -2987,7 +2986,7 @@ RenameRelation(RenameStmt *stmt)
* escalation. * escalation.
*/ */
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
stmt->missing_ok, false, stmt->missing_ok ? RVR_MISSING_OK : 0,
RangeVarCallbackForAlterRelation, RangeVarCallbackForAlterRelation,
(void *) stmt); (void *) stmt);
@ -3146,7 +3145,8 @@ CheckTableNotInUse(Relation rel, const char *stmt)
Oid Oid
AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode) AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode)
{ {
return RangeVarGetRelidExtended(stmt->relation, lockmode, stmt->missing_ok, false, return RangeVarGetRelidExtended(stmt->relation, lockmode,
stmt->missing_ok ? RVR_MISSING_OK : 0,
RangeVarCallbackForAlterRelation, RangeVarCallbackForAlterRelation,
(void *) stmt); (void *) stmt);
} }
@ -12683,7 +12683,7 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt, Oid *oldschema)
ObjectAddress myself; ObjectAddress myself;
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
stmt->missing_ok, false, stmt->missing_ok ? RVR_MISSING_OK : 0,
RangeVarCallbackForAlterRelation, RangeVarCallbackForAlterRelation,
(void *) stmt); (void *) stmt);
@ -14613,7 +14613,7 @@ ATExecAttachPartitionIdx(List **wqueue, Relation parentIdx, RangeVar *name)
state.parentTblOid = parentIdx->rd_index->indrelid; state.parentTblOid = parentIdx->rd_index->indrelid;
state.lockedParentTbl = false; state.lockedParentTbl = false;
partIdxId = partIdxId =
RangeVarGetRelidExtended(name, AccessExclusiveLock, false, false, RangeVarGetRelidExtended(name, AccessExclusiveLock, 0,
RangeVarCallbackForAttachIndex, RangeVarCallbackForAttachIndex,
(void *) &state); (void *) &state);
/* Not there? */ /* Not there? */

View File

@ -1667,7 +1667,7 @@ renametrig(RenameStmt *stmt)
* release until end of transaction). * release until end of transaction).
*/ */
relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackForRenameTrigger, RangeVarCallbackForRenameTrigger,
NULL); NULL);

View File

@ -951,7 +951,7 @@ RenameRewriteRule(RangeVar *relation, const char *oldName,
* release until end of transaction). * release until end of transaction).
*/ */
relid = RangeVarGetRelidExtended(relation, AccessExclusiveLock, relid = RangeVarGetRelidExtended(relation, AccessExclusiveLock,
false, false, 0,
RangeVarCallbackForRenameRule, RangeVarCallbackForRenameRule,
NULL); NULL);

View File

@ -1305,7 +1305,7 @@ ProcessUtilitySlow(ParseState *pstate,
: ShareLock; : ShareLock;
relid = relid =
RangeVarGetRelidExtended(stmt->relation, lockmode, RangeVarGetRelidExtended(stmt->relation, lockmode,
false, false, 0,
RangeVarCallbackOwnsRelation, RangeVarCallbackOwnsRelation,
NULL); NULL);

View File

@ -47,14 +47,24 @@ typedef struct OverrideSearchPath
bool addTemp; /* implicitly prepend temp schema? */ bool addTemp; /* implicitly prepend temp schema? */
} OverrideSearchPath; } OverrideSearchPath;
/*
* Option flag bits for RangeVarGetRelidExtended().
*/
typedef enum RVROption
{
RVR_MISSING_OK = 1 << 0, /* don't error if relation doesn't exist */
RVR_NOWAIT = 1 << 1 /* error if relation cannot be locked */
} RVROption;
typedef void (*RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId, typedef void (*RangeVarGetRelidCallback) (const RangeVar *relation, Oid relId,
Oid oldRelId, void *callback_arg); Oid oldRelId, void *callback_arg);
#define RangeVarGetRelid(relation, lockmode, missing_ok) \ #define RangeVarGetRelid(relation, lockmode, missing_ok) \
RangeVarGetRelidExtended(relation, lockmode, missing_ok, false, NULL, NULL) RangeVarGetRelidExtended(relation, lockmode, \
(missing_ok) ? RVR_MISSING_OK : 0, NULL, NULL)
extern Oid RangeVarGetRelidExtended(const RangeVar *relation, extern Oid RangeVarGetRelidExtended(const RangeVar *relation,
LOCKMODE lockmode, bool missing_ok, bool nowait, LOCKMODE lockmode, uint32 flags,
RangeVarGetRelidCallback callback, RangeVarGetRelidCallback callback,
void *callback_arg); void *callback_arg);
extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation); extern Oid RangeVarGetCreationNamespace(const RangeVar *newRelation);