Subject: [pgjdbc/pgjdbc] PR #4077: pgjdbc: introduce @PgApi / @PgTags / @PgPropertyType annotations on PGProperty

From: "vlsi (@vlsi)" <[email-masked]>
Date: Mon, 18 May 2026 08:58:32 +0000

Adds three CLASS-retained annotations in org.postgresql.annotations and applies them to all 87 PGProperty values. The annotations are the contract a documentation generator can read via ASM bytecode inspection — without exposing the data at runtime.

The annotations are is used in https://github.com/pgjdbc/pgjdbc/pull/4075 to implement https://github.com/pgjdbc/pgjdbc/issues/1687

---

The annotations are designed after https://github.com/apiguardian-team/apiguardian with several changes:
* The annotations are renamed to avoid third-party dependencies
* I've added special fields to track "available since, deprecated in, hidden in", see https://github.com/apiguardian-team/apiguardian/issues/207
* I've added `status=HIDDEN` so we can hide certain members at the bytecode later, see https://github.com/apiguardian-team/apiguardian/issues/208

---

```
  PgApi(status, introducedIn, deprecatedIn, hiddenIn)
    Lifecycle status (STABLE / EXPERIMENTAL / MAINTAINED / INTERNAL /
    DEPRECATED / HIDDEN) plus three orthogonal version axes so docs can
    render "Available since X.Y; deprecated in Y.Z; hidden in Z.W"
    without losing any.

  PgTags(Tag[]) — topical buckets (SSL, AUTHENTICATION, FETCH, TIMEOUT,
    NETWORK, KERBEROS_GSS, ...) plus the OPERATIONS secondary tag for
    properties tuned at deployment time. Drives section-specific
    sub-tables in the docs.

  PgPropertyType(Kind) — semantic data type, with unit-bearing variants
    (DURATION_SECONDS / DURATION_MILLIS, SIZE_BYTES / SIZE_EXPRESSION).
    Surfaces "is this number seconds or milliseconds?" — a long-standing
    pgjdbc foot-gun.
```

All annotations use `@Retention(CLASS)` so they are visible to bytecode readers but not exposed at runtime. Pg-prefixed names avoid collisions with widely-used annotation libraries (`org.apiguardian.api.API` ships with JUnit Jupiter), so a user typing `@Pg...` in their IDE sees only pgjdbc annotations.

Each DEPRECATED `@PgApi` sits alongside the standard JDK `@Deprecated` so that both bytecode readers and the compiler / IDE see the deprecation.

---

From: "vlsi (@vlsi)" <[email-masked]>
Date: Fri, 22 May 2026 06:47:43 +0000

Here's a use case for `status=HIDDEN`: https://github.com/pgjdbc/pgjdbc/pull/661/changes#diff-f1f17a9527eed81e0d547e9d6b7d5a00c62627e6c9ddeac6416fe290a2bd07d3L111-L112

We should not have removed enum entry `PGProperty.COMPATIBLE`, but we should rather deprecated it or made it hidden.

---

From: "sehrope (@sehrope)" <[email-masked]>
Date: Fri, 22 May 2026 12:00:56 +0000

Besides the data type piece, I don't think this makes sense. We do not introduce anything as a property that is not stable. We're not going to have experimental properties released and then removed or linger. If there's an experiment branch with a property, that can be a snapshot release of the jar for people to test out. It's not going to be a published thing in the driver. Ditto for "hidden". It's either there or it's not. There's no secret properties. If something should not be used it can be `@Deprecated`. If we remove things, it's a conscious breaking change.

The topic tags would be useful for an automated doc site. I haven't actually looked them individually to see if the meaning align with the properties. So ignoring that for now.

I think the `PgPropertyType`  may be better named as "DataType" or "ValueType" to reflect the intent. And having it be a runtime annotation would allow it to be used for runtime validation of the value to standardize the checks and error messages. It could be "integer", "positive integer", "string", "boolean", ... or even "second" etc. We'd have to be careful here if there's special values out of range though (e.g., "seconds" would normally be >=0 but maybe -1 has special meaning).

Having those types exposed to the user could be a useful feature. User applications could use it to dynamically provide connection options. Not just the names, but structured validation of the values. It's not a light decision though as we'd clearly be increasing the surface area of the driver to include this new enum. So would want to think about this for a bit before proceeding.