From ffed645c6a033171c1374fc0d6d37cca686d345e Mon Sep 17 00:00:00 2001 From: Dave Page Date: Wed, 26 Aug 2026 15:12:39 +0100 Subject: [PATCH 1/3] Fix MAINTAIN privilege silently dropped for views/mviews on PG17+ allowed_privs.json for the 17_plus bucket lived directly under the bucket directory instead of under a sql/ subdirectory like every other bucket (including default), so render_template() looked for views/pg/17_plus/sql/allowed_privs.json, didn't find it, and silently fell back to the default bucket's list - which predates MAINTAIN and lacks 'm'. Moved the four affected files (views/mviews x pg/ppas) to match the default bucket's layout. Closes #10350 --- .../pg/17_plus/{ => sql}/allowed_privs.json | 0 .../ppas/17_plus/{ => sql}/allowed_privs.json | 0 .../pg/17_plus/{ => sql}/allowed_privs.json | 0 .../ppas/17_plus/{ => sql}/allowed_privs.json | 0 .../tests/test_allowed_privs_json_path.py | 54 +++++++++++++++++++ 5 files changed, 54 insertions(+) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/{ => sql}/allowed_privs.json (100%) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/{ => sql}/allowed_privs.json (100%) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/{ => sql}/allowed_privs.json (100%) rename web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/{ => sql}/allowed_privs.json (100%) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/pg/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/mviews/ppas/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/pg/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/allowed_privs.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/sql/allowed_privs.json similarity index 100% rename from web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/allowed_privs.json rename to web/pgadmin/browser/server_groups/servers/databases/schemas/views/templates/views/ppas/17_plus/sql/allowed_privs.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py new file mode 100644 index 00000000000..cc036ee894f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py @@ -0,0 +1,54 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2026, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""Verify that the PG17+ allowed_privs.json for views/materialized views +resolves via the versioned template loader (issue #10350). It previously +lived directly under the 17_plus bucket instead of under a sql/ +subdirectory like every other bucket, so it was never found and the +MAINTAIN privilege ('m') silently fell back to the default bucket's list, +which lacks it. +""" + +import json + +from flask import render_template + +from pgadmin.utils.route import BaseTestGenerator + +# PG17 in pgAdmin's version-number-times-10000 scheme. +PG17 = 170000 + +_ALLOWED_PRIVS_JSON = 'sql/allowed_privs.json' + + +class AllowedPrivsJsonPathTestCase(BaseTestGenerator): + """Loading allowed_privs.json for PG17+ must pick up the 17_plus + bucket's list (with MAINTAIN), not silently fall back to default. + """ + + scenarios = [ + ('views on pg', dict(base_template='views/pg/#{0}#')), + ('views on ppas', dict(base_template='views/ppas/#{0}#')), + ('materialized views on pg', dict( + base_template='mviews/pg/#{0}#')), + ('materialized views on ppas', dict( + base_template='mviews/ppas/#{0}#')), + ] + + def setUp(self): + pass + + def runTest(self): + template_path = self.base_template.format(PG17) + with self.app.app_context(): + rendered = render_template( + '/'.join([template_path, _ALLOWED_PRIVS_JSON]) + ) + allowed_acls = json.loads(rendered) + self.assertIn('m', allowed_acls['datacl']['acl']) From ab01c4be943efeb8574e9b90416b14f1eb37377d Mon Sep 17 00:00:00 2001 From: Dave Page Date: Wed, 26 Aug 2026 15:39:08 +0100 Subject: [PATCH 2/3] Add PG17+ RE-SQL fixture overrides for mview privilege grants Now that allowed_acls for views/mviews correctly includes MAINTAIN on PG17+, granting the same non-MAINTAIN privilege set as before no longer equals the full allowed set, so the generated SQL expands to the explicit privilege list instead of collapsing to "GRANT ALL" - this is the correct new behaviour, but it left the two mview msql fixtures (which fell back to the default bucket, written before MAINTAIN existed) stale. Added 17_plus overrides with the corrected expected output, alongside the existing 15_plus/16_plus buckets for these fixtures. --- .../tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql | 2 ++ .../schemas/views/tests/pg/17_plus/alter_mview_msql.sql | 1 + .../tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql | 2 ++ .../schemas/views/tests/ppas/17_plus/alter_mview_msql.sql | 1 + 4 files changed, 6 insertions(+) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql new file mode 100644 index 00000000000..c92eb9d341c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv_msql.sql @@ -0,0 +1,2 @@ +REVOKE ALL ON TABLE public."testmview_$%{}[]()&*^!/@`#" FROM ; +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql new file mode 100644 index 00000000000..bdf4b291a36 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_msql.sql @@ -0,0 +1 @@ +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql new file mode 100644 index 00000000000..81ce5fe812e --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv_msql.sql @@ -0,0 +1,2 @@ +REVOKE ALL ON TABLE public."testmview_$%{}[]()&*^!/@`#" FROM enterprisedb; +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql new file mode 100644 index 00000000000..bdf4b291a36 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_msql.sql @@ -0,0 +1 @@ +GRANT INSERT, SELECT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; From d827f4c085fa58ae2d5ab1d88c9b4eb2263a781c Mon Sep 17 00:00:00 2001 From: Dave Page Date: Mon, 14 Sep 2026 10:20:43 +0100 Subject: [PATCH 3/3] Complete the PG17+ RE-SQL fixtures for views and materialised views The 17_plus test directories added for the msql fixtures contained only .sql files, and get_test_folder() in the RE-SQL runner resolves at folder level rather than per file, unlike get_test_file(): it picks the first existing version directory and then lists the .json scenario files in it. On a PG17+ server the runner therefore resolved to a directory with no JSON in it and ran no view or materialised view scenarios at all, which is why the stale expected SQL below went unnoticed. Each bucket carries its own copy of tests.json and test_mview.json for that reason, so the 17_plus buckets now do too. With the scenarios running again, the reverse engineered SQL for the two scenarios that grant the seven-privilege set to PUBLIC needs the same 17_plus treatment as the msql fixtures, since sql() re-filters through parse_priv_to_db() with the version's allowed ACLs and no longer collapses seven of eight privileges to ALL. The owner's grant still collapses, as the owner holds MAINTAIN as well. Verified against PostgreSQL 18: 43 scenarios now run, where none ran before, and all pass. --- .../views/tests/pg/17_plus/alter_mview.sql | 18 + .../alter_mview_change_grantee_priv.sql | 17 + .../views/tests/pg/17_plus/test_mview.json | 345 ++++++++++++++++++ .../schemas/views/tests/pg/17_plus/tests.json | 246 +++++++++++++ .../views/tests/ppas/17_plus/alter_mview.sql | 18 + .../alter_mview_change_grantee_priv.sql | 17 + .../views/tests/ppas/17_plus/test_mview.json | 339 +++++++++++++++++ .../views/tests/ppas/17_plus/tests.json | 207 +++++++++++ .../tests/test_allowed_privs_json_path.py | 3 + 9 files changed, 1210 insertions(+) create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/test_mview.json create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/tests.json create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv.sql create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/test_mview.json create mode 100644 web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/tests.json diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview.sql new file mode 100644 index 00000000000..1a1ad3e3b44 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview.sql @@ -0,0 +1,18 @@ +-- View: public.testmview_$%{}[]()&*^!/@`# + +-- DROP MATERIALIZED VIEW IF EXISTS public."testmview_$%{}[]()&*^!/@`#"; + +CREATE MATERIALIZED VIEW IF NOT EXISTS public."testmview_$%{}[]()&*^!/@`#" +TABLESPACE pg_default +AS + SELECT 1 AS col1 +WITH NO DATA; + +ALTER TABLE IF EXISTS public."testmview_$%{}[]()&*^!/@`#" + OWNER TO ; + +COMMENT ON MATERIALIZED VIEW public."testmview_$%{}[]()&*^!/@`#" + IS 'comment1'; + +GRANT TRUNCATE, INSERT, DELETE, SELECT, TRIGGER, UPDATE, REFERENCES ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; +GRANT ALL ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO ; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv.sql new file mode 100644 index 00000000000..dcba43c9d26 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/alter_mview_change_grantee_priv.sql @@ -0,0 +1,17 @@ +-- View: public.testmview_$%{}[]()&*^!/@`# + +-- DROP MATERIALIZED VIEW IF EXISTS public."testmview_$%{}[]()&*^!/@`#"; + +CREATE MATERIALIZED VIEW IF NOT EXISTS public."testmview_$%{}[]()&*^!/@`#" +TABLESPACE pg_default +AS + SELECT 1 AS col1 +WITH NO DATA; + +ALTER TABLE IF EXISTS public."testmview_$%{}[]()&*^!/@`#" + OWNER TO ; + +COMMENT ON MATERIALIZED VIEW public."testmview_$%{}[]()&*^!/@`#" + IS 'comment1'; + +GRANT TRUNCATE, INSERT, DELETE, SELECT, TRIGGER, UPDATE, REFERENCES ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/test_mview.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/test_mview.json new file mode 100644 index 00000000000..ac63312cb0a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/test_mview.json @@ -0,0 +1,345 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Extension", + "endpoint": "NODE-extension.obj", + "sql_endpoint": "NODE-extension.sql_id", + "data": { + "name": "postgres_fdw", + "version": "", + "relocatable": true + }, + "store_object_id": true + }, + { + "type": "create", + "name": "Create Materialised Views with extensions.", + "endpoint": "NODE-mview.obj", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql", + "data": { + "spcname": "pg_default", + "schema": "public", + "owner": "", + "datacl": [], + "seclabels": [], + "name": "testmview_$%{}[]()&*^!/@`#", + "comment": "comment1", + "definition": "SELECT 1 AS col1", + "dependsonextensions": [ + "plpgsql", + "postgres_fdw" + ] + }, + "expected_sql_file": "create_mview_no_depends.sql", + "expected_msql_file": "create_mview_no_depends.msql" + }, + { + "type": "alter", + "name": "Alter Materialised Views with NO DEPENDS.", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "dependsonextensions": [ + "plpgsql" + ] + }, + "expected_sql_file": "alter_mview_no_depends.sql", + "expected_msql_file": "alter_mview_no_depends.msql" + }, + { + "type": "delete", + "name": "Drop Materialised Views", + "endpoint": "NODE-mview.delete_id", + "data": {} + }, + { + "type": "delete", + "name": "Drop Extension", + "endpoint": "NODE-extension.delete", + "data": { + "ids": [ + "" + ] + }, + "preprocess_data": true + }, + { + "type": "create", + "name": "Create Materialised Views", + "endpoint": "NODE-mview.obj", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql", + "data": { + "spcname": "pg_default", + "schema": "public", + "owner": "", + "datacl": [], + "seclabels": [], + "name": "testmview_$%{}[]()&*^!/@`#", + "comment": "comment1", + "definition": "SELECT 1 AS col1" + }, + "expected_sql_file": "create_mview.sql", + "expected_msql_file": "create_mview_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (Adding privileges)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "datacl": { + "added": [ + { + "grantee": "PUBLIC", + "grantor": "", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "d", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "D", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "x", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "t", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_mview.sql", + "expected_msql_file": "alter_mview_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (Remove all privileges)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "datacl": { + "deleted": [ + { + "grantee": "PUBLIC", + "grantor": "", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "d", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "D", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "x", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "t", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_mview_drop_all_priv.sql", + "expected_msql_file": "alter_mview_drop_all_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (change grantee in privileges)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "datacl": { + "changed": [ + { + "grantee": "PUBLIC", + "grantor": "", + "old_grantee": "", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "d", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "D", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "x", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "t", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_mview_change_grantee_priv.sql", + "expected_msql_file": "alter_mview_change_grantee_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (change definition)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "definition": "SELECT 12 AS col1;" + }, + "expected_sql_file": "alter_mview_definition.sql", + "expected_msql_file": "alter_mview_definition_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (Fillfactor)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "fillfactor": "18", + "with_data": true + }, + "expected_sql_file": "alter_mview_add_fillfactor.sql", + "expected_msql_file": "alter_mview_add_fillfactor_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (add table parameters)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "autovacuum_custom": true, + "autovacuum_enabled": "t", + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_analyze_scale_factor", + "value": 0.2 + } + ] + } + }, + "expected_sql_file": "alter_mview_add_table_parameter.sql", + "expected_msql_file": "alter_mview_add_table_parameter_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (remove table parameters)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "autovacuum_custom": true, + "autovacuum_enabled": "x", + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_analyze_scale_factor", + "value": null + } + ] + } + }, + "expected_sql_file": "alter_mview_remove_table_parameter.sql", + "expected_msql_file": "alter_mview_remove_table_parameter_msql.sql" + }, + { + "type": "create", + "name": "Create Materialised Views with access method", + "endpoint": "NODE-mview.obj", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql", + "data": { + "spcname": "pg_default", + "schema": "public", + "owner": "", + "datacl": [], + "seclabels": [], + "name": "testmview_am_$%{}[]()&*^!/@`#", + "comment": "comment1", + "definition": "SELECT 1 AS col1", + "amname": "heap" + }, + "expected_msql_file": "create_mview_with_am_msql.sql", + "expected_sql_file": "create_mview_with_am.sql" + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/tests.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/tests.json new file mode 100644 index 00000000000..534503f9ebb --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/pg/17_plus/tests.json @@ -0,0 +1,246 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Table for Views", + "endpoint": "NODE-table.obj", + "sql_endpoint": "NODE-table.sql_id", + "data": { + "name": "test_view_table", + "check_constraint": [], + "coll_inherits": "[]", + "columns": [ + { + "name": "col1", + "cltype": "integer" + } + ], + "schema": "public" + } + }, + { + "type": "create", + "name": "Create View", + "endpoint": "NODE-view.obj", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql", + "data": { + "definition": "select col1 from test_view_table;", + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public", + "check_option": "local", + "security_barrier": false, + "security_invoker": false, + "comment": "Testcomment", + "datacl": [ + { + "grantee": "", + "old_grantee": "", + "grantor": "", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + } + ] + } + ] + }, + "expected_sql_file": "create_view.sql", + "expected_msql_file": "create_view_msql.sql" + }, + { + "type": "alter", + "name": "Alter View", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "security_invoker": true, + "comment": "Testcomment-updated", + "datacl": [ + { + "grantee": "", + "grantor": "", + "old_grantee": "", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + } + ] + } + ] + }, + "expected_sql_file": "alter_view.sql", + "expected_msql_file": "alter_view_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (changing code)", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "definition": "SELECT * FROM test_view_table;" + }, + "expected_sql_file": "alter_view_definition.sql", + "expected_msql_file": "alter_view_definition_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (adding privileges)", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment": "Testcomment-updated", + "datacl": { + "added": [ + { + "grantee": "PUBLIC", + "grantor": "", + "privileges": [ + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_view_add_some_priv.sql", + "expected_msql_file": "alter_view_add_some_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (deleting privileges (PUBLIC))", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment": "Testcomment-updated", + "datacl": { + "deleted": [ + { + "grantee": "PUBLIC", + "grantor": "", + "privileges": [ + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + } + }, + { + "type": "alter", + "name": "Alter View (changing privileges (postgres to PUBLIC))", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment": "Testcomment-updated", + "datacl": { + "changed": [ + { + "grantee": "PUBLIC", + "grantor": "", + "old_grantee": "", + "privileges": [ + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_view_update_priv.sql", + "expected_msql_file": "alter_view_update_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (deleting privileges)", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment": "Testcomment-updated", + "datacl": { + "deleted": [ + { + "grantee": "PUBLIC", + "grantor": "", + "privileges": [ + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_view_delete_priv.sql", + "expected_msql_file": "alter_view_delete_priv_msql.sql" + }, + { + "type": "delete", + "name": "Drop View", + "endpoint": "NODE-view.obj_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "", + "schema": "public" + } + }, + { + "type": "delete", + "name": "Drop Table for view", + "endpoint": "NODE-table.obj_id", + "data": { + "name": "test_view_table", + "owner": "", + "schema": "public" + } + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview.sql new file mode 100644 index 00000000000..2ed9346fbac --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview.sql @@ -0,0 +1,18 @@ +-- View: public.testmview_$%{}[]()&*^!/@`# + +-- DROP MATERIALIZED VIEW public."testmview_$%{}[]()&*^!/@`#"; + +CREATE MATERIALIZED VIEW IF NOT EXISTS public."testmview_$%{}[]()&*^!/@`#" +TABLESPACE pg_default +AS + SELECT 1 AS col1 +WITH NO DATA; + +ALTER TABLE IF EXISTS public."testmview_$%{}[]()&*^!/@`#" + OWNER TO enterprisedb; + +COMMENT ON MATERIALIZED VIEW public."testmview_$%{}[]()&*^!/@`#" + IS 'comment1'; + +GRANT TRUNCATE, INSERT, DELETE, SELECT, TRIGGER, UPDATE, REFERENCES ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; +GRANT ALL ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO enterprisedb; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv.sql new file mode 100644 index 00000000000..4794ef4a051 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/alter_mview_change_grantee_priv.sql @@ -0,0 +1,17 @@ +-- View: public.testmview_$%{}[]()&*^!/@`# + +-- DROP MATERIALIZED VIEW public."testmview_$%{}[]()&*^!/@`#"; + +CREATE MATERIALIZED VIEW IF NOT EXISTS public."testmview_$%{}[]()&*^!/@`#" +TABLESPACE pg_default +AS + SELECT 1 AS col1 +WITH NO DATA; + +ALTER TABLE IF EXISTS public."testmview_$%{}[]()&*^!/@`#" + OWNER TO enterprisedb; + +COMMENT ON MATERIALIZED VIEW public."testmview_$%{}[]()&*^!/@`#" + IS 'comment1'; + +GRANT TRUNCATE, INSERT, DELETE, SELECT, TRIGGER, UPDATE, REFERENCES ON TABLE public."testmview_$%{}[]()&*^!/@`#" TO PUBLIC; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/test_mview.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/test_mview.json new file mode 100644 index 00000000000..9e18388d61a --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/test_mview.json @@ -0,0 +1,339 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Extension", + "endpoint": "NODE-extension.obj", + "sql_endpoint": "NODE-extension.sql_id", + "data": { + "name": "postgres_fdw", + "version": "", + "relocatable": true + }, + "store_object_id": true + }, + { + "type": "create", + "name": "Create Materialised Views with extensions.", + "endpoint": "NODE-mview.obj", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql", + "data": { + "spcname": "pg_default", + "schema": "public", + "owner": "enterprisedb", + "datacl": [], + "seclabels": [], + "name": "testmview_$%{}[]()&*^!/@`#", + "comment": "comment1", + "definition": "SELECT 1 AS col1", + "dependsonextensions": ["plpgsql", "postgres_fdw"] + }, + "expected_sql_file": "create_mview_no_depends.sql", + "expected_msql_file": "create_mview_no_depends.msql" + }, + { + "type": "alter", + "name": "Alter Materialised Views with NO DEPENDS ON.", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "dependsonextensions": ["plpgsql"] + }, + "expected_sql_file": "alter_mview_no_depends.sql", + "expected_msql_file": "alter_mview_no_depends.msql" + }, + { + "type": "delete", + "name": "Drop Materialised Views", + "endpoint": "NODE-mview.delete_id", + "data": { + } + }, + { + "type": "delete", + "name": "Drop Extension", + "endpoint": "NODE-extension.delete", + "data": { + "ids": [""] + }, + "preprocess_data": true + }, + { + "type": "create", + "name": "Create Materialised Views", + "endpoint": "NODE-mview.obj", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql", + "data": { + "spcname": "pg_default", + "schema": "public", + "owner": "enterprisedb", + "datacl": [], + "seclabels": [], + "name": "testmview_$%{}[]()&*^!/@`#", + "comment": "comment1", + "definition": "SELECT 1 AS col1" + }, + "expected_sql_file": "create_mview.sql", + "expected_msql_file": "create_mview_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (Adding privileges)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "datacl": { + "added": [ + { + "grantee": "PUBLIC", + "grantor": "enterprisedb", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "d", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "D", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "x", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "t", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_mview.sql", + "expected_msql_file": "alter_mview_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (Remove all privileges)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "datacl": { + "deleted": [ + { + "grantee": "PUBLIC", + "grantor": "enterprisedb", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "d", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "D", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "x", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "t", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_mview_drop_all_priv.sql", + "expected_msql_file": "alter_mview_drop_all_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (change grantee in privileges)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "datacl": { + "changed": [ + { + "grantee": "PUBLIC", + "grantor": "enterprisedb", + "old_grantee": "enterprisedb", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "r", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "w", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "d", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "D", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "x", + "privilege": true, + "with_grant": false + }, + { + "privilege_type": "t", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_mview_change_grantee_priv.sql", + "expected_msql_file": "alter_mview_change_grantee_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (change definition)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "definition": "SELECT 12 AS col1;" + }, + "expected_sql_file": "alter_mview_definition.sql", + "expected_msql_file": "alter_mview_definition_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (Fillfactor)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "fillfactor": "18", + "with_data": true + }, + "expected_sql_file": "alter_mview_add_fillfactor.sql", + "expected_msql_file": "alter_mview_add_fillfactor_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (add table parameters)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "autovacuum_custom": true, + "autovacuum_enabled": "t", + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_analyze_scale_factor", + "value": 0.2 + } + ] + } + }, + "expected_sql_file": "alter_mview_add_table_parameter.sql", + "expected_msql_file": "alter_mview_add_table_parameter_msql.sql" + }, + { + "type": "alter", + "name": "Alter Materialised Views (remove table parameters)", + "endpoint": "NODE-mview.obj_id", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql_id", + "data": { + "autovacuum_custom": true, + "autovacuum_enabled": "x", + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_analyze_scale_factor", + "value": null + } + ] + } + }, + "expected_sql_file": "alter_mview_remove_table_parameter.sql", + "expected_msql_file": "alter_mview_remove_table_parameter_msql.sql" + }, + { + "type": "create", + "name": "Create Materialised Views with access method", + "endpoint": "NODE-mview.obj", + "sql_endpoint": "NODE-mview.sql_id", + "msql_endpoint": "NODE-mview.msql", + "data": { + "spcname": "pg_default", + "schema": "public", + "owner": "enterprisedb", + "datacl": [], + "seclabels": [], + "name": "testmview_am_$%{}[]()&*^!/@`#", + "comment": "comment1", + "definition": "SELECT 1 AS col1", + "amname": "heap" + }, + "expected_msql_file": "create_mview_with_am_msql.sql", + "expected_sql_file": "create_mview_with_am.sql" + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/tests.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/tests.json new file mode 100644 index 00000000000..c8111f9f557 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/ppas/17_plus/tests.json @@ -0,0 +1,207 @@ +{ + "scenarios": [ + { + "type": "create", + "name": "Create Table for Views", + "endpoint": "NODE-table.obj", + "sql_endpoint": "NODE-table.sql_id", + "data": { + "name": "test_view_table", + "check_constraint": [], + "coll_inherits": "[]", + "columns": [ + { + "name": "col1", + "cltype": "integer" + } + ], + "schema": "public" + } + }, + { + "type": "create", + "name": "Create View", + "endpoint": "NODE-view.obj", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql", + "data": { + "definition": "select col1 from test_view_table;", + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "enterprisedb", + "schema": "public", + "check_option": "local", + "security_barrier": false, + "security_invoker": false, + "comment":"Testcomment", + "datacl":[{"grantee":"enterprisedb", "grantor":"enterprisedb", "privileges":[{"privilege_type": "a", "privilege": true, + "with_grant":false}]}] + }, + "expected_sql_file": "create_view.sql", + "expected_msql_file": "create_view_msql.sql" + }, + { + "type": "alter", + "name": "Alter View", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "enterprisedb", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "security_invoker": true, + "comment":"Testcomment-updated", + "datacl":[{"grantee":"enterprisedb", "grantor":"enterprisedb", "privileges":[{"privilege_type": "a", "privilege": true, + "with_grant":false}]}] + }, + "expected_sql_file": "alter_view.sql", + "expected_msql_file": "alter_view_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (adding privileges)", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "datacl":{ + "added":[ + { + "grantee":"PUBLIC", + "grantor":"enterprisedb", + "privileges":[ + { + "privilege_type":"r", + "privilege":true, + "with_grant":false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_view_add_some_priv.sql", + "expected_msql_file": "alter_view_add_some_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (deleting privileges (PUBLIC))", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "enterprisedb", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment":"Testcomment-updated", + "datacl": + { + "deleted":[ + { + "grantee":"PUBLIC", + "grantor":"enterprisedb", + "privileges":[ + { + "privilege_type":"r", + "privilege":true, + "with_grant":false + } + ] + } + ] + } + } + }, + { + "type": "alter", + "name": "Alter View (changing privileges (enterprisedb to PUBLIC))", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "enterprisedb", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment":"Testcomment-updated", + "datacl": + { + "changed":[ + { + "grantee":"PUBLIC", + "grantor":"enterprisedb", + "old_grantee": "enterprisedb", + "privileges":[ + { + "privilege_type":"r", + "privilege":true, + "with_grant":false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_view_update_priv.sql", + "expected_msql_file": "alter_view_update_priv_msql.sql" + }, + { + "type": "alter", + "name": "Alter View (deleting privileges)", + "endpoint": "NODE-view.obj_id", + "sql_endpoint": "NODE-view.sql_id", + "msql_endpoint": "NODE-view.msql_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "enterprisedb", + "schema": "public", + "check_option": "cascaded", + "security_barrier": true, + "comment":"Testcomment-updated", + "datacl": + { + "deleted":[ + { + "grantee":"PUBLIC", + "grantor":"enterprisedb", + "privileges":[ + { + "privilege_type":"r", + "privilege":true, + "with_grant":false + } + ] + } + ] + } + }, + "expected_sql_file": "alter_view_delete_priv.sql", + "expected_msql_file": "alter_view_delete_priv_msql.sql" + }, + { + "type": "delete", + "name": "Drop View", + "endpoint": "NODE-view.obj_id", + "data": { + "name": "testview_$%{}[]()&*^!@\"'`\\/#", + "owner": "enterprisedb", + "schema": "public" + } + }, + { + "type": "delete", + "name": "Drop Table for view", + "endpoint": "NODE-table.obj_id", + "data": { + "name": "test_view_table", + "owner": "enterprisedb", + "schema": "public" + } + } + ] +} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py index cc036ee894f..2b43f4a22b4 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_allowed_privs_json_path.py @@ -42,6 +42,9 @@ class AllowedPrivsJsonPathTestCase(BaseTestGenerator): ] def setUp(self): + # BaseTestGenerator.setUp() connects to the test server, which this + # test has no use for: it only renders a template, and the Flask app + # it needs is set up by the regression harness rather than here. pass def runTest(self):