test/native_upgrade_converge.sh upgrades from frozen fixtures in test/fixtures/, and its own words say what they are for:
Each released starting point must upgrade to an identical catalog.
For 1.0-alpha2 the fixture is not the released starting point, and for 1.0-alpha no such release exists.
This is not caused by #899. I found it reviewing that PR and confirmed both fixtures are byte-identical between main and its head.
How the fixtures are made, and why that is the bug
A fixture is created by renaming the root base-install script when the next cycle opens — 4878567 did it for 1.0-alpha2, and #899 does the same for 1.0-alpha3. A rename at cycle-open equals the release only if nothing touched the file between the tag and the rename.
Counted, on main:
commits touching pgcolumnar--1.0-alpha2.sql after v1.0-alpha2: 3
4878567 release: open the 1.0-alpha3 cycle and report sorted_kind (#761) <- the rename
f21b7aa fix: set_options must refuse with 42809, not plpgsql's default P0001
62db78a fix: set_options must refuse a relation that is not columnar
commits touching pgcolumnar--1.0-alpha3.sql after v1.0-alpha3: 0
So the 1.0-alpha2 fixture is the released base script plus two post-release fixes. Sizes agree with that: 77606 bytes at the tag, 80524 bytes as the fixture.
The 1.0-alpha3 fixture #899 adds is exactly right — its blob sha equals the file at v1.0-alpha3. That is timing, not construction: nothing happened to touch the file during that cycle.
1.0-alpha is a different shape of the same problem
v1.0-alpha shipped default_version = '1.0-dev' and contains no pgcolumnar--1.0-alpha.sql at all — only pgcolumnar--1.0-dev.sql. The CHANGELOG already records this (1.0-dev, which the v1.0-alpha tag installed).
So test/fixtures/pgcolumnar--1.0-alpha.sql is a base install script for a version that was never released as one. A user at 1.0-alpha reached that catalog by running the 1.0-dev--1.0-alpha upgrade script, not by installing this file. The convergence arm for 1.0-alpha therefore starts from a state that exists only inside the test.
Why it matters, stated at the strength I can support
The arm's purpose is to catch an upgrade script that does not reproduce the current base catalog from a real user's starting point. Two of the three starting points are not real user states:
- from
1.0-alpha2: a real user has the 77606-byte script. If either post-release set_options fix changed a catalog object in a way the 1.0-alpha2--1.0-alpha3 upgrade script assumes is already present, the arm would pass while a real upgrade diverged.
- from
1.0-alpha: no user installed that base at all.
I have not shown that either actually diverges. That would need running the convergence check against the true released scripts, which is the natural fix and also the test for it.
Suggested fix
Take the fixtures from the tags rather than from the working tree at cycle-open, and assert it:
- add a check that each
test/fixtures/pgcolumnar--<v>.sql matches pgcolumnar--<v>.sql at v<v> — a hash comparison, so it costs nothing and cannot silently drift again;
- for
1.0-alpha, either drop the arm or replace it with a 1.0-dev fixture taken from v1.0-alpha, which is what that tag actually installed.
The second half is what makes this stick. Without a check, the next cycle-open reproduces the same fixture by the same rename and the only thing standing between the fixture and the release is whether anyone happened to patch that file mid-cycle.
test/native_upgrade_converge.shupgrades from frozen fixtures intest/fixtures/, and its own words say what they are for:For
1.0-alpha2the fixture is not the released starting point, and for1.0-alphano such release exists.This is not caused by #899. I found it reviewing that PR and confirmed both fixtures are byte-identical between
mainand its head.How the fixtures are made, and why that is the bug
A fixture is created by renaming the root base-install script when the next cycle opens —
4878567did it for1.0-alpha2, and #899 does the same for1.0-alpha3. A rename at cycle-open equals the release only if nothing touched the file between the tag and the rename.Counted, on
main:So the
1.0-alpha2fixture is the released base script plus two post-release fixes. Sizes agree with that: 77606 bytes at the tag, 80524 bytes as the fixture.The
1.0-alpha3fixture #899 adds is exactly right — its blob sha equals the file atv1.0-alpha3. That is timing, not construction: nothing happened to touch the file during that cycle.1.0-alphais a different shape of the same problemv1.0-alphashippeddefault_version = '1.0-dev'and contains nopgcolumnar--1.0-alpha.sqlat all — onlypgcolumnar--1.0-dev.sql. TheCHANGELOGalready records this (1.0-dev, which the v1.0-alpha tag installed).So
test/fixtures/pgcolumnar--1.0-alpha.sqlis a base install script for a version that was never released as one. A user at1.0-alphareached that catalog by running the1.0-dev--1.0-alphaupgrade script, not by installing this file. The convergence arm for1.0-alphatherefore starts from a state that exists only inside the test.Why it matters, stated at the strength I can support
The arm's purpose is to catch an upgrade script that does not reproduce the current base catalog from a real user's starting point. Two of the three starting points are not real user states:
1.0-alpha2: a real user has the 77606-byte script. If either post-releaseset_optionsfix changed a catalog object in a way the1.0-alpha2--1.0-alpha3upgrade script assumes is already present, the arm would pass while a real upgrade diverged.1.0-alpha: no user installed that base at all.I have not shown that either actually diverges. That would need running the convergence check against the true released scripts, which is the natural fix and also the test for it.
Suggested fix
Take the fixtures from the tags rather than from the working tree at cycle-open, and assert it:
test/fixtures/pgcolumnar--<v>.sqlmatchespgcolumnar--<v>.sqlatv<v>— a hash comparison, so it costs nothing and cannot silently drift again;1.0-alpha, either drop the arm or replace it with a1.0-devfixture taken fromv1.0-alpha, which is what that tag actually installed.The second half is what makes this stick. Without a check, the next cycle-open reproduces the same fixture by the same rename and the only thing standing between the fixture and the release is whether anyone happened to patch that file mid-cycle.