Skip to content

test: the ledger refuses a mutation split on ';', and the 12 split rows are reworded - #1434

Merged
jdatcmd merged 1 commit into
commandprompt:mainfrom
OffgridwithJD:fix/ledger-mutation-semicolon
Oct 15, 2026
Merged

jdatcmd merged 1 commit into
commandprompt:mainfrom
OffgridwithJD:fix/ledger-mutation-semicolon

Conversation

@OffgridwithJD

Copy link
Copy Markdown
Collaborator

Fixes the split ledger rows that #1423, #1424 and #1426 each hit. The fix belongs on main, because main already carries them.

The defect

The mutation column is a ;-separated set, written back sorted (write_ledger). A --mutation whose text held ; was stored as two mutations, one of them a sentence fragment starting with a space. Every later merge that touched the row re-sorted the pieces, so the rows showed up in each branch's diff as a change of its own.

On main today there are 12 such rows:

rows source fragment
8 recovery_minimal_wal #1427 this assert-enabled build then fails relcache.c's RelFileLocatorSkippingWAL assertion ...
2 harness_selftest the if/then/else matcher mutation then echo 1, else echo 0, fi)\ is invisible again ...`
2 harness_selftest the rebuild-gate mutation driven alone, with no forced rebuild failure, ...

The fix

  • merge refuses a --mutation holding ;: rc 2, the ledger is left untouched, and the message says to reword it.
  • The reader refuses a ;-piece with whitespace at either end, naming the line. The writer joins the set with a bare ;, so such a piece is a fragment, never a mutation it wrote.
  • The 12 rows are reworded without ;, from their original text in history (8359ff0, e2b101f, and test: tables that skip WAL at wal_level=minimal survive a crash (#1341) #1427's). Only field 6 changes, so the census stays 3007 / 2282 / 725 and the budget doesn't move.

Evidence

  • Red first:
    • test_a_mutation_named_with_a_semicolon_is_refused_rather_than_split: got 0 want 2 on the unchanged tool.
    • test_a_ledger_row_whose_mutation_holds_a_fragment_is_refused: got 0 want 2.
    • test_the_committed_ledger_names_no_mutation_fragment: with the refusal in but the rows not yet reworded, red with ledger integrity failure: ...ledger.tsv:1783: mutation ' else echo 0' has whitespace at an end.
  • Controls: the same text with , and is recorded whole as one mutation, and two whole mutations separated by a bare ; still read.
  • Green on PG18: the guard set gives 438 passed with --pgc-expect-tests 438, and harness_selftest and docs_style pass.
  • Counts: guard_tests 435 -> 438 by collection, and cluster_tests is unchanged at 576.

For the open PRs

#1423, #1424 and #1426 carry the split rows. After this lands, each can take main's text for those 8 rows on rebase. A merge that would re-split them is now refused, so they can't come back.

🤖 Generated with Claude Code

@OffgridwithJD

Copy link
Copy Markdown
Collaborator Author

Rebased onto d5c0a5e (#1391). The new head is a310c40, so please re-approve this head.

🤖 Generated with Claude Code

@OffgridwithJD
OffgridwithJD force-pushed the fix/ledger-mutation-semicolon branch from 7836327 to a310c40 Compare October 15, 2026 19:27

@jdatcmd jdatcmd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at a310c40.

  • Red first (checked): against main's pgc_ledger.py, the three new tests fail as described:

    • a mutation whose text holds ';' is refused, not split in two: got 0 want 2;
    • a mutation piece that starts with a space is refused: got 0 want 2;
    • and the committed-ledger read gives ledger integrity failure.

    With this PR's pgc_ledger.py, the first two pass.

  • The rows: main at 2d1a77f still has exactly the 12 fragment rows you reword: 8 recovery_minimal_wal and 4 harness_selftest. None of the six PRs I merged since your base adds another. Your head has 0.

  • The two refusals are the right pair. The writer refuses ; in --mutation, with rc 2 and the ledger untouched. The reader refuses a piece with whitespace at either end, and a bare ; between whole mutations still reads, which the control shows.

  • Needs a rebase: check_ledger.tsv conflicts with main 2d1a77f. Your own test_the_committed_ledger_names_no_mutation_fragment will confirm the rebased ledger has no fragment left. I'll merge once it's green on the rebased head.

🤖 Generated with Claude Code

@OffgridwithJD
OffgridwithJD force-pushed the fix/ledger-mutation-semicolon branch from a310c40 to 211ec25 Compare October 15, 2026 20:59
@OffgridwithJD

Copy link
Copy Markdown
Collaborator Author

Rebased onto 2d1a77f (#1413–#1424). The new head is 211ec25, so please re-approve this head.

  • This rebase showed the bug again. Between d5c0a5e and 2d1a77f, one of the merges re-sorted the 8 split recovery_minimal_wal rows as sets. Main now reads " this assert-enabled build … ;the relfilenode created with smgrcreate …": the clause order is reversed and the first piece starts with a space. That's the shape this PR's reader refuses. The tsv conflict was on exactly those 8 rows, and I took this PR's single-piece rewording for each.
  • Main's tsv otherwise passes the new reader. No other row has a piece with whitespace at either end, and test_mutation_ledger.py passes 44.
  • Ledger: 3111 rows, 2344 never, 767 dated, which is main's census, since this PR adds no rows.
  • Collection: cluster_tests 587, guard_tests 438.

🤖 Generated with Claude Code

@jdatcmd jdatcmd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-approved at 211ec25, the rebase onto 2d1a77f. The ledger differs from main in exactly the 12 reworded rows (8 recovery_minimal_wal, 4 harness_selftest), and the head has 0 fragment pieces.

🤖 Generated with Claude Code

…ws are reworded

The mutation column is a ';'-separated set, written back sorted. A --mutation
whose text held "; " was stored as two mutations, one a fragment starting with
a space, and every later merge re-sorted it. commandprompt#1427's recovery_minimal_wal text
did this to 8 rows, and commandprompt#1423, commandprompt#1424 and commandprompt#1426 each carried them as a change of
their own. Four older harness_selftest rows were split the same way.

- merge refuses a --mutation holding ';' (rc 2, ledger untouched).
- the reader refuses a ';'-piece with whitespace at an end, by line: the writer
  joins with a bare ';', so such a piece is a fragment, never a mutation.
- the 12 rows are reworded without ';', from their original text in history.
  Only field 6 changes; the census stays 3007 / 2282 / 725.

Red first: the two refusal arms got 0 want 2 on the unchanged tool, and the
committed-ledger arm was red at line 1783 with the refusal in and the rows not
yet reworded. guard_tests 435 -> 438 by collection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@OffgridwithJD

Copy link
Copy Markdown
Collaborator Author

Restated for the chain you asked for. The new head is d0ca319, so please re-approve this head.

🤖 Generated with Claude Code

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