aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/createas.c
diff options
context:
space:
mode:
authorJeff Davis <jdavis@postgresql.org>2024-07-16 15:41:29 -0700
committerJeff Davis <jdavis@postgresql.org>2024-07-16 15:41:29 -0700
commit4b74ebf726d444ba820830cad986a1f92f724649 (patch)
tree7b985099966a2649debd6628f4f416baf8467108 /src/backend/commands/createas.c
parent0a8ca122e511884d98a640cb3302866b74638688 (diff)
downloadpostgresql-4b74ebf726d444ba820830cad986a1f92f724649.tar.gz
postgresql-4b74ebf726d444ba820830cad986a1f92f724649.zip
When creating materialized views, use REFRESH to load data.
Previously, CREATE MATERIALIZED VIEW ... WITH DATA populated the MV the same way as CREATE TABLE ... AS. Instead, reuse the REFRESH logic, which locks down security-restricted operations and restricts the search_path. This reduces the chance that a subsequent refresh will fail. Reported-by: Noah Misch Backpatch-through: 17 Discussion: https://postgr.es/m/20240630222344.db.nmisch@google.com
Diffstat (limited to 'src/backend/commands/createas.c')
-rw-r--r--src/backend/commands/createas.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 62050f4dc59..2c8a93b6e56 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -225,10 +225,8 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
Query *query = castNode(Query, stmt->query);
IntoClause *into = stmt->into;
bool is_matview = (into->viewQuery != NULL);
+ bool do_refresh = false;
DestReceiver *dest;
- Oid save_userid = InvalidOid;
- int save_sec_context = 0;
- int save_nestlevel = 0;
ObjectAddress address;
List *rewritten;
PlannedStmt *plan;
@@ -263,18 +261,13 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
Assert(query->commandType == CMD_SELECT);
/*
- * For materialized views, lock down security-restricted operations and
- * arrange to make GUC variable changes local to this command. This is
- * not necessary for security, but this keeps the behavior similar to
- * REFRESH MATERIALIZED VIEW. Otherwise, one could create a materialized
- * view not possible to refresh.
+ * For materialized views, always skip data during table creation, and use
+ * REFRESH instead (see below).
*/
if (is_matview)
{
- GetUserIdAndSecContext(&save_userid, &save_sec_context);
- SetUserIdAndSecContext(save_userid,
- save_sec_context | SECURITY_RESTRICTED_OPERATION);
- save_nestlevel = NewGUCNestLevel();
+ do_refresh = !into->skipData;
+ into->skipData = true;
}
if (into->skipData)
@@ -346,13 +339,18 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
PopActiveSnapshot();
}
- if (is_matview)
+ /*
+ * For materialized views, reuse the REFRESH logic, which locks down
+ * security-restricted operations and restricts the search_path. This
+ * reduces the chance that a subsequent refresh will fail.
+ */
+ if (do_refresh)
{
- /* Roll back any GUC changes */
- AtEOXact_GUC(false, save_nestlevel);
+ RefreshMatViewByOid(address.objectId, false, false,
+ pstate->p_sourcetext, NULL, qc);
- /* Restore userid and security context */
- SetUserIdAndSecContext(save_userid, save_sec_context);
+ if (qc)
+ qc->commandTag = CMDTAG_SELECT;
}
return address;