diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 41e9299..ce795a6 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -311,19 +311,6 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
 							newRelation->relname)));
 	}
 
-	if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
-	{
-		/* TEMP tables are created in our backend-local temp namespace */
-		if (newRelation->schemaname)
-			ereport(ERROR,
-					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
-				   errmsg("temporary tables cannot specify a schema name")));
-		/* Initialize temp namespace if first time through */
-		if (!OidIsValid(myTempNamespace))
-			InitTempTableNamespace();
-		return myTempNamespace;
-	}
-
 	if (newRelation->schemaname)
 	{
 		/* check for pg_temp alias */
@@ -338,6 +325,13 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
 		namespaceId = get_namespace_oid(newRelation->schemaname, false);
 		/* we do not check for USAGE rights here! */
 	}
+	else if (newRelation->relpersistence == RELPERSISTENCE_TEMP)
+	{
+		/* Initialize temp namespace if first time through */
+		if (!OidIsValid(myTempNamespace))
+			InitTempTableNamespace();
+		return myTempNamespace;
+	}
 	else
 	{
 		/* use the default creation namespace */
@@ -390,6 +384,43 @@ RangeVarGetAndCheckCreationNamespace(const RangeVar *newRelation)
 }
 
 /*
+ * Adjust the relpersistence for an about-to-be-created relation based on the
+ * creation namespace, and throw an error for invalid combinations.
+ */
+void
+RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid)
+{
+	switch (newRelation->relpersistence)
+	{
+		case RELPERSISTENCE_TEMP:
+			if (!isTempOrToastNamespace(nspid))
+			{
+				if (isAnyTempNamespace(nspid))
+					ereport(ERROR,
+							(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+							 errmsg("cannot create relations in temporary schemas of other sessions")));
+				else
+					ereport(ERROR,
+							(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+							 errmsg("cannot create temporary relation in non-temporary schema")));
+			}
+			break;
+		case RELPERSISTENCE_PERMANENT:
+			if (isTempOrToastNamespace(nspid))
+				newRelation->relpersistence = RELPERSISTENCE_TEMP;
+			else if (isAnyTempNamespace(nspid))
+				ereport(ERROR,
+						(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+						 errmsg("cannot create relations in temporary schemas of other sessions")));
+			break;
+		default:
+			ereport(ERROR,
+					(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
+					 errmsg("only temporary relations may be created in temporary schemas")));
+	}
+}
+
+/*
  * RelnameGetRelid
  *		Try to resolve an unqualified relation name.
  *		Returns OID if relation found in search path, else InvalidOid.
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index cfc685b..a3a99d2 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -432,6 +432,13 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 				 errmsg("constraints on foreign tables are not supported")));
 
 	/*
+	 * Look up the namespace in which we are supposed to create the relation,
+	 * and check we have permission to create there.
+	 */
+	namespaceId = RangeVarGetAndCheckCreationNamespace(stmt->relation);
+	RangeVarAdjustRelationPersistence(stmt->relation, namespaceId);
+
+	/*
 	 * Security check: disallow creating temp tables from security-restricted
 	 * code.  This is needed because calling code might not expect untrusted
 	 * tables to appear in pg_temp at the front of its search path.
@@ -443,12 +450,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
 				 errmsg("cannot create temporary table within security-restricted operation")));
 
 	/*
-	 * Look up the namespace in which we are supposed to create the relation,
-	 * and check we have permission to create there.
-	 */
-	namespaceId = RangeVarGetAndCheckCreationNamespace(stmt->relation);
-
-	/*
 	 * Select tablespace to use.  If not specified, use default tablespace
 	 * (which may in turn default to database's default).
 	 */
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 437d23a..e636ad9 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -1610,6 +1610,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
 	 * instead of below about a "relation".
 	 */
 	typeNamespace = RangeVarGetCreationNamespace(createStmt->relation);
+	RangeVarAdjustRelationPersistence(createStmt->relation, typeNamespace);
 	old_type_oid =
 		GetSysCacheOid2(TYPENAMENSP,
 						CStringGetDatum(createStmt->relation->relname),
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index be681e3..b238199 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -97,10 +97,10 @@ isViewOnTempTable_walker(Node *node, void *context)
  *---------------------------------------------------------------------
  */
 static Oid
-DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
+DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace,
+					  Oid namespaceId)
 {
-	Oid			viewOid,
-				namespaceId;
+	Oid			viewOid;
 	CreateStmt *createStmt = makeNode(CreateStmt);
 	List	   *attrList;
 	ListCell   *t;
@@ -160,7 +160,6 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
 	/*
 	 * Check to see if we want to replace an existing view.
 	 */
-	namespaceId = RangeVarGetCreationNamespace(relation);
 	viewOid = get_relname_relid(relation->relname, namespaceId);
 
 	if (OidIsValid(viewOid) && replace)
@@ -417,6 +416,7 @@ DefineView(ViewStmt *stmt, const char *queryString)
 {
 	Query	   *viewParse;
 	Oid			viewOid;
+	Oid			namespaceId;
 	RangeVar   *view;
 
 	/*
@@ -480,28 +480,31 @@ DefineView(ViewStmt *stmt, const char *queryString)
 							"names than columns")));
 	}
 
+	/* Unlogged views are not sensible. */
+	if (stmt->view->relpersistence == RELPERSISTENCE_UNLOGGED)
+		ereport(ERROR,
+				(errcode(ERRCODE_SYNTAX_ERROR),
+		errmsg("views cannot be unlogged because they do not have storage")));
+
 	/*
 	 * If the user didn't explicitly ask for a temporary view, check whether
 	 * we need one implicitly.	We allow TEMP to be inserted automatically as
 	 * long as the CREATE command is consistent with that --- no explicit
 	 * schema name.
 	 */
-	view = stmt->view;
+	view = copyObject(stmt->view);  /* don't corrupt original command */
 	if (view->relpersistence == RELPERSISTENCE_PERMANENT
 		&& isViewOnTempTable(viewParse))
 	{
-		view = copyObject(view);	/* don't corrupt original command */
 		view->relpersistence = RELPERSISTENCE_TEMP;
 		ereport(NOTICE,
 				(errmsg("view \"%s\" will be a temporary view",
 						view->relname)));
 	}
 
-	/* Unlogged views are not sensible. */
-	if (view->relpersistence == RELPERSISTENCE_UNLOGGED)
-		ereport(ERROR,
-				(errcode(ERRCODE_SYNTAX_ERROR),
-		errmsg("views cannot be unlogged because they do not have storage")));
+	/* Might also need to make it temporary if placed in temp schema. */
+	namespaceId = RangeVarGetCreationNamespace(view);
+	RangeVarAdjustRelationPersistence(view, namespaceId);
 
 	/*
 	 * Create the view relation
@@ -510,7 +513,7 @@ DefineView(ViewStmt *stmt, const char *queryString)
 	 * aborted.
 	 */
 	viewOid = DefineVirtualRelation(view, viewParse->targetList,
-									stmt->replace);
+									stmt->replace, namespaceId);
 
 	/*
 	 * The relation we have just created is not visible to any other commands
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 2f8deb4..eacd863 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -2414,6 +2414,13 @@ OpenIntoRel(QueryDesc *queryDesc)
 				 errmsg("ON COMMIT can only be used on temporary tables")));
 
 	/*
+	 * Find namespace to create in, check its permissions
+	 */
+	intoName = into->rel->relname;
+	namespaceId = RangeVarGetAndCheckCreationNamespace(into->rel);
+	RangeVarAdjustRelationPersistence(into->rel, namespaceId);
+
+	/*
 	 * Security check: disallow creating temp tables from security-restricted
 	 * code.  This is needed because calling code might not expect untrusted
 	 * tables to appear in pg_temp at the front of its search path.
@@ -2425,12 +2432,6 @@ OpenIntoRel(QueryDesc *queryDesc)
 				 errmsg("cannot create temporary table within security-restricted operation")));
 
 	/*
-	 * Find namespace to create in, check its permissions
-	 */
-	intoName = into->rel->relname;
-	namespaceId = RangeVarGetAndCheckCreationNamespace(into->rel);
-
-	/*
 	 * Select tablespace to use.  If not specified, use default tablespace
 	 * (which may in turn default to database's default).
 	 */
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index d40a963..1771fee 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -162,6 +162,7 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	 * possible.
 	 */
 	namespaceid = RangeVarGetAndCheckCreationNamespace(stmt->relation);
+	RangeVarAdjustRelationPersistence(stmt->relation, namespaceid);
 
 	/*
 	 * If the relation already exists and the user specified "IF NOT EXISTS",
@@ -374,7 +375,10 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 		if (cxt->rel)
 			snamespaceid = RelationGetNamespace(cxt->rel);
 		else
+		{
 			snamespaceid = RangeVarGetCreationNamespace(cxt->relation);
+			RangeVarAdjustRelationPersistence(cxt->relation, snamespaceid);
+		}
 		snamespace = get_namespace_name(snamespaceid);
 		sname = ChooseRelationName(cxt->relation->relname,
 								   column->colname,
diff --git a/src/include/catalog/namespace.h b/src/include/catalog/namespace.h
index 5360096..7e1e194 100644
--- a/src/include/catalog/namespace.h
+++ b/src/include/catalog/namespace.h
@@ -50,6 +50,7 @@ typedef struct OverrideSearchPath
 extern Oid	RangeVarGetRelid(const RangeVar *relation, bool failOK);
 extern Oid	RangeVarGetCreationNamespace(const RangeVar *newRelation);
 extern Oid	RangeVarGetAndCheckCreationNamespace(const RangeVar *newRelation);
+extern void RangeVarAdjustRelationPersistence(RangeVar *newRelation, Oid nspid);
 extern Oid	RelnameGetRelid(const char *relname);
 extern bool RelationIsVisible(Oid relid);
 
diff --git a/src/test/regress/expected/create_view.out b/src/test/regress/expected/create_view.out
index f2c0685..f9490a3 100644
--- a/src/test/regress/expected/create_view.out
+++ b/src/test/regress/expected/create_view.out
@@ -81,11 +81,11 @@ CREATE VIEW temp_view_test.v2 AS SELECT * FROM base_table;
 -- should fail
 CREATE VIEW temp_view_test.v3_temp AS SELECT * FROM temp_table;
 NOTICE:  view "v3_temp" will be a temporary view
-ERROR:  temporary tables cannot specify a schema name
+ERROR:  cannot create temporary relation in non-temporary schema
 -- should fail
 CREATE SCHEMA test_schema
     CREATE TEMP VIEW testview AS SELECT 1;
-ERROR:  temporary tables cannot specify a schema name
+ERROR:  cannot create temporary relation in non-temporary schema
 -- joins: if any of the join relations are temporary, the view
 -- should also be temporary
 -- should be non-temp