Repository navigation
test: native_index_projection gets its pytest twin, and every oracle reads the index it names (#1341) - #1480
Conversation
…reads the index it names (#1341) The oracles comparing an index scan with a sequential scan set enable_seqscan=off, which does not disable the columnar custom scan. Measured: the late-column, expression and text-expression oracles, and the expression point lookup, ran as the custom scan on both sides, so a sequential scan was compared with itself; dropping w_expr before them left the shell green. The index side now turns the custom scan off, and each oracle asserts, as a premise, the index its own query reads. The premise reads the oracle query itself, fenced with OFFSET 0: without the fence the aggregate's ORDER BY sent the late-column oracle down a full scan of w_k12 with its predicate as a filter, two minutes at 60,000 rows. The md5-shape failure now records under the oracle's own name. test_native_index_projection.py carries all 41 checks by the shell's name in four tests, building the parallel indexes after the serial oracles as the shell does. Its oracle table joins the loop-reader guard's list. COMPLETE gains native_index_projection, TESTS.md section 163, cluster_tests 698 -> 702. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… two projection mutations (#1341) The suite had no rows. suites_not_covered 203 -> 202; census 4048 rows / 2923 never / 1125 dated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
82a31a2 to
a08464a
Compare
|
@jdatcmd #1451, #1459 and #1475 landed under this, so I've restated it onto main
The PR body still quotes the pre-restate census (4047 / 2929 / 1118). The commit and the files are right. One thing on main, not from this PR: #1475 renamed its five rows in place, so 🤖 Generated with Claude Code |
jdatcmd
left a comment
There was a problem hiding this comment.
Approve, at a08464a. Against 82a31a2, your restate leaves the patches of all five test files and the ledger rows unchanged; only the budget paragraph is re-anchored. So this evidence, measured at 82a31a2, holds here.
My own mutant, different from yours: in pgcolumnar_index_build_range_scan, skip every 997th row, but only for an expression index (if (index_info->ii_Expressions != NIL && rowNumber % 997 == 0) continue;). The projection count stays right, so only a real oracle can see it. PG17:
| shell | result under the mutant |
|---|---|
main's native_index_projection.sh |
35/35 green |
| yours | 2 red: expression index agrees and text expression index agrees (md5 mismatch) |
| your pytest twin | 1 red: expression index agrees |
The clean build afterwards is 41/41. So the custom-scan-off change and the per-oracle plan premise are what give these oracles teeth.
One note, not blocking. The twin found 1 red where the shell found 2, because expect raises on the first failing arm and all five oracles sit in one test function. A red there hides the oracles after it. If you want the twins' failure output to match, give each oracle its own test (or parametrize it).
#1479 also adds one ledger row (census 2889 -> 2890), so whichever of us merges second re-anchors.
|
@OffgridwithJD, merging #1480 now: approved at a08464a, 15/15 green, CLEAN. |
Stacked on #1477 (merge after it). Two commits:
3b4bff5a(the twin and the shell fix) and82a31a21(the ledger seed).What was wrong
The oracles compare an index scan with a sequential scan, but their "index" side only set
enable_seqscan=off, which doesn't disable the columnar custom scan. Measured plans (PG18):So three oracles compared a sequential scan with itself. With
w_exprdropped before the oracles, the old shell stayed green on the expression oracle. The fixes:pgcolumnar.enable_custom_scan=off.Turning the custom scan off exposed a second problem. The aggregate's
ORDER BYsent the late-column oracle down a full scan ofw_k12with its predicate as a filter, fetching every row through the index: over 120 s at 60,000 rows, and the 300,000-row run blew its 30-minute limit. The premise therefore reads the oracle query itself, fenced withOFFSET 0, and every oracle reads its own index in milliseconds. The suite runs in 18 s.The md5-shape failure now records under the oracle's own name. A separate failure-only name left an orphan ledger row.
Measured (PG18)
DROP INDEX w_exprbefore the oracles (harness)premise: expression index agrees -- the index side reads w_exprii_Expressions' columnsii_Predicate's columnsThe twin
test_native_index_projection.pycarries all 41 checks by the shell's name (compare_to_bash: every property covered), in four tests. As in the shell, the parallel indexes are built after the serial oracles. When they came first, the planner tookw_parfor the plain oracle. The build lines come from psycopg notice handlers atclient_min_messages=debug1. The oracle table joins the loop-reader guard's list.Runs
Head is 41/41 in both twins on each of 15, 16, 17, 18 and 19, at the full 300,000 rows.
Ledger
suites_not_covered203 → 202. The census is 4047 / 2929 / 1118.pgc_ledger.py gatereturns rc 0, andorphan-scanreports 0 orphans.Counts and guards
cluster_tests698 → 702, and pytest collects 702.COMPLETEgains the suite, and TESTS.md gains §163.harness_selftest.shpasses, anddocs_style.shpasses.A note for the product, outside this PR: a full index scan of a 20-column columnar table fetches at roughly 2 ms a row (60,000 rows in over 120 s), while the same query on the columnar scan takes 15 ms.
🤖 Generated with Claude Code