Describe the bug
views/__init__.py:360 sets a fixed relative suffix for locating the allowed-privileges list:
_ALLOWED_PRIVS_JSON = 'sql/allowed_privs.json'
used at views/__init__.py:289:
self.allowed_acls = render_template(
"/".join([self.template_path, self._ALLOWED_PRIVS_JSON])
)
For the default version bucket, the file genuinely lives under a sql/ subdirectory (e.g. templates/views/pg/default/sql/allowed_privs.json), so this resolves correctly. But for the PG17+ bucket, the file was added directly under the bucket directory, with no sql/ subdirectory:
web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/allowed_privs.json
web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/allowed_privs.json
web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/allowed_privs.json
web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/allowed_privs.json
So on PG17+/EPAS17+, render_template is asked for views/pg/17_plus/sql/allowed_privs.json, which doesn't exist. The failure is swallowed silently:
try:
self.allowed_acls = render_template(...)
self.allowed_acls = json.loads(self.allowed_acls)
except Exception as e:
current_app.logger.exception(e)
with no user-visible error — self.allowed_acls simply doesn't pick up the 17_plus list, which is the one that adds MAINTAIN ('m') for views and materialized views. The result: the MAINTAIN checkbox still appears in the Grant Wizard / privileges UI (added via table.ui.js, shared across table-like objects), the user can tick it, but because allowed_acls never validated/loaded it for views/mviews, _parse_privileges drops it and the generated GRANT statement never includes MAINTAIN.
To Reproduce
- Connect to a PostgreSQL 17+ (or EPAS 17+) server.
- Open a view or materialized view's Properties/Security tab.
- Grant a role the MAINTAIN privilege and save.
- Check the generated SQL / re-open the properties: MAINTAIN was not actually granted.
Expected behavior
Either move the 17_plus allowed_privs.json files under a sql/ subdirectory to match the default bucket's layout, or make _ALLOWED_PRIVS_JSON version-bucket-aware, so the 17+ allowed-privileges list (including MAINTAIN) is actually loaded.
Found while re-verifying #5597 (MAINTAIN privilege support) — the table-side implementation is correct and complete; this is a views/mviews-specific packaging bug in the same feature.
Describe the bug
views/__init__.py:360sets a fixed relative suffix for locating the allowed-privileges list:used at
views/__init__.py:289:For the
defaultversion bucket, the file genuinely lives under asql/subdirectory (e.g.templates/views/pg/default/sql/allowed_privs.json), so this resolves correctly. But for the PG17+ bucket, the file was added directly under the bucket directory, with nosql/subdirectory:So on PG17+/EPAS17+,
render_templateis asked forviews/pg/17_plus/sql/allowed_privs.json, which doesn't exist. The failure is swallowed silently:with no user-visible error —
self.allowed_aclssimply doesn't pick up the 17_plus list, which is the one that addsMAINTAIN('m') for views and materialized views. The result: the MAINTAIN checkbox still appears in the Grant Wizard / privileges UI (added viatable.ui.js, shared across table-like objects), the user can tick it, but becauseallowed_aclsnever validated/loaded it for views/mviews,_parse_privilegesdrops it and the generated GRANT statement never includes MAINTAIN.To Reproduce
Expected behavior
Either move the 17_plus
allowed_privs.jsonfiles under asql/subdirectory to match thedefaultbucket's layout, or make_ALLOWED_PRIVS_JSONversion-bucket-aware, so the 17+ allowed-privileges list (including MAINTAIN) is actually loaded.Found while re-verifying #5597 (MAINTAIN privilege support) — the table-side implementation is correct and complete; this is a views/mviews-specific packaging bug in the same feature.