test: compile against every major before merge#166
Conversation
main did not compile on PostgreSQL 17 for a few hours, and the gate that approved the change could not have caught it. scan_analyze_next_block changed signature at PG17; #159 guarded the callback body at PG18; PG15 and PG16 build because they really are pre-17, PG18 and PG19 because they are past both guards. PG17 is the only major where the mismatch exists, and the per-PR cadence is PG18 and PG19. That cadence is the right trade for test time. What it cannot do is see a defect on a major it never builds, so this is the cheap half of the answer: no clusters, no suites, a compile against each installed major, about a minute for all five. Run it before merging anything that touches a version guard, a table AM callback signature, or columnar_compat.h. Proven by reintroducing the exact defect. With the guard back at 180000: PG15, PG16, PG18 and PG19 report OK and PG17 fails with src/columnar_tableam.c:619:67: error: 'blockno' undeclared Unmutated, all five report OK with zero warnings. It also reports warning counts per major, since -Werror is not set and a warning that only appears on one major would otherwise accumulate unnoticed, and it cleans the object tree afterwards so the next build against a different major cannot link objects compiled for this one. Allowlisted in the harness self-test rather than registered as a suite, with the reason recorded there: it takes no cluster and reports per major, so the matrix cannot run it the way it runs a suite. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uKWWwBDt5TWWS5DR2tzDb
ChronicallyJD
left a comment
There was a problem hiding this comment.
Approving. This is the gate that would have stopped my defect, and I verified it does rather than taking the table on trust.
Reproduced independently
I built PostgreSQL 17.6 with --enable-cassert -O2 for this — I had never built on 17 at all, which is the root of #163 — and ran your script against my own two majors:
== pgColumnar build check across majors ==
OK PostgreSQL 17.6 0 warning(s)
OK PostgreSQL 18.4 0 warning(s)
build_all_versions.sh: PASSED
Then reverted both guards to 180000, which is exactly what shipped:
FAIL PostgreSQL 17.6
src/columnar_tableam.c:619:67: error: 'blockno' undeclared
OK PostgreSQL 18.4 0 warning(s)
build_all_versions.sh: FAILED
Same line, same error, non-zero exit. It catches the real thing on a different machine with different builds at different paths.
That last part matters more than it looks: DEFAULT_CONFIGS hardcodes paths I do not have, and the script took explicit pg_config arguments without modification. A build gate that only works on the author's layout is a gate one person runs.
The three decisions I would have got wrong
Warning counts per major. Without -Werror, a warning that appears on exactly one major is invisible in a per-major pass/fail, and it is the same shape of defect as the one this fixes — something true on a major nobody looks at. Reporting the count makes a new warning on 15 as visible as an error.
Cleaning between majors. Necessary, and my container proves the failure mode is live: I found src/columnar_index.o sitting in the tree, left from building #158 earlier. It is harmless here because PGXS links $(OBJS) and that file is not in main's list — but it survived make clean precisely because it is not in OBJS, so an object built against one major can outlive a switch away from the branch that introduced it. Your per-major clean is what keeps that from mattering.
Allowlisting rather than registering. Right, and the reasoning is the interesting part: it takes no pg_config per run and reports per major, so the matrix cannot drive it the way it drives a suite. #161 is what turned that from an omission into a decision someone had to write down — the two changes compound, which is the sign both were aimed at the same thing.
On the cadence
Agreed, and I would put the boundary where you have it: the per-PR PG18-and-PG19 cadence is the right trade for test time, and the thing it cannot do is see a defect on a major it never builds. Compiling is not testing, so this does not shrink the matrix — it covers the one class the matrix is structurally blind to, for about a minute.
I have already adopted it. #164 now builds on 17 and 18 with zero warnings, and the full suite passes 77/77 on the PG17 assert build, which is the first time anything of mine has run on 17.
One thing this does not cover, worth saying out loud
A guard boundary can be wrong in the other direction — code compiled on every major that is semantically wrong on one, say a callback that builds fine at 17 but is handed a stream it treats as a block number. This catches the compile error, which is the common case and the cheap one. The matrix is still what catches the rest, and I would not want the existence of a build gate to read as coverage of version-guarded behaviour.
Verdict
Approving. Verified against the real defect on an independent set of builds, and the three design decisions all go the way that makes it survive contact with someone else's machine.
Follow-up to #163, which fixed
mainnot compiling on PostgreSQL 17. This makes that hard to repeat.Why the gate could not catch it
scan_analyze_next_blockchanged signature at PG17. #159 guarded the callback body at PG18. PG15 and PG16 build because they really are pre-17; PG18 and PG19 build because they are past both guards. PG17 is the only major where the mismatch exists, and the per-PR cadence is PG18 and PG19.That cadence is the right trade for test time. What it cannot do is see a defect on a major it never builds.
The cheap half of the answer
test/build_all_versions.sh: no clusters, no suites, a compile against each installed major. About a minute for all five. Run it before merging anything that touches a version guard, a table AM callback signature, orcolumnar_compat.h. The full matrix stays the thorough half.Proven against the real defect
Reverting the guard to
180000, which is exactly what shipped:Not a synthetic mutation: that is the defect that reached
main.Two details
It reports warning counts per major, since
-Werroris not set and a warning appearing on only one major would otherwise accumulate unnoticed. And it cleans the object tree afterwards, so a later build against a different major cannot link objects compiled for this one, which is a trap this project has hit before.Allowlisted in the harness self-test rather than registered as a suite, with the reason recorded inline: it takes no
pg_configper run and reports per major, so the matrix cannot run it the way it runs a suite. The #161 guard is what forced that to be a deliberate decision rather than an omission.Gate
PG18 and PG19, full suite,
ALL VERSIONS PASSED,harness_selftest=PASS, which is the suite this change actually touches.