aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/tablecmds.c14
-rw-r--r--src/backend/commands/typecmds.c3
-rw-r--r--src/backend/commands/view.c36
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