1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-20 15:22:23 +03:00

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.
This commit is contained in:
Robert Haas
2011-07-03 17:34:47 -04:00
parent acb9198b96
commit 5da79169d3
8 changed files with 81 additions and 39 deletions

View File

@ -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