Skip to content

Handling a new PostgreSQL release ​

What has to happen in PlumeSQL when PostgreSQL ships a new major, in the order that keeps every step verifiable, plus the inventory of every version-sensitive surface so nothing is discovered by a user first. Written 2026-08 with 13 through 18 supported; the steps are the same for every future major.

What "supported" means here ​

PlumeSQL supports a contiguous range of majors: the oldest release the snapshot renders correctly through the newest one the test matrix proves. The range lives in exactly three places, and they must agree:

  • scripts/pgmatrix.sh (the VERSIONS default): what make test-versions boots locally.
  • .github/workflows/schema-matrix.yml: one service container per version plus the port spec line, the CI copy of the same matrix.
  • web/src/lib/pgsql-versions.ts: the newest major with a grammar delta entry (newestKnown follows the delta table).

A server NEWER than the newest known major is not refused anywhere: the editor grammar gives it every delta it has (languageFor treats an unknown major as "all of them"), the snapshot renders what the catalog offers, and whatever is wrong surfaces in the matrix once the version is added. Support is therefore a statement about what is TESTED, not a gate.

The checklist for a new major NN ​

Do the steps in this order: each one's verification depends on the one before it.

  1. Read the release notes first, with four questions: new SQL syntax and keywords (grammar deltas), catalog changes (search.sql), new object families or properties (snapshot CTEs and the dictionary), and pg_dump or psql behavior changes (the backup modal and the replay half of the matrix). PostgreSQL's own src/include/parser/kwlist.h diff between NN-1 and NN is the authoritative keyword list.

  2. Add NN to the test matrix and make it pass. Add the version to scripts/pgmatrix.sh VERSIONS, a postgres:NN-alpine service to schema-matrix.yml with its port in the spec line, then run make test-versions. This is the only thing that checks the four properties nothing else can: every rendered file executes again on the server it came from, a snapshot of the replayed database equals the original byte for byte, the dictionary matches the catalog, and nothing flaps between two renders. Fix search.sql where NN moved a catalog column or changed a render function's output; a genuinely new object family gets its own CTE, its dictionary entry (docs/OBJECTINDEX.md in the same change) and a matrix_fixture.sql block declaring min=NN. A beta can be run through the same matrix without committing anything: PLUMESQL_PG_VERSIONS="18 19" make test-versions.

  3. Add the editor grammar delta. One entry in web/src/lib/pgsql-versions.ts deltas: the keywords, builtin functions and type keywords NN introduced (from step 1's kwlist diff). This is what makes a new keyword light up only on servers that can run it, and what feeds completion's keyword lists. The per-version reserved-word comment in pgsql.ts says how reserved words are handled; touch it only if NN reserves a formerly unreserved word.

  4. Refresh the tree-sitter grammar asset once upstream (gmr/tree-sitter-postgres, generated from PostgreSQL's own gram.y) lands the NN grammar. The rebuild steps live in web/public/treesitter/README.md beside the asset (git-lfs clone, tree-sitter build --wasm, gzip -9); update that README's provenance commit in the same change. Deliberate design: ONE grammar tracking the newest release serves every server, because a newer grammar parses older SQL (supersets), and any gap while upstream catches up costs only completion scope and formatting for the new syntax, never correctness: the formatter refuses what does not parse and completion falls back to the sqlcontext.ts heuristics.

  5. Check the client tools story. Dumps (the backup modal, the snapshot's pg_dump paths) need pg_dump >= the server's major; pg_dump --version older than NN refuses an NN server. The System page's tool install should offer a version that covers NN, and the version-mismatch wording in the dump flows should stay truthful. psql needs nothing.

  6. Spot-check what needs no change, so it stays that way. pgdocs.ts builds postgresql.org/docs/<major>/ URLs from the server's own major, so new docs links work the day NN ships (only a renamed page would need the keyword-to-page map touched). pgx handles the wire protocol via make upgrade-go. The Activity and Top queries panels read pg_stat_activity and pg_stat_statements, whose shapes DO occasionally move between majors: run both against an NN server once.

  7. Bump the disposable containers when NN becomes the new stable: the dev container line in AGENTS.md and the e2e-db container in the Makefile (postgres:NN-alpine). Not a correctness matter (the matrix covers every version), just keeping daily development on a current server.

  8. Manual pass and the changelog. Connect to an NN server and walk the surfaces that read the catalog live: object tree and dictionary (refresh a snapshot), completion with and without the parser, statement marks, Activity, Top queries, a backup and a restore. Then one CHANGELOG line under Unreleased naming the supported range, since a new supported major is a user-visible change.

Dropping an old major ​

A deliberate decision, never a side effect, and lazier than PostgreSQL's own EOL calendar (13 went EOL in late 2025 and is still supported here because supporting it costs almost nothing). When one is dropped: remove it from pgmatrix.sh and schema-matrix.yml, fold its grammar delta into the base grammar in pgsql.ts (the base targets the oldest supported server, so the delta table's floor moves up), sweep search.sql for branches that only existed for it, and raise the min= floors in matrix_fixture.sql. Keep the removal in one commit so the range change reads as one decision.

The inventory ​

SurfaceFile(s)Changes when
Snapshot renderer and dictionaryinternal/schemasnap/search.sql, sql/Catalog or render-function changes, new families
Version matrixscripts/pgmatrix.sh, .github/workflows/schema-matrix.yml, internal/schemasnap/testdata/matrix_fixture.sqlEvery new major, every dropped one
Editor grammar per majorweb/src/lib/pgsql-versions.ts (deltas), pgsql.ts (base, oldest supported)New keywords, functions, types; base only when the floor moves
Structural parser (completion scope, formatter)web/public/treesitter/postgres.wasm.gz + READMEWhen upstream regenerates from the new gram.y
Docs linksweb/src/lib/pgdocs.tsOnly a renamed docs page; URLs are per-major already
Live catalog readersActivity, Top queries (internal/db/sql)Only when pg_stat views move
Client toolsSystem page install, backup and dump flowspg_dump must cover the newest supported server
Dev and e2e containersAGENTS.md, MakefileWhen the new major becomes the daily default

What deliberately does not track versions ​

The wire protocol (pgx, via make upgrade-go), Monaco itself, the action annotation format (server-agnostic by design, ACTIONSPEC.md), and the session and settings stores. None of these carry a PostgreSQL version anywhere, and nothing should be added to them that does.

PlumeSQL is a hercstack product.