diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/tablecmds.c | 14 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 3 | ||||
-rw-r--r-- | src/backend/commands/view.c | 36 |
3 files changed, 26 insertions, 27 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index c37301671e4..d0843b2f588 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -451,10 +451,12 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) /* * Look up the namespace in which we are supposed to create the relation, - * and check we have permission to create there. + * check we have permission to create there, lock it against concurrent + * drop, and mark stmt->relation as RELPERSISTENCE_TEMP if a temporary + * namespace is selected. */ - namespaceId = RangeVarGetAndCheckCreationNamespace(stmt->relation); - RangeVarAdjustRelationPersistence(stmt->relation, namespaceId); + namespaceId = + RangeVarGetAndCheckCreationNamespace(stmt->relation, NoLock, NULL); /* * Security check: disallow creating temp tables from security-restricted @@ -9417,6 +9419,7 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt) Oid oldNspOid; Oid nspOid; Relation classRel; + RangeVar *newrv; relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock, false, false, @@ -9441,8 +9444,9 @@ AlterTableNamespace(AlterObjectSchemaStmt *stmt) get_rel_name(tableId)))); } - /* get schema OID and check its permissions */ - nspOid = LookupCreationNamespace(stmt->newschema); + /* Get and lock schema OID and check its permissions. */ + newrv = makeRangeVar(stmt->newschema, RelationGetRelationName(rel), -1); + nspOid = RangeVarGetAndCheckCreationNamespace(newrv, NoLock, NULL); /* common checks on switching namespaces */ CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid); diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 0f8af31feef..0043bf1fee2 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -2005,7 +2005,8 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist) * check is here mainly to get a better error message about a "type" * instead of below about a "relation". */ - typeNamespace = RangeVarGetCreationNamespace(createStmt->relation); + typeNamespace = RangeVarGetAndCheckCreationNamespace(createStmt->relation, + NoLock, NULL); RangeVarAdjustRelationPersistence(createStmt->relation, typeNamespace); old_type_oid = GetSysCacheOid2(TYPENAMENSP, diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index ff9c44908a3..c3520ae03c6 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -98,10 +98,12 @@ isViewOnTempTable_walker(Node *node, void *context) *--------------------------------------------------------------------- */ static Oid -DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace, - Oid namespaceId, List *options) +DefineVirtualRelation(RangeVar *relation, List *tlist, bool replace, + List *options) { Oid viewOid; + Oid namespaceId; + LOCKMODE lockmode; CreateStmt *createStmt = makeNode(CreateStmt); List *attrList; ListCell *t; @@ -159,9 +161,14 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace, errmsg("view must have at least one column"))); /* - * Check to see if we want to replace an existing view. + * Look up, check permissions on, and lock the creation namespace; also + * check for a preexisting view with the same name. This will also set + * relation->relpersistence to RELPERSISTENCE_TEMP if the selected + * namespace is temporary. */ - viewOid = get_relname_relid(relation->relname, namespaceId); + lockmode = replace ? AccessExclusiveLock : NoLock; + namespaceId = + RangeVarGetAndCheckCreationNamespace(relation, lockmode, &viewOid); if (OidIsValid(viewOid) && replace) { @@ -170,24 +177,16 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace, List *atcmds = NIL; AlterTableCmd *atcmd; - /* - * Yes. Get exclusive lock on the existing view ... - */ - rel = relation_open(viewOid, AccessExclusiveLock); + /* Relation is already locked, but we must build a relcache entry. */ + rel = relation_open(viewOid, NoLock); - /* - * Make sure it *is* a view, and do permissions checks. - */ + /* Make sure it *is* a view. */ if (rel->rd_rel->relkind != RELKIND_VIEW) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a view", RelationGetRelationName(rel)))); - if (!pg_class_ownercheck(viewOid, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, - RelationGetRelationName(rel)); - /* Also check it's not in use already */ CheckTableNotInUse(rel, "CREATE OR REPLACE VIEW"); @@ -428,7 +427,6 @@ DefineView(ViewStmt *stmt, const char *queryString) { Query *viewParse; Oid viewOid; - Oid namespaceId; RangeVar *view; /* @@ -514,10 +512,6 @@ DefineView(ViewStmt *stmt, const char *queryString) view->relname))); } - /* Might also need to make it temporary if placed in temp schema. */ - namespaceId = RangeVarGetCreationNamespace(view); - RangeVarAdjustRelationPersistence(view, namespaceId); - /* * Create the view relation * @@ -525,7 +519,7 @@ DefineView(ViewStmt *stmt, const char *queryString) * aborted. */ viewOid = DefineVirtualRelation(view, viewParse->targetList, - stmt->replace, namespaceId, stmt->options); + stmt->replace, stmt->options); /* * The relation we have just created is not visible to any other commands |