Fix problems with incomplete attempt to prohibit OIDS with MVs.

Problem with assertion failure in restoring from pg_dump output
reported by Joachim Wieland.

Review and suggestions by Tom Lane and Robert Haas.
This commit is contained in:
Kevin Grittner 2013-03-22 13:27:34 -05:00
parent 4912385b56
commit 549dae0352
6 changed files with 32 additions and 6 deletions

View File

@ -44,6 +44,9 @@ CREATE [ UNLOGGED ] MATERIALIZED VIEW <replaceable>table_name</replaceable>
<command>CREATE MATERIALIZED VIEW</command> is similar to <command>CREATE MATERIALIZED VIEW</command> is similar to
<command>CREATE TABLE AS</>, except that it also remembers the query used <command>CREATE TABLE AS</>, except that it also remembers the query used
to initialize the view, so that it can be refreshed later upon demand. to initialize the view, so that it can be refreshed later upon demand.
A materialized view has many of the same properties as a table, but there
is no support for temporary materialized views or automatic generation of
OIDs.
</para> </para>
</refsect1> </refsect1>
@ -88,7 +91,9 @@ CREATE [ UNLOGGED ] MATERIALIZED VIEW <replaceable>table_name</replaceable>
This clause specifies optional storage parameters for the new This clause specifies optional storage parameters for the new
materialized view; see <xref linkend="sql-createtable-storage-parameters" materialized view; see <xref linkend="sql-createtable-storage-parameters"
endterm="sql-createtable-storage-parameters-title"> for more endterm="sql-createtable-storage-parameters-title"> for more
information. information. All parameters supported for <literal>CREATE
TABLE</literal> are also supported for <literal>CREATE MATERIALIZED
VIEW</literal> with the exception of <literal>OIDS</literal>.
See <xref linkend="sql-createtable"> for more information. See <xref linkend="sql-createtable"> for more information.
</para> </para>
</listitem> </listitem>

View File

@ -218,11 +218,15 @@ GetIntoRelEFlags(IntoClause *intoClause)
* because it doesn't have enough information to do so itself (since we * because it doesn't have enough information to do so itself (since we
* can't build the target relation until after ExecutorStart). * can't build the target relation until after ExecutorStart).
*/ */
if (interpretOidsOption(intoClause->options)) if (interpretOidsOption(intoClause->options, intoClause->relkind))
flags = EXEC_FLAG_WITH_OIDS; flags = EXEC_FLAG_WITH_OIDS;
else else
flags = EXEC_FLAG_WITHOUT_OIDS; flags = EXEC_FLAG_WITHOUT_OIDS;
Assert(intoClause->relkind != RELKIND_MATVIEW ||
(flags & (EXEC_FLAG_WITH_OIDS | EXEC_FLAG_WITHOUT_OIDS)) ==
EXEC_FLAG_WITHOUT_OIDS);
if (intoClause->skipData) if (intoClause->skipData)
flags |= EXEC_FLAG_WITH_NO_DATA; flags |= EXEC_FLAG_WITH_NO_DATA;

View File

@ -559,7 +559,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId)
*/ */
descriptor = BuildDescForRelation(schema); descriptor = BuildDescForRelation(schema);
localHasOids = interpretOidsOption(stmt->options); localHasOids = interpretOidsOption(stmt->options, relkind);
descriptor->tdhasoid = (localHasOids || parentOidCount > 0); descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
/* /*

View File

@ -243,9 +243,14 @@ interpretInhOption(InhOption inhOpt)
* table/result set should be created with OIDs. This needs to be done after * table/result set should be created with OIDs. This needs to be done after
* parsing the query string because the return value can depend upon the * parsing the query string because the return value can depend upon the
* default_with_oids GUC var. * default_with_oids GUC var.
*
* Materialized views are handled here rather than reloptions.c because that
* code explicitly punts checking for oids to here. We prohibit any explicit
* specification of the oids option for a materialized view, and indicate that
* oids are not needed if we don't get an error.
*/ */
bool bool
interpretOidsOption(List *defList) interpretOidsOption(List *defList, char relkind)
{ {
ListCell *cell; ListCell *cell;
@ -256,9 +261,19 @@ interpretOidsOption(List *defList)
if (def->defnamespace == NULL && if (def->defnamespace == NULL &&
pg_strcasecmp(def->defname, "oids") == 0) pg_strcasecmp(def->defname, "oids") == 0)
{
if (relkind == RELKIND_MATVIEW)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unrecognized parameter \"%s\"", "oids")));
return defGetBoolean(def); return defGetBoolean(def);
}
} }
if (relkind == RELKIND_MATVIEW)
return false;
/* OIDS option was not specified, so use default. */ /* OIDS option was not specified, so use default. */
return default_with_oids; return default_with_oids;
} }

View File

@ -199,11 +199,14 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
{ {
cxt.stmtType = "CREATE FOREIGN TABLE"; cxt.stmtType = "CREATE FOREIGN TABLE";
cxt.isforeign = true; cxt.isforeign = true;
cxt.hasoids = interpretOidsOption(stmt->options,
RELKIND_FOREIGN_TABLE);
} }
else else
{ {
cxt.stmtType = "CREATE TABLE"; cxt.stmtType = "CREATE TABLE";
cxt.isforeign = false; cxt.isforeign = false;
cxt.hasoids = interpretOidsOption(stmt->options, RELKIND_RELATION);
} }
cxt.relation = stmt->relation; cxt.relation = stmt->relation;
cxt.rel = NULL; cxt.rel = NULL;
@ -217,7 +220,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
cxt.blist = NIL; cxt.blist = NIL;
cxt.alist = NIL; cxt.alist = NIL;
cxt.pkey = NULL; cxt.pkey = NULL;
cxt.hasoids = interpretOidsOption(stmt->options);
Assert(!stmt->ofTypename || !stmt->inhRelations); /* grammar enforces */ Assert(!stmt->ofTypename || !stmt->inhRelations); /* grammar enforces */

View File

@ -20,7 +20,7 @@ extern void transformFromClause(ParseState *pstate, List *frmList);
extern int setTargetTable(ParseState *pstate, RangeVar *relation, extern int setTargetTable(ParseState *pstate, RangeVar *relation,
bool inh, bool alsoSource, AclMode requiredPerms); bool inh, bool alsoSource, AclMode requiredPerms);
extern bool interpretInhOption(InhOption inhOpt); extern bool interpretInhOption(InhOption inhOpt);
extern bool interpretOidsOption(List *defList); extern bool interpretOidsOption(List *defList, char relkind);
extern Node *transformWhereClause(ParseState *pstate, Node *clause, extern Node *transformWhereClause(ParseState *pstate, Node *clause,
ParseExprKind exprKind, const char *constructName); ParseExprKind exprKind, const char *constructName);