Skip to content

test: maintenance_rollback's and maintenance_crash's "by index" readings read the index (#1339) - #1502

Merged
jdatcmd merged 4 commits into
mainfrom
test/1339-maintenance-by-index
Oct 16, 2026
Merged

jdatcmd merged 4 commits into
mainfrom
test/1339-maintenance-by-index

Conversation

@OffgridwithJD

Copy link
Copy Markdown
Collaborator

@jdatcmd The third #1339 custom-scan audit entry: maintenance_rollback and maintenance_crash, in both twins. Stacked on #1500 (#1499 → #1500 → this). This PR's own commits are the top two.

The "by index" readings never read the index

Both suites' by_index forced the index with enable_seqscan = off alone. Their whole-table range (id BETWEEN 1 AND 10000) planned as Custom Scan (PgColumnarScan), so every "…by scan and by index" arm compared the scan with itself. by_index now also turns the custom scan off, and each suite gains a premise that the reading is an Index Scan through its index (pgc_uses_row_fetch in the shells, EXPLAIN in the twins).

Red first, maintenance_rollback, with pgcolumnar_index_fetch_tuple finding no row. I checked that the mutant build's source fingerprint (68d9a953) differs from head's:

old suite new suite = twin
index fetch finds nothing 13/13 green 6 red: all five "by index" rollback arms and the savepoint arm

maintenance_crash compares the state after a crash with the state before it, both through by_index. So an index that was broken before the crash too reddens nothing, by design: its arms catch index drift caused by the crash. Before this change the by-index leg was a second scan and couldn't see index drift at all. I don't have a single-gate mutation that drifts the index only across a crash, so its arms stay as they were.

Two side notes:

Five-major runs at head: maintenance_rollback 14/14 and maintenance_crash 25/25, shell and twin alike, on each of 15–19.

Ledger

Census 4332 / 3017 never / 1315 dated (on #1500's 4330 / 3019 / 1311):

  • two new premise rows, both never;
  • four rollback arms that entered never are now dated;
  • the other two gain the mutation in their history.

The gate gives rc 0, and the guards pass 438/438. No tests are added.

🤖 Generated with Claude Code

jdatcmd and others added 4 commits October 16, 2026 17:46
…name, as its twin does (#1339)

The shell set enable_seqscan / enable_indexonlyscan and trusted the arm
names, but none of the enable_* scan GUCs governs Custom Scan
(PgColumnarScan). The index / bitmap and index-only arms planned as the
columnar custom scan, the same path as the sequential arm. The pytest twin
has forced each path with pgcolumnar.enable_custom_scan = off and asserted
the node since it was written; its docstring reported the shell's gap. The
shell now does the same, under the twin's premise names, and gains the
twin's three other checks (the 5000 rows, more than one row group, and the
rolled-back delete left the row).

Red first: with pgcolumnar_fetch_row ignoring the delete mask, the old
shell's "index / bitmap scan sees the live set" and "index-only scan sees
the live set" stayed green. Both are now red in both twins, and the twins
redden the same set by name under each mutation.

The twin's "premise: the table holds all {ROWS} rows" becomes a literal
name, which the grader needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e twin's seven checks to the ledger (#1339)

Census 4330 rows / 3019 never / 1311 dated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ngs read the index (#1339)

Both suites' by_index forced the index with enable_seqscan off, which
leaves the columnar custom scan on. Their whole-table range planned as
Custom Scan (PgColumnarScan), so every "by scan and by index" arm compared
the scan with itself. by_index now also turns the custom scan off, and each
suite gains a premise that the reading is an Index Scan through its index,
in both twins.

Red first, maintenance_rollback, with pgcolumnar_index_fetch_tuple finding
no row (the source fingerprint checked to differ from head): the old suite
passes 13/13, and the new one reddens all six "by index" arms. The twins
redden the same six by name.

maintenance_crash compares the state after a crash with the state before
it, both through by_index, so an index broken before the crash as well
reddens nothing, by design: the arms catch drift the crash causes. Before
this change the by-index leg was a second scan and could not see index
drift at all.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…four rollback arms are dated (#1339)

Census 4332 rows / 3017 never / 1315 dated.

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

@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.

Approve, at d33011b (its own commits e52bcf4 and d33011b, on #1500).

My own mutant, different from yours: the deferred decode (pgcolumnar_slot_getsomeattrs) returns column 1 as NULL on every 7th row number, so it corrupts values rather than losing rows. PG17:

suite shell pytest
maintenance_rollback 5 red: all five "… rolls back, the table holds the same rows and row groups, by scan and by index" (5400/… hash mismatch) red (the first; the rest masked)
maintenance_crash 25/25 green 25/25 green

maintenance_crash staying green under a fault that's there both before and after the crash is exactly the design you describe: its arms catch index drift caused by the crash, and a value fault on both sides cancels out. I agree that's not this PR's to fix. If the crash suite should also vouch for the index reading itself, it needs a heap-mirror arm, not a before/after one. That's a separate entry.

Thanks for the deferred-slot note too; it's the same trap my first #1499 mutant fell into.

@jdatcmd

jdatcmd commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

@OffgridwithJD, merging #1502 now: approved at d33011b, 15/15 green, CLEAN.

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