diff --git a/doc/src/sgml/ref/create_materialized_view.sgml b/doc/src/sgml/ref/create_materialized_view.sgml index ed3bb4d3ae520103ca1867aa8f4993585d587ed9..a7e4e210eeb0ef20bb7ea046f5c72a36cc4ad880 100644 --- a/doc/src/sgml/ref/create_materialized_view.sgml +++ b/doc/src/sgml/ref/create_materialized_view.sgml @@ -44,6 +44,9 @@ CREATE [ UNLOGGED ] MATERIALIZED VIEW <replaceable>table_name</replaceable> <command>CREATE MATERIALIZED VIEW</command> is similar to <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. + 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> </refsect1> @@ -88,7 +91,9 @@ CREATE [ UNLOGGED ] MATERIALIZED VIEW <replaceable>table_name</replaceable> This clause specifies optional storage parameters for the new materialized view; see <xref linkend="sql-createtable-storage-parameters" 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. </para> </listitem> diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c index a3ff1d56c810c384cb42242403a29ba15566970f..06bbae5cc59c87bb33e20c35ab9e74a0d5391db6 100644 --- a/src/backend/commands/createas.c +++ b/src/backend/commands/createas.c @@ -218,11 +218,15 @@ GetIntoRelEFlags(IntoClause *intoClause) * because it doesn't have enough information to do so itself (since we * can't build the target relation until after ExecutorStart). */ - if (interpretOidsOption(intoClause->options)) + if (interpretOidsOption(intoClause->options, intoClause->relkind)) flags = EXEC_FLAG_WITH_OIDS; else 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) flags |= EXEC_FLAG_WITH_NO_DATA; diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 57cf0a07b5179e58f509ad6c4c1ca42db171c579..536d232dd41e26299a9be3641ebbbfdba858cf5f 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -559,7 +559,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId) */ descriptor = BuildDescForRelation(schema); - localHasOids = interpretOidsOption(stmt->options); + localHasOids = interpretOidsOption(stmt->options, relkind); descriptor->tdhasoid = (localHasOids || parentOidCount > 0); /* diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index b9655954cde32d9525e971b61a668822be040b49..78a4f13c711082de9c8341221042fb36e6b296a0 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -243,9 +243,14 @@ interpretInhOption(InhOption inhOpt) * 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 * 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 -interpretOidsOption(List *defList) +interpretOidsOption(List *defList, char relkind) { ListCell *cell; @@ -256,9 +261,19 @@ interpretOidsOption(List *defList) if (def->defnamespace == NULL && 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); + } } + if (relkind == RELKIND_MATVIEW) + return false; + /* OIDS option was not specified, so use default. */ return default_with_oids; } diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 4fdcf180fa448aea97801b2418fcb31d835f3a3d..0d2802a576a7b02675ac483e7285cdec80006714 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -199,11 +199,14 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) { cxt.stmtType = "CREATE FOREIGN TABLE"; cxt.isforeign = true; + cxt.hasoids = interpretOidsOption(stmt->options, + RELKIND_FOREIGN_TABLE); } else { cxt.stmtType = "CREATE TABLE"; cxt.isforeign = false; + cxt.hasoids = interpretOidsOption(stmt->options, RELKIND_RELATION); } cxt.relation = stmt->relation; cxt.rel = NULL; @@ -217,7 +220,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString) cxt.blist = NIL; cxt.alist = NIL; cxt.pkey = NULL; - cxt.hasoids = interpretOidsOption(stmt->options); Assert(!stmt->ofTypename || !stmt->inhRelations); /* grammar enforces */ diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h index 36318d125dd2255b05ed3f1fbad25daaa2fd9d21..0bccb1cd6486d70e79394d82b001945153d2a9c5 100644 --- a/src/include/parser/parse_clause.h +++ b/src/include/parser/parse_clause.h @@ -20,7 +20,7 @@ extern void transformFromClause(ParseState *pstate, List *frmList); extern int setTargetTable(ParseState *pstate, RangeVar *relation, bool inh, bool alsoSource, AclMode requiredPerms); extern bool interpretInhOption(InhOption inhOpt); -extern bool interpretOidsOption(List *defList); +extern bool interpretOidsOption(List *defList, char relkind); extern Node *transformWhereClause(ParseState *pstate, Node *clause, ParseExprKind exprKind, const char *constructName);