Message-ID: From: "vlsi (@vlsi)" To: "pgjdbc/pgjdbc" Date: Tue, 02 Jun 2026 11:54:19 +0000 Subject: [pgjdbc/pgjdbc] PR #4133: fix(jdbc): request the RULE privilege only below PostgreSQL 18 List-Id: X-GitHub-Additions: 20 X-GitHub-Author-Id: 213894 X-GitHub-Author-Login: vlsi X-GitHub-Base: release/42.4.x X-GitHub-Changed-Files: 3 X-GitHub-Commits: 1 X-GitHub-Deletions: 2 X-GitHub-Head-Branch: codex/rule-privilege-pg18-42.4 X-GitHub-Head-SHA: 587e7da509f7868486fbbf911b6ac3e4c5683c84 X-GitHub-Issue: 4133 X-GitHub-Merge-SHA: 0ae5d18083261651bf4acc4c617ec49a71a7bfb8 X-GitHub-Merged-By: vlsi X-GitHub-Repo: pgjdbc/pgjdbc X-GitHub-State: merged X-GitHub-Type: pull_request X-GitHub-Url: https://github.com/pgjdbc/pgjdbc/pull/4133 Content-Type: text/plain; charset=utf-8 ## What Backport of d43568ebe425a4a9e35fc46f4ddb6a3bd6102133 (already on `release/42.5.x`) to `release/42.4.x`. - `PgDatabaseMetaData.getTables`: when `hideUnprivilegedObjects` is enabled, include `RULE` in the `has_table_privilege` list only for servers below 18. - `ServerVersion`: add the `v17` and `v18` enum constants and a `getMajorVersionNumber()` method. - `Version`: add `getMajorVersionNumber()` to the interface (implemented by `ServerVersion` and the anonymous `Version` in `ServerVersion.from`). ## Why PostgreSQL 18 removed the `RULE` privilege, so `has_table_privilege` now rejects it with `unrecognized privilege type: RULE`. With `hideUnprivilegedObjects` enabled, `getTables` always added `RULE` to the privilege list, which broke metadata lookups against PostgreSQL 18. Upstream of the backported commit: master commits 74d8c239d and d98b56bec. ## How to verify Connect to PostgreSQL 18 with `hideUnprivilegedObjects=true` and call `getTables`; it should return without the `unrecognized privilege type: RULE` error. Against servers below 18 the privilege list is unchanged. ## Notes The full Gradle build does not run in my sandbox: the 42.4 build script fails to resolve the `org.ajoberstar.grgit:grgit-core:4.0.1` plugin dependency at configuration time, which is unrelated to this change and reproduces on the base branch. The change is a clean cherry-pick of the identical, already-released 42.5 commit; the relevant source matches between the branches and no other `Version` implementer exists. 🤖 Generated with [Claude Code](https://claude.com/claude-code) diff --git a/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java b/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java index c587270396..7372b73cac 100644 --- a/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java +++ b/pgjdbc/src/main/java/org/postgresql/core/ServerVersion.java @@ -32,7 +32,9 @@ public enum ServerVersion implements Version { v13("13"), v14("14"), v15("15"), - v16("16") + v16("16"), + v17("17"), + v18("18") ; private final int version; @@ -51,6 +53,11 @@ public int getVersionNum() { return version; } + @Override + public int getMajorVersionNumber() { + return version / 10000; + } + /** *

Attempt to parse the server version string into an XXYYZZ form version number into a * {@link Version}.

@@ -68,6 +75,11 @@ public int getVersionNum() { return versionNum; } + @Override + public int getMajorVersionNumber() { + return versionNum / 10000; + } + @Override public boolean equals(@Nullable Object obj) { if (obj instanceof Version) { diff --git a/pgjdbc/src/main/java/org/postgresql/core/Version.java b/pgjdbc/src/main/java/org/postgresql/core/Version.java index 639226a172..d192531633 100644 --- a/pgjdbc/src/main/java/org/postgresql/core/Version.java +++ b/pgjdbc/src/main/java/org/postgresql/core/Version.java @@ -14,4 +14,5 @@ public interface Version { */ int getVersionNum(); + int getMajorVersionNumber(); } diff --git a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java index 3588f464c9..485032bac0 100644 --- a/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java +++ b/pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java @@ -1318,8 +1318,13 @@ public ResultSet getTables(@Nullable String catalog, @Nullable String schemaPatt select += " AND n.nspname LIKE " + escapeQuotes(schemaPattern); } if (connection.getHideUnprivilegedObjects()) { + // as of https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=fefa76f70fdc75c91f80bddce2df7a8825205962 + // The RULE privilege has been removed + String privileges = connection.getServerMajorVersion() < ServerVersion.v18.getMajorVersionNumber() + ? " 'SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES, TRIGGER')" + : " 'SELECT, INSERT, UPDATE, DELETE, REFERENCES, TRIGGER')"; select += " AND has_table_privilege(c.oid, " - + " 'SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES, TRIGGER')"; + + privileges; } orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME ";