aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2011-07-03 17:34:47 -0400
committerRobert Haas <rhaas@postgresql.org>2011-07-03 17:34:47 -0400
commit5da79169d3e9f0fab47da03318c44075b3f824c5 (patch)
tree312828bda5b38877a6d9cd5c11061a339fee324a /src/backend/commands
parentacb9198b960caaa2fe9f31258116eaa7c1154093 (diff)
downloadpostgresql-5da79169d3e9f0fab47da03318c44075b3f824c5.tar.gz
postgresql-5da79169d3e9f0fab47da03318c44075b3f824c5.zip
Fix bugs in relpersistence handling during table creation.
Unlike the relistemp field which it replaced, relpersistence must be set correctly quite early during the table creation process, as we rely on it quite early on for a number of purposes, including security checks. Normally, this is set based on whether the user enters CREATE TABLE, CREATE UNLOGGED TABLE, or CREATE TEMPORARY TABLE, but a relation may also be made implicitly temporary by creating it in pg_temp. This patch fixes the handling of that case, and also disables creation of unlogged tables in temporary tablespace (such table indeed skip WAL-logging, but we reject an explicit specification) and creation of relations in the temporary schemas of other sessions (which is not very sensible, and didn't work right anyway). Report by Amit Khandekar.
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/tablecmds.c13
-rw-r--r--src/backend/commands/typecmds.c1
-rw-r--r--src/backend/commands/view.c27
3 files changed, 23 insertions, 18 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index cfc685b9499..a3a99d28806 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 3f3e0bce34d..85a7585c6c9 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 be681e3fd4f..b2381996586 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