Skip to content

Ship canonical ALTER EXTENSION UPDATE scripts - #70

Merged
seanwevans merged 1 commit into
mainfrom
claude/pg-git-upgrade-deps-rk0oxk
Sep 3, 2026
Merged

seanwevans merged 1 commit into
mainfrom
claude/pg-git-upgrade-deps-rk0oxk

Conversation

@seanwevans

Copy link
Copy Markdown
Owner

The problem

PostgreSQL discovers upgrade scripts by filename only: it looks for pg_git--<from>--<to>.sql in the extension directory. The repository's upgrade scripts were named pgit-version-updates.sql, pgit-version-updates-0.2.0--0.3.0.sql and pgit-version.sql, so the extension machinery never found any of them. DATA listed only the install entrypoint, so make install never copied an upgrade script either. And there was no 0.3.0 → 0.4.0 delta at all.

ALTER EXTENSION pg_git UPDATE could not work from any version.

The legacy files could not simply be renamed. Each began with ALTER EXTENSION pg_git UPDATE TO '<version>' — recursive when run as an upgrade script — and pulled its content in with psql \i includes, which the server cannot process when it runs an extension script.

The fix

Generate the upgrade scripts from the same fragments as the install entrypoint. Every fragment is attributed to the version that introduced it (V0_1_0_PARTS … V0_4_0_PARTS); a fresh install of version N is the concatenation of every list through N, and the N-1 → N upgrade script is exactly the list for N. The two paths cannot drift because they are built from one source.

  • sql/pg_git--0.1.0--0.2.0.sql, sql/pg_git--0.2.0--0.3.0.sql, sql/pg_git--0.3.0--0.4.0.sql (generated, committed)
  • DATA now includes them, so make install actually installs them
  • make check-parts fails the build if a fragment is added to the install without being attributed to a version — otherwise it would silently go missing for everyone who upgrades
  • sql/pgit-update.sql deleted: a third stale copy of the same 0.1.0 → 0.2.0 content, already excluded from the build

sql/pg_git--0.4.0.sql is byte-identical. This changes only the upgrade path, not what a fresh install produces.

Verification

On PostgreSQL 16: installed 0.1.0 and walked 0.2.0 → 0.3.0 → 0.4.0, then diffed against a fresh 0.4.0 install.

Check Result
Extension member objects identical (140)
Table columns identical (164)
Constraints identical (82)
pg_get_functiondef for every function identical
CREATE EXTENSION pg_git VERSION '0.3.0' resolves via the chain
bare ALTER EXTENSION pg_git UPDATE reaches 0.4.0

🤖 Generated with Claude Code

https://claude.ai/code/session_017nq3xZcPqSTKtskyP2DzkK


Generated by Claude Code

PostgreSQL discovers upgrade scripts by filename only: it looks for
pg_git--<from>--<to>.sql in the extension directory. The repository's
upgrade scripts were named pgit-version-updates.sql,
pgit-version-updates-0.2.0--0.3.0.sql and pgit-version.sql, so the
extension machinery never found any of them, no upgrade script was
listed in DATA so `make install` never copied one either, and there was
no 0.3.0 -> 0.4.0 delta at all. `ALTER EXTENSION pg_git UPDATE` could
not work from any version.

The legacy files could not be renamed as-is: each began with
`ALTER EXTENSION pg_git UPDATE TO '<version>'` (recursive when run as an
upgrade script) and pulled its content in with psql \i includes, which
the server cannot process when it runs an extension script.

Generate the upgrade scripts from the same fragments as the install
entrypoint instead. Every fragment is attributed to the version that
introduced it (V0_1_0_PARTS ... V0_4_0_PARTS); a fresh install of
version N is the concatenation of every list through N, and the
N-1 -> N upgrade script is exactly the list for N. The two paths cannot
drift because they are built from one source, and `make check-parts`
fails the build if a fragment is added to the install without being
attributed to a version.

Also add the upgrade scripts to DATA so they are actually installed, and
drop sql/pgit-update.sql, which was a third stale copy of the same
0.1.0 -> 0.2.0 content and was already excluded from the build.

sql/pg_git--0.4.0.sql is byte-identical: this changes only the upgrade
path, not what a fresh install produces.

Verified on PostgreSQL 16 by installing 0.1.0 and walking
0.2.0 -> 0.3.0 -> 0.4.0, then diffing against a fresh 0.4.0 install:
identical extension membership (140 objects), identical table columns
(164), constraints (82) and function definitions. `CREATE EXTENSION
pg_git VERSION '0.3.0'` and a bare `ALTER EXTENSION pg_git UPDATE` both
resolve correctly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017nq3xZcPqSTKtskyP2DzkK
@seanwevans
seanwevans merged commit a90da8a into main Sep 3, 2026
2 checks passed
@seanwevans
seanwevans deleted the claude/pg-git-upgrade-deps-rk0oxk branch September 3, 2026 23:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants