diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c index 19b98fb..9d639f0 100644 --- a/contrib/dblink/dblink.c +++ b/contrib/dblink/dblink.c @@ -2044,7 +2044,7 @@ get_rel_from_relname(text *relname_text, LOCKMODE lockmode, AclMode aclmode) AclResult aclresult; relvar = makeRangeVarFromNameList(textToQualifiedNameList(relname_text)); - rel = heap_openrv(relvar, lockmode); + rel = heap_openrv(relvar, lockmode, false); aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), aclmode); diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c index ef27cd4..9c535f9 100644 --- a/contrib/pageinspect/btreefuncs.c +++ b/contrib/pageinspect/btreefuncs.c @@ -184,7 +184,7 @@ bt_page_stats(PG_FUNCTION_ARGS) (errmsg("must be superuser to use pageinspect functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); if (!IS_INDEX(rel) || !IS_BTREE(rel)) elog(ERROR, "relation \"%s\" is not a btree index", @@ -302,7 +302,7 @@ bt_page_items(PG_FUNCTION_ARGS) fctx = SRF_FIRSTCALL_INIT(); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); if (!IS_INDEX(rel) || !IS_BTREE(rel)) elog(ERROR, "relation \"%s\" is not a btree index", @@ -451,7 +451,7 @@ bt_metap(PG_FUNCTION_ARGS) (errmsg("must be superuser to use pageinspect functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); if (!IS_INDEX(rel) || !IS_BTREE(rel)) elog(ERROR, "relation \"%s\" is not a btree index", diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 2607576..427e916 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -106,7 +106,7 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno) (errmsg("must be superuser to use raw functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); /* Check that this relation has storage */ if (rel->rd_rel->relkind == RELKIND_VIEW) diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c index 302bb5c..72c150c 100644 --- a/contrib/pgrowlocks/pgrowlocks.c +++ b/contrib/pgrowlocks/pgrowlocks.c @@ -90,7 +90,7 @@ pgrowlocks(PG_FUNCTION_ARGS) relname = PG_GETARG_TEXT_P(0); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = heap_openrv(relrv, AccessShareLock); + rel = heap_openrv(relrv, AccessShareLock, false); /* check permissions: must have SELECT on table */ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c index fd2cc92..7900eae 100644 --- a/contrib/pgstattuple/pgstatindex.c +++ b/contrib/pgstattuple/pgstatindex.c @@ -101,7 +101,7 @@ pgstatindex(PG_FUNCTION_ARGS) (errmsg("must be superuser to use pgstattuple functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); if (!IS_INDEX(rel) || !IS_BTREE(rel)) elog(ERROR, "relation \"%s\" is not a btree index", @@ -270,7 +270,7 @@ pg_relpages(PG_FUNCTION_ARGS) (errmsg("must be superuser to use pgstattuple functions")))); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); /* note: this will work OK on non-local temp tables */ diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c index e5ddd87..654af20 100644 --- a/contrib/pgstattuple/pgstattuple.c +++ b/contrib/pgstattuple/pgstattuple.c @@ -169,7 +169,7 @@ pgstattuple(PG_FUNCTION_ARGS) /* open relation */ relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); + rel = relation_openrv(relrv, AccessShareLock, false); PG_RETURN_DATUM(pgstat_relation(rel, fcinfo)); } diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 7bb4a87..f515f50 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -974,45 +974,14 @@ try_relation_open(Oid relationId, LOCKMODE lockmode) * relation_openrv - open any relation specified by a RangeVar * * Same as relation_open, but the relation is specified by a RangeVar. - * ---------------- - */ -Relation -relation_openrv(const RangeVar *relation, LOCKMODE lockmode) -{ - Oid relOid; - - /* - * Check for shared-cache-inval messages before trying to open the - * relation. This is needed to cover the case where the name identifies a - * rel that has been dropped and recreated since the start of our - * transaction: if we don't flush the old syscache entry then we'll latch - * onto that entry and suffer an error when we do RelationIdGetRelation. - * Note that relation_open does not need to do this, since a relation's - * OID never changes. - * - * We skip this if asked for NoLock, on the assumption that the caller has - * already ensured some appropriate lock is held. - */ - if (lockmode != NoLock) - AcceptInvalidationMessages(); - - /* Look up the appropriate relation using namespace search */ - relOid = RangeVarGetRelid(relation, false); - - /* Let relation_open do the rest */ - return relation_open(relOid, lockmode); -} - -/* ---------------- - * try_relation_openrv - open any relation specified by a RangeVar * - * Same as relation_openrv, but return NULL instead of failing for + * If missing_ok is true, return NULL instead of failing for * relation-not-found. (Note that some other causes, such as * permissions problems, will still result in an ereport.) * ---------------- */ Relation -try_relation_openrv(const RangeVar *relation, LOCKMODE lockmode) +relation_openrv(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok) { Oid relOid; @@ -1032,7 +1001,7 @@ try_relation_openrv(const RangeVar *relation, LOCKMODE lockmode) AcceptInvalidationMessages(); /* Look up the appropriate relation using namespace search */ - relOid = RangeVarGetRelid(relation, true); + relOid = RangeVarGetRelid(relation, missing_ok); /* Return NULL on not-found */ if (!OidIsValid(relOid)) @@ -1104,39 +1073,11 @@ heap_open(Oid relationId, LOCKMODE lockmode) * ---------------- */ Relation -heap_openrv(const RangeVar *relation, LOCKMODE lockmode) -{ - Relation r; - - r = relation_openrv(relation, lockmode); - - if (r->rd_rel->relkind == RELKIND_INDEX) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an index", - RelationGetRelationName(r)))); - else if (r->rd_rel->relkind == RELKIND_COMPOSITE_TYPE) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is a composite type", - RelationGetRelationName(r)))); - - return r; -} - -/* ---------------- - * try_heap_openrv - open a heap relation specified - * by a RangeVar node - * - * As above, but return NULL instead of failing for relation-not-found. - * ---------------- - */ -Relation -try_heap_openrv(const RangeVar *relation, LOCKMODE lockmode) +heap_openrv(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok) { Relation r; - r = try_relation_openrv(relation, lockmode); + r = relation_openrv(relation, lockmode, missing_ok); if (r) { diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index fc093cc..4533648 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -623,7 +623,7 @@ boot_openrel(char *relname) elog(DEBUG4, "open relation %s, attrsize %d", relname, (int) ATTRIBUTE_FIXED_PART_SIZE); - boot_reldesc = heap_openrv(makeRangeVar(NULL, relname, -1), NoLock); + boot_reldesc = heap_openrv(makeRangeVar(NULL, relname, -1), NoLock, false); numattr = boot_reldesc->rd_rel->relnatts; for (i = 0; i < numattr; i++) { diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index bf25091..b8a4cc3 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -381,7 +381,8 @@ get_relation_by_qualified_name(ObjectType objtype, List *objname, { Relation relation; - relation = relation_openrv(makeRangeVarFromNameList(objname), lockmode); + relation = relation_openrv(makeRangeVarFromNameList(objname), lockmode, + false); switch (objtype) { case OBJECT_INDEX: @@ -473,7 +474,7 @@ get_object_address_relobject(ObjectType objtype, List *objname, Relation *relp) /* Extract relation name and open relation. */ relname = list_truncate(list_copy(objname), nnames - 1); relation = heap_openrv(makeRangeVarFromNameList(relname), - AccessShareLock); + AccessShareLock, false); reloid = RelationGetRelid(relation); switch (objtype) @@ -523,7 +524,8 @@ get_object_address_attribute(ObjectType objtype, List *objname, /* Extract relation name and open relation. */ attname = strVal(lfirst(list_tail(objname))); relname = list_truncate(list_copy(objname), list_length(objname) - 1); - relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode); + relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode, + false); reloid = RelationGetRelid(relation); /* Look up attribute and construct return value. */ diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index b059f9d..6634480 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -81,7 +81,8 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid) { Relation rel; - rel = heap_openrv(makeRangeVar(NULL, relName, -1), AccessExclusiveLock); + rel = heap_openrv(makeRangeVar(NULL, relName, -1), AccessExclusiveLock, + false); /* Note: during bootstrap may see uncataloged relation */ if (rel->rd_rel->relkind != RELKIND_RELATION && diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c index 9a7649b..cb00369 100644 --- a/src/backend/commands/cluster.c +++ b/src/backend/commands/cluster.c @@ -115,7 +115,7 @@ cluster(ClusterStmt *stmt, bool isTopLevel) Relation rel; /* Find and lock the table */ - rel = heap_openrv(stmt->relation, AccessExclusiveLock); + rel = heap_openrv(stmt->relation, AccessExclusiveLock, false); tableOid = RelationGetRelid(rel); diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 5742903..4eaaebd 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -758,7 +758,8 @@ DoCopy(const CopyStmt *stmt, const char *queryString) /* Open and lock the relation, using the appropriate lock type. */ rel = heap_openrv(stmt->relation, - (is_from ? RowExclusiveLock : AccessShareLock)); + (is_from ? RowExclusiveLock : AccessShareLock), + false); rte = makeNode(RangeTblEntry); rte->rtekind = RTE_RELATION; diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index b7c021d..f59e4dd 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -175,7 +175,8 @@ DefineIndex(RangeVar *heapRelation, * (but not VACUUM). */ rel = heap_openrv(heapRelation, - (concurrent ? ShareUpdateExclusiveLock : ShareLock)); + (concurrent ? ShareUpdateExclusiveLock : ShareLock), + false); relationId = RelationGetRelid(rel); namespaceId = RelationGetNamespace(rel); @@ -505,7 +506,7 @@ DefineIndex(RangeVar *heapRelation, */ /* Open and lock the parent heap relation */ - rel = heap_openrv(heapRelation, ShareUpdateExclusiveLock); + rel = heap_openrv(heapRelation, ShareUpdateExclusiveLock, false); /* And the target index relation */ indexRelation = index_open(indexRelationId, RowExclusiveLock); diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index be04177..a5b407c 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1392,7 +1392,7 @@ process_owned_by(Relation seqrel, List *owned_by) /* Open and lock rel to ensure it won't go away meanwhile */ rel = makeRangeVarFromNameList(relname); - tablerel = relation_openrv(rel, AccessShareLock); + tablerel = relation_openrv(rel, AccessShareLock, false); /* Must be a regular table */ if (tablerel->rd_rel->relkind != RELKIND_RELATION) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index b2ba11c..afd066f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -862,7 +862,7 @@ ExecuteTruncate(TruncateStmt *stmt) bool recurse = interpretInhOption(rv->inhOpt); Oid myrelid; - rel = heap_openrv(rv, AccessExclusiveLock); + rel = heap_openrv(rv, AccessExclusiveLock, false); myrelid = RelationGetRelid(rel); /* don't throw error for "TRUNCATE foo, foo" */ if (list_member_oid(relids, myrelid)) @@ -1346,7 +1346,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence, * parent's relhassubclass field, leading to a "tuple concurrently * updated" error. */ - relation = heap_openrv(parent, ShareUpdateExclusiveLock); + relation = heap_openrv(parent, ShareUpdateExclusiveLock, false); if (relation->rd_rel->relkind != RELKIND_RELATION) ereport(ERROR, @@ -2458,7 +2458,7 @@ AlterTable(AlterTableStmt *stmt) /* * Acquire same level of lock as already acquired during parsing. */ - rel = relation_openrv(stmt->relation, lockmode); + rel = relation_openrv(stmt->relation, lockmode, false); CheckTableNotInUse(rel, "ALTER TABLE"); @@ -5481,7 +5481,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, Oid indexOid; Oid constrOid; - pkrel = heap_openrv(fkconstraint->pktable, lockmode); + pkrel = heap_openrv(fkconstraint->pktable, lockmode, false); /* * Validity checks (permission checks wait till we have the column @@ -7270,7 +7270,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode) IndexStmt *stmt = (IndexStmt *) stm; AlterTableCmd *newcmd; - rel = relation_openrv(stmt->relation, lockmode); + rel = relation_openrv(stmt->relation, lockmode, false); tab = ATGetQueueEntry(wqueue, rel); newcmd = makeNode(AlterTableCmd); newcmd->subtype = AT_ReAddIndex; @@ -7285,7 +7285,7 @@ ATPostAlterTypeParse(char *cmd, List **wqueue, LOCKMODE lockmode) AlterTableStmt *stmt = (AlterTableStmt *) stm; ListCell *lcmd; - rel = relation_openrv(stmt->relation, lockmode); + rel = relation_openrv(stmt->relation, lockmode, false); tab = ATGetQueueEntry(wqueue, rel); foreach(lcmd, stmt->cmds) { @@ -8068,7 +8068,7 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode) * A self-exclusive lock is needed here. See the similar case in * MergeAttributes() for a full explanation. */ - parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock); + parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock, false); /* * Must be owner of both parent and child -- child was checked by @@ -8442,7 +8442,7 @@ ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode) * TABLE doesn't lock parent tables at all. We need some lock since we'll * be inspecting the parent's schema. */ - parent_rel = heap_openrv(parent, AccessShareLock); + parent_rel = heap_openrv(parent, AccessShareLock, false); /* * We don't bother to check ownership of the parent table --- ownership of @@ -8915,7 +8915,7 @@ AlterTableNamespace(RangeVar *relation, const char *newschema, Oid nspOid; Relation classRel; - rel = relation_openrv(relation, lockmode); + rel = relation_openrv(relation, lockmode, false); relid = RelationGetRelid(rel); oldNspOid = RelationGetNamespace(rel); diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 798d8a8..5b3a23c 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -150,7 +150,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, * triggers we would need to take an AccessExclusiveLock to add one of * those, just as we do with ON SELECT rules. */ - rel = heap_openrv(stmt->relation, ShareRowExclusiveLock); + rel = heap_openrv(stmt->relation, ShareRowExclusiveLock, false); /* * Triggers must be on tables or views, and there are additional diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 5359e69..3134882 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -826,7 +826,7 @@ parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockmode) ParseCallbackState pcbstate; setup_parser_errposition_callback(&pcbstate, pstate, relation->location); - rel = try_heap_openrv(relation, lockmode); + rel = heap_openrv(relation, lockmode, true); if (rel == NULL) { if (relation->schemaname) diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 8744654..4efab09 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -1663,7 +1663,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) int count; Assert(IsA(inh, RangeVar)); - rel = heap_openrv(inh, AccessShareLock); + rel = heap_openrv(inh, AccessShareLock, false); if (rel->rd_rel->relkind != RELKIND_RELATION) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), @@ -1837,7 +1837,8 @@ transformIndexStmt(IndexStmt *stmt, const char *queryString) * already hold a higher lock. */ rel = heap_openrv(stmt->relation, - (stmt->concurrent ? ShareUpdateExclusiveLock : ShareLock)); + (stmt->concurrent ? ShareUpdateExclusiveLock : ShareLock), + false); /* Set up pstate */ pstate = make_parsestate(NULL); @@ -1935,7 +1936,7 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString, * DefineQueryRewrite(), and we don't want to grab a lesser lock * beforehand. */ - rel = heap_openrv(stmt->relation, AccessExclusiveLock); + rel = heap_openrv(stmt->relation, AccessExclusiveLock, false); /* Set up pstate */ pstate = make_parsestate(NULL); @@ -2259,7 +2260,7 @@ transformAlterTableStmt(AlterTableStmt *stmt, const char *queryString) * new commands we add after this must not upgrade the lock level * requested here. */ - rel = relation_openrv(stmt->relation, lockmode); + rel = relation_openrv(stmt->relation, lockmode, false); /* Set up pstate and CreateStmtContext */ pstate = make_parsestate(NULL); diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c index 69e89b8..32f6da5 100644 --- a/src/backend/utils/adt/tid.c +++ b/src/backend/utils/adt/tid.c @@ -370,7 +370,7 @@ currtid_byrelname(PG_FUNCTION_ARGS) AclResult aclresult; relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = heap_openrv(relrv, AccessShareLock); + rel = heap_openrv(relrv, AccessShareLock, false); aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_SELECT); diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c index aa249fa..a4c5510 100644 --- a/src/backend/utils/fmgr/funcapi.c +++ b/src/backend/utils/fmgr/funcapi.c @@ -1160,7 +1160,7 @@ RelationNameGetTupleDesc(const char *relname) /* Open relation and copy the tuple description */ relname_list = stringToQualifiedNameList(relname); relvar = makeRangeVarFromNameList(relname_list); - rel = relation_openrv(relvar, AccessShareLock); + rel = relation_openrv(relvar, AccessShareLock, false); tupdesc = CreateTupleDescCopy(RelationGetDescr(rel)); relation_close(rel, AccessShareLock); diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index fc65761..5391e86 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -49,13 +49,13 @@ typedef enum /* in heap/heapam.c */ extern Relation relation_open(Oid relationId, LOCKMODE lockmode); extern Relation try_relation_open(Oid relationId, LOCKMODE lockmode); -extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode); -extern Relation try_relation_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok); extern void relation_close(Relation relation, LOCKMODE lockmode); extern Relation heap_open(Oid relationId, LOCKMODE lockmode); -extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode); -extern Relation try_heap_openrv(const RangeVar *relation, LOCKMODE lockmode); +extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode, + bool missing_ok); #define heap_close(r,l) relation_close(r,l) diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c index 7b952b2..e89c485 100644 --- a/src/pl/tcl/pltcl.c +++ b/src/pl/tcl/pltcl.c @@ -493,8 +493,8 @@ pltcl_init_load_unknown(Tcl_Interp *interp) * This is for backwards compatibility. To ensure that the table * is trustworthy, we require it to be owned by a superuser. ************************************************************/ - pmrel = try_relation_openrv(makeRangeVar(NULL, "pltcl_modules", -1), - AccessShareLock); + pmrel = relation_openrv(makeRangeVar(NULL, "pltcl_modules", -1), + AccessShareLock, true); if (pmrel == NULL) return; /* must be table or view, else ignore */