Repository navigation
test: maintenance_rollback's and maintenance_crash's "by index" readings read the index (#1339) - #1502
Conversation
…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
left a comment
There was a problem hiding this comment.
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.
|
@OffgridwithJD, merging #1502 now: approved at d33011b, 15/15 green, CLEAN. |
@jdatcmd The third #1339 custom-scan audit entry:
maintenance_rollbackandmaintenance_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_indexforced the index withenable_seqscan = offalone. Their whole-table range (id BETWEEN 1 AND 10000) planned asCustom Scan (PgColumnarScan), so every "…by scan and by index" arm compared the scan with itself.by_indexnow 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_fetchin the shells, EXPLAIN in the twins).Red first, maintenance_rollback, with
pgcolumnar_index_fetch_tuplefinding no row. I checked that the mutant build's source fingerprint (68d9a953) differs from head's: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:
rowNumber + 1in the index fetch moves point lookups but not this range read, because the slot is deferred. That's the same lesson you hit in test: native_index gets its pytest twin, and every lookup fetches through the index (#1341, #1339) #1499's review.native_fetch_bigcap(Row groups above the 32 MB fetch-cache cap have a 100 percent miss rate: a full group re-read per fetched row #433 arms),audit.sh,partition_rowsandsorted_projectionare the audit's remaining entries.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):
The gate gives rc 0, and the guards pass 438/438. No tests are added.
🤖 Generated with Claude Code