Thread
-
Re: [Patch] Add WHERE clause support to REFRESH MATERIALIZED VIEW
Adam Brusselback <adambrusselback@gmail.com> — 2026-05-29T02:53:15Z
Hi Zsolt, and hackers, On the privilege escalation: Yup, that isn't good. Thank you for catching that. In both paths the predicate is concatenated directly into the SQL that evaluates the view, e.g. in refresh_by_direct_modification: SELECT * FROM (<view definition>) mv WHERE (<predicate>) and in refresh_by_match_merge: SELECT ctid, * FROM <matview> WHERE (<predicate>) There's one plan, executed under one userid. I can't run the (<view definition>) subquery as the owner and the WHERE (<predicate>) as the invoker, SPI executes the whole statement in whatever security context is active when it runs. So the predicate runs as the owner. The levers left are what the predicate may contain and who may run it. Here is what I was thinking: - Predicate functions all leakproof: allow for anyone with the privilege to refresh today (MAINTAIN or owner). A leakproof predicate in owner context can't leak the owner's data or do anything the invoker couldn't, so nothing escalates. - Predicate contains a non-leakproof function: require ownership (or superuser). Invoker and owner are then the same trust domain, so owner-context execution doesn't escalate. This keeps MAINTAIN working for the common case, predicates over columns with built-in operators. The tightening only hits custom non-leakproof predicate functions. If anyone else has better ideas, i'm all ears. Your second issue is due to a missing PG_TRY around the OpenMatViewIncrementalMaintenance()/Close pair in the direct-modification path (the match/merge site already handles it). An error between open and close goes past the close and leaves matview_maintenance_depth above zero for the session, which is what lets plain DELETE/INSERT through afterward. Will fix. Thanks, Adam