#include "commands/prepare.h"
#include "commands/tablecmds.h"
#include "commands/view.h"
+#include "miscadmin.h"
#include "parser/parse_clause.h"
#include "rewrite/rewriteHandler.h"
#include "storage/smgr.h"
{
Query *query = (Query *) stmt->query;
IntoClause *into = stmt->into;
+ bool is_matview = (into->viewQuery != NULL);
DestReceiver *dest;
+ Oid save_userid = InvalidOid;
+ int save_sec_context = 0;
+ int save_nestlevel = 0;
List *rewritten;
PlannedStmt *plan;
QueryDesc *queryDesc;
{
ExecuteStmt *estmt = (ExecuteStmt *) query->utilityStmt;
+ Assert(!is_matview); /* excluded by syntax */
ExecuteQuery(estmt, into, queryString, params, dest, completionTag);
return;
}
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.
+ */
+ if (is_matview)
+ {
+ GetUserIdAndSecContext(&save_userid, &save_sec_context);
+ SetUserIdAndSecContext(save_userid,
+ save_sec_context | SECURITY_RESTRICTED_OPERATION);
+ save_nestlevel = NewGUCNestLevel();
+ }
+
/*
* Parse analysis was done already, but we still have to run the rule
* rewriter. We do not do AcquireRewriteLocks: we assume the query either
FreeQueryDesc(queryDesc);
PopActiveSnapshot();
+
+ if (is_matview)
+ {
+ /* Roll back any GUC changes */
+ AtEOXact_GUC(false, save_nestlevel);
+
+ /* Restore userid and security context */
+ SetUserIdAndSecContext(save_userid, save_sec_context);
+ }
}
/*
RewriteRule *rule;
List *actions;
Query *dataQuery;
+ Oid save_userid;
+ int save_sec_context;
+ int save_nestlevel;
Oid tableSpace;
Oid OIDNewHeap;
DestReceiver *dest;
*/
CheckTableNotInUse(matviewRel, "REFRESH MATERIALIZED VIEW");
+ /*
+ * Switch to the owner's userid, so that any functions are run as that
+ * user. Also lock down security-restricted operations and arrange to
+ * make GUC variable changes local to this command.
+ */
+ GetUserIdAndSecContext(&save_userid, &save_sec_context);
+ SetUserIdAndSecContext(matviewRel->rd_rel->relowner,
+ save_sec_context | SECURITY_RESTRICTED_OPERATION);
+ save_nestlevel = NewGUCNestLevel();
+
/*
* Tentatively mark the matview as populated or not (this will roll back
* if we fail later).
RecentXmin, ReadNextMultiXactId());
RelationCacheInvalidateEntry(matviewOid);
+
+ /* Roll back any GUC changes */
+ AtEOXact_GUC(false, save_nestlevel);
+
+ /* Restore userid and security context */
+ SetUserIdAndSecContext(save_userid, save_sec_context);
}
/*