Guard the analyze block callback at PG17, where the signature actually changed - #163
Conversation
…y changed
main does not build on PostgreSQL 17:
src/columnar_tableam.c: In function 'columnar_scan_analyze_next_block':
error: 'blockno' undeclared (first use in this function)
scan_analyze_next_block took (BlockNumber, BufferAccessStrategy) through PG16
and (ReadStream *) from PG17, which is the read-stream ANALYZE rework.
columnar_compat.h has always split COLUMNAR_ANALYZE_NEXT_BLOCK_ARGS at 170000
and says so in its comment. #159 guarded the callback body at 180000 instead, so
PG17 compiled the pre-17 branch against a PG17 signature and referenced a
parameter it does not have.
PG15 and PG16 build because they really are pre-17, and PG18 and PG19 build
because they are past both guards. PG17 is the only major the mismatch can
show up on, which is why a PG18-and-PG19 gate reported the change green: I
approved it on that gate, and the full matrix is what caught this.
The two guards now agree with the compat macro. Builds clean with no warnings
on 15, 16, 17, 18 and 19.
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 my bug and it broke the build on a supported major.
I had the answer in front of me
columnar_compat.h does not merely split at 170000, it says why:
* scan_analyze_next_block() took (BlockNumber, BufferAccessStrategy) through
* PG16 and (ReadStream *) from PG17 (the read-stream ANALYZE rework).
I guarded the callback at 180000 because I knew PG18 has read streams, and never checked when the callback signature changed. I read that header during #159 — I quoted the macro in my own analysis — and took the two branches without reading the #if directly above them. Assuming a boundary while looking at the file that states it is worse than not looking at all.
The include guard was mine too, and your diff fixes both. They have to move together, which is the argument for the comment you put on each.
Why the gate could not see it
PG15 and PG16 are genuinely pre-17, and PG18/PG19 are past both guards, so PG17 is the only major where the mismatch is expressible. The PG18-and-PG19 cadence cannot see a defect that exists only on a major it does not build, and it reported #159 green while main did not compile on 17.
Agreed on the rule, and I would draw it slightly wider: any change touching a COLUMNAR_*_ARGS macro or a PG_VERSION_NUM guard should build all five majors before merge, whatever it gates on. A build is about a minute, and it is the only thing that checks a guard boundary. Compiling is not testing, so this does not replace the matrix — it catches the one class of defect the matrix is structurally blind to.
The failure mode is worth naming: a wrong guard boundary is not a subtle runtime bug, it is a hard compile error on exactly one major. Cheap to find, and invisible if you never build there.
Verified
The compat macro's #else branch supplies (TableScanDesc scan, ReadStream *stream) from 17, and the pre-17 body references blockno, so at PG17 the old code took the pre-17 branch against a signature that has no such parameter. Your five-major build table plus the full 15-through-19 matrix with analyze_stats green on all five is the right evidence, and it is more than I produced for the change that caused this.
Nothing to change.
|
Built PostgreSQL 17.6 with So the fix is complete, not partial: nothing else on
What I could fix is the branch I own. #164 was based on the broken Two things I am carrying forward from this:
|
maindoes not build on PostgreSQL 17. Found re-reviewing #159 after merging it.Why
scan_analyze_next_blocktook(BlockNumber, BufferAccessStrategy)through PG16 and(ReadStream *)from PG17, which is the read-stream ANALYZE rework.columnar_compat.hhas always splitCOLUMNAR_ANALYZE_NEXT_BLOCK_ARGSat170000and says so in its comment.#159 guarded the callback body at
180000. So on PG17 the pre-17 branch was compiled against a PG17 signature and referenced a parameter that signature does not have.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 can appear, which is exactly why the PG18-and-PG19 gate I approved #159 on reported it green.
Fix
Both guards now agree with the compat macro at
170000, with a comment saying the two must stay in step and what happens when they do not.Verification
Builds clean, zero warnings, on all five majors:
Full 15 through 19 matrix:
ALL VERSIONS PASSED, withanalyze_statspassing on all five majors.What this says about the gating rule
The per-PR cadence is PG18 and PG19, with a full matrix once per feature. That is cheap and it is usually right, but it cannot see a defect that exists only on a major it does not build. Any change touching a version-guarded callback should build all five before merge even if it only gates two, which costs about a minute. I approved #159 without doing that.