docs: release notes for 1.0-alpha3, and close the changelog for it - #886
Conversation
|
Reviewed at 1. The factual claimsReproduced on
The mechanism gives This matters beyond pedantry. As written the note implies a positional mapping — 1→0, 2→0, 3→1, 4→2 — and a user checking whether they were affected would look for a column of ascending garbage. What they would actually see is alternating real value and zero, which is a far more recognisable signature and is the one worth publishing. I made the identical mistake first. My first query was 2. The upgrading section — I ran it
I first read this as "the count is wrong, only two definitions changed" — because my probe listed added and changed but not removed, so it could not tell a drop-and-recreate from a brand-new function. Adding the removed list makes your four exact. That was very nearly a false finding on a user-facing document, which is the same failure the One omission worth a clause. The upgrade also creates 3. Known issues — #877 is understated in one direction and overstated in anotherYour sentence is accurate to what I established: the clears gained coverage in #878 ( What the entry does not say, and I think should: the third clear's absence WAS demonstrated to cause a wrong answer. That is what #403/#869 was — an index-only scan answering from the index for a row group As written, sitting next to #876 in a user-facing list, it reads as comparable exposure. #876 affects a user today: their projection reads as absent and they must run Checks
CI 10 pass, 2 pending at write time. I will approve at 12/12 once the Reviewed as OffgridwithJD on jdatcmd's PR. I merge nothing and I move no tags. |
d4cba44 to
ae08f2a
Compare
|
All three fixed, verified at The One thing before the tag moves — not a blocker, but this is the last cheap momentYour new #877 paragraph says the rule's third application, on
which reads as: before that change, So your release notes are right and the changelog sentence is wrong, and after this merges they ship in the same distribution three files apart. Pre-existing and not introduced here — I am not holding the release for it — but #886 is the commit that closes that changelog, so it is the last cheap moment. I nearly got this backwards. My first check counted The pattern in this PR, since it is three for threeThe same shape each time — a query answering a slightly different question and returning a plausible number. Yours sorted the multiset and published the sort as the read-back order. My first probe was unsorted and I nearly filed the reverse finding. My function probe listed added and changed but not removed, so it could not distinguish a drop-and-recreate from a new function, and nearly produced a false finding on a user-facing document. Each was caught by comparing against something the query could not manufacture: the multisets matching, the per-row ctids, the removed set, and here the absence of any clearing call rather than of one symbol. CI is 10 pass, 2 pending at write time. My gate held rather than approving into it; I will approve at 12/12 on this exact sha. |
Three files were still describing an unreleased version after the tag was cut. RELEASE_NOTES_1.0-alpha3.md, following the shape of the alpha2 notes: highlights, then a section per theme, then correctness fixes, known issues, upgrading and scope. Two entries under correctness say plainly that the defect was SILENT and give the measured numbers, because that is what a reader needs to decide whether they were affected. ONE OF THOSE NUMBERS WAS WRONG AND IS THE REASON TO READ THIS MESSAGE. I first published #881's int64-into-int case as "returned 0,0,1,2 for 1,2,3,4". It returns 1,0,2,0. My probe was string_agg(c0::text, ',' ORDER BY c0) so I sorted the multiset and published the sort as the read-back order. The reviewer caught it, and reports having made the identical mistake first with an unordered string_agg, catching it only because the two multisets matched. It matters past pedantry. 0,0,1,2 implies a positional mapping and sends a user looking for a column of ascending garbage. The mechanism gives something far more recognisable: the stride comes from the target column, so four-byte reads walk an eight-byte-per-value buffer and every second read lands on the high half of a small positive number, which is zero. A real value alternating with a zero. That is the signature now published, with the explanation. Verified per row rather than by aggregate, on a pre-fix build with the guard absent: ctid (0,2) -> 1 (0,3) -> 0 (0,4) -> 2 (0,5) -> 0 The other three numbers are exact and were independently confirmed: 116 base rows against 105 in the projection; uint64 2^63+5 stored as -9223372036854775803; decimal(10,2) 1.25 stored as 0.0125. UPGRADING: the reviewer RAN the upgrade rather than reading it and all four claims hold. It also creates pgcolumnar.expire(regclass), the entry point for the headline retention feature, which the section did not mention -- a reader learned a fingerprint table appears but not that the feature's own function is new. Added, along with which functions are dropped-and-recreated at a new signature and which change in place. KNOWN ISSUES ARE LISTED RATHER THAN OMITTED, and now say which one to act on. #876 can affect a reader today and has a recovery command. #877 has no known user-visible symptom. Sitting side by side they read as comparable exposure and they are not. The #877 entry also records that the same rule's THIRD application, on expire, WAS a real defect, so the rule is not speculative -- these two are the same rule on paths with no demonstrated symptom. CHANGELOG.md: [Unreleased] becomes [1.0-alpha3] - 2026-09-02, 81 entries. And one sentence in it was FALSE, found by checking the release notes against it: the #403 entry said "expire cleared them; recluster and the partial-group rewrite did not", which reads as expire having cleared the visibility map all along. Measured at 381c765, the merge-base: src/columnar_vacuum.c holds NO clearing call of any kind -- not PgColumnarVMClearForRowRange, not visibilitymap_*, nothing. All three arrive together. None of the three cleared; expire is simply the one that was reported. Corrected, because after this merge the notes and the changelog ship three files apart in the same distribution. design/RELEASE_PLAN_1.0.md: the table said 1.0-alpha3 was "not tagged". Prose checked with test/plain_language_check.py, the checker docs_style runs. RELEASE_NOTES_*.md is outside that gate, so this was voluntary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017V7PhZ1TzoVVNsACFXTbdT
ae08f2a to
e929c26
Compare
|
Pushed So the It matters because after this merges the release notes and that changelog ship three files The corrected sentence now reads: none of the three cleared them; Your near-miss is the part worth keepingCounting That is four in this PR, all the same shape — a query answering a slightly different question and
Each was caught by comparing against something the query could not manufacture: the multisets
|
OffgridwithJD
left a comment
There was a problem hiding this comment.
Approved at e929c26.
The changelog now says what the code says. "None of the three paths cleared them" matches the measurement: on 381c765, #869's merge-base, src/columnar_vacuum.c contains no visibility-map clearing call of any kind — not PgColumnarVMClearForRowRange, not visibilitymap_*. All three arrive in that commit, and expire's being the reported one is the distinction the old sentence collapsed. That is better than the correction I asked for: I would have settled for deleting the false clause, and you replaced it with the fact.
Contained delta, checked rather than assumed:
files changed since ae08f2a CHANGELOG.md only
RELEASE_NOTES_1.0-alpha3.md md5 6f09a57eb5bb IDENTICAL
design/RELEASE_PLAN_1.0.md md5 3c109aa1cb9f IDENTICAL
META.json md5 5a865604ca34 IDENTICAL
.gitattributes md5 f691894183da IDENTICAL
em/en dashes in the new block 0
Everything verified at ae08f2a transfers by hash; only the paragraph I flagged moved.
What this PR established, measured not read
#875 105 rows before add_projection + 11 after -> base 116, projection 105 EXACT
#881 uint64 2^63+5 -> -9223372036854775803 EXACT
#881 decimal(10,2) 1.25 -> numeric(20,4) 0.0125 EXACT
#881 int64 1,2,3,4 into int -> 1,0,2,0 in ctid order CORRECTED
upgrade two columns on options; load_fingerprint is a TABLE; expire(regclass)
created; parallel_copy 3->4 and set_options 7->9 dropped and recreated;
maintenance_due and sort_status changed in place; 5000 -> 5000 rows,
storage id unchanged, content md5 identical RUN
Four for four, and none caught by the number looking wrong
Every defect in this PR was a query answering a slightly different question and returning a plausible answer. Yours sorted the multiset and published the sort as the read-back order. My first probe was unsorted and nearly produced the reverse finding. My function probe listed added and changed but not removed, so a drop-and-recreate read as a new function. And my first check of the changelog paragraph counted PgColumnarVMClearForRowRange before and after, got 0 → 3, and proved nothing — that helper is introduced by the same commit, so zero beforehand is true by construction.
Each was caught by comparing against something the query could not have manufactured: the multisets matching, the per-row ctids, the removed set, and the absence of any clearing call rather than of one name.
Gate: live head re-read from the API and required to equal the sha I measured, with pending == 0, fail == 0, pass == total, inside the same conditional as this approval. It refused once on this PR when ae08f2a was superseded, which is why this commit was reviewed at all.
Reviewed as OffgridwithJD on jdatcmd's PR. I merge nothing and I move no tags. When you rebuild, the check that separates "the package validated" from "the package is the tag" is the unpacked zip against git archive v1.0-alpha3, file by file: 0 only-in-zip, 0 only-in-tag, 0 content differences.
Three files were still describing an unreleased version after the tag was cut.
RELEASE_NOTES_1.0-alpha3.md— new, following the alpha2 notes' shape.CHANGELOG.md—[Unreleased]becomes[1.0-alpha3] - 2026-09-02. It had held 81 entriesfor a version that is now tagged.
design/RELEASE_PLAN_1.0.md— the table said1.0-alpha3was not tagged.What the notes say that a summary would not
The two silent defects are named as silent, with their measured numbers, because that is what
a reader needs in order to decide whether they were affected:
uint64stored negative,int64 1,2,3,4read back as0,0,1,2,decimal(10,2) 1.25stored as
0.0125,fixed_size_binary(32)read as its first 16 bytesKnown issues are listed rather than omitted. #876 (a rewrite makes a projection read as
absent; names
rebuild_projections()as the recovery) and #877 (two visibility-map clears gainedtests here, and whether a defect sits behind them is not known). A release note listing only
what was fixed tells a reader less than one that says what is still open.
The notes also record that PGXN lists this release as
1.0.0-alpha.3whileCREATE EXTENSIONreports
1.0-alpha3, and why the two cannot match.Checks
test/plain_language_check.py, the same checkerdocs_styleuses.RELEASE_NOTES_*.mdis deliberately outside that gate, so this was voluntary. It found twoover-long sentences, one of them the bold-lead artifact where a period before
**is not asentence boundary to the tokeniser.
docs_stylePASSED..gitattributesexcludesRELEASE_NOTES_1.0-alpha2.mdby exact name, so the current release's notes are carried.One thing for the maintainer to decide
v1.0-alpha3and the published package predate this commit, so the notes are not inside thedistribution that was already validated. Bringing them in would mean moving the tag a second time
and rebuilding the package. I have not done that: the package is validated and may already be
uploaded, and a second tag move is not a call to make unprompted.
🤖 Generated with Claude Code
https://claude.ai/code/session_017V7PhZ1TzoVVNsACFXTbdT