diff options
Diffstat (limited to 'src/backend/parser/analyze.c')
-rw-r--r-- | src/backend/parser/analyze.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 2a943f9c6a5..e5faf46a7a6 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -2132,27 +2132,53 @@ static Query * transformCreateTableAsStmt(ParseState *pstate, CreateTableAsStmt *stmt) { Query *result; + Query *query; - /* - * Set relkind in IntoClause based on statement relkind. These are - * different types, because the parser users the ObjectType enumeration - * and the executor uses RELKIND_* defines. - */ - switch (stmt->relkind) + /* transform contained query */ + query = transformStmt(pstate, stmt->query); + stmt->query = (Node *) query; + + /* additional work needed for CREATE MATERIALIZED VIEW */ + if (stmt->relkind == OBJECT_MATVIEW) { - case (OBJECT_TABLE): - stmt->into->relkind = RELKIND_RELATION; - break; - case (OBJECT_MATVIEW): - stmt->into->relkind = RELKIND_MATVIEW; - break; - default: - elog(ERROR, "unrecognized object relkind: %d", - (int) stmt->relkind); - } + /* + * Prohibit a data-modifying CTE in the query used to create a + * materialized view. It's not sufficiently clear what the user would + * want to happen if the MV is refreshed or incrementally maintained. + */ + if (query->hasModifyingCTE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialized views must not use data-modifying statements in WITH"))); - /* transform contained query */ - stmt->query = (Node *) transformStmt(pstate, stmt->query); + /* + * Check whether any temporary database objects are used in the + * creation query. It would be hard to refresh data or incrementally + * maintain it if a source disappeared. + */ + if (isQueryUsingTempRelation(query)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialized views must not use temporary tables or views"))); + + /* + * A materialized view would either need to save parameters for use in + * maintaining/loading the data or prohibit them entirely. The latter + * seems safer and more sane. + */ + if (query_contains_extern_params(query)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialized views may not be defined using bound parameters"))); + + /* + * At runtime, we'll need a copy of the parsed-but-not-rewritten Query + * for purposes of creating the view's ON SELECT rule. We stash that + * in the IntoClause because that's where intorel_startup() can + * conveniently get it from. + */ + stmt->into->viewQuery = copyObject(query); + } /* represent the command as a utility Query */ result = makeNode(Query); |