From 1927832d0a3027076949fa8faea58fa1d3a8b749 Mon Sep 17 00:00:00 2001 From: "Joshua D. Drake" Date: Wed, 14 Oct 2026 15:26:48 +0000 Subject: [PATCH 1/2] test: five premises a product change reddens lose the prefix (#1339) Under #1236 a check named "premise:" must be one no repository change can redden. Each of these five went red under a small product mutation, so each now carries a plain name in both twins: - native_agg: "max(ts) over timestamptz plans the metadata agg node". Red when the metadata min/max aggregate refuses timestamptz. - native_fetch_coalesce: "the wide fetch returns the projected values". Red when the coalesced index fetch reads each column's values from the start of the span instead of the column's own offset. - native_delete_visibility_paths (pytest twin only): "the rolled-back delete left the row in place". Red when the delete-vector read sees aborted catalog rows. - projection_update: "planner uses the covering projection". Red when the planner never offers a covering projection scan. - projection_update: "projection matches the heap before any update". Red when projection rows store the first projected column's value in every projected column. The ledger seeds native_agg and projection_update from five-major runs (35/35 and 9/9 on each of PG 15-19), dates the renamed checks and the arms the same mutations reddened, and drops the old premise row for the wide fetch. Ledger: 2460 -> 2504 rows, never 1893 -> 1926, dated 567 -> 578; suites_not_covered 244 -> 242. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019VvWuX1zUwk6Y513waRd4N --- test/check_ledger.tsv | 44 +++++++++++++++++++ test/check_ledger_budget.txt | 29 +++++++++++- test/projection_update.sh | 4 +- .../test_native_delete_visibility_paths.py | 2 +- test/pytest/test_projection_update.py | 4 +- 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/test/check_ledger.tsv b/test/check_ledger.tsv index 54cb46a65..5d39a2ec8 100644 --- a/test/check_ledger.tsv +++ b/test/check_ledger.tsv @@ -1920,6 +1920,41 @@ latest_reading latest_reading the GROUP BY form returns what DISTINCT ON returns latest_reading latest_reading the LATERAL form returns what DISTINCT ON returns 15;16;17;18;19 2026-10-12 the document's LATERAL recipe orders by ts ascending, so it returns each device's FIRST reading latest_reading latest_reading with the btree the LATERAL form reads under a tenth of the table 15;16;17;18;19 never - latest_reading latest_reading without the btree the LATERAL form reads the table once per device 15;16;17;18;19 never - +native_agg native_agg an aggregate that needs zone maps reads them 15;16;17;18;19 never - +native_agg native_agg avg(int4,nulls) 15;16;17;18;19 never - +native_agg native_agg control: decoding ts reads the table's blocks 15;16;17;18;19 never - +native_agg native_agg count(*) 15;16;17;18;19 never - +native_agg native_agg count(*) beats a parallel plan 15;16;17;18;19 never - +native_agg native_agg count(*) plan has no Gather 15;16;17;18;19 never - +native_agg native_agg count(*) reads no zone maps 15;16;17;18;19 never - +native_agg native_agg count(*) uses the metadata agg node 15;16;17;18;19 never - +native_agg native_agg count(col,nulls) 15;16;17;18;19 never - +native_agg native_agg empty count(*) 15;16;17;18;19 never - +native_agg native_agg empty min NULL 15;16;17;18;19 never - +native_agg native_agg empty sum NULL 15;16;17;18;19 never - +native_agg native_agg filtered aggregate not metadata node 15;16;17;18;19 never - +native_agg native_agg filtered aggregate parity 15;16;17;18;19 never - +native_agg native_agg max(int4) 15;16;17;18;19 never - +native_agg native_agg max(text) 15;16;17;18;19 never - +native_agg native_agg max(timestamptz) parity 15;16;17;18;19 never - +native_agg native_agg max(timestamptz) parity after deleting the newest rows 15;16;17;18;19 never - +native_agg native_agg max(ts) over timestamptz plans the metadata agg node 15;16;17;18;19 2026-10-14 the metadata min/max aggregate refusing timestamptz, so max(ts) and min(ts) fall back to decoding the column +native_agg native_agg max(ts) reads under a tenth of the blocks a decode of ts reads 15;16;17;18;19 2026-10-14 the metadata min/max aggregate refusing timestamptz, so max(ts) and min(ts) fall back to decoding the column +native_agg native_agg min(int4) 15;16;17;18;19 never - +native_agg native_agg min(int4,nulls) 15;16;17;18;19 never - +native_agg native_agg min(text) 15;16;17;18;19 never - +native_agg native_agg min(timestamptz) parity 15;16;17;18;19 never - +native_agg native_agg min(timestamptz) parity after deleting the oldest rows 15;16;17;18;19 never - +native_agg native_agg min(ts) reads under a tenth of the blocks a decode of ts reads 15;16;17;18;19 2026-10-14 the metadata min/max aggregate refusing timestamptz, so max(ts) and min(ts) fall back to decoding the column +native_agg native_agg multi-agg 15;16;17;18;19 never - +native_agg native_agg multi-agg beats a parallel plan 15;16;17;18;19 never - +native_agg native_agg multi-agg plan has no Gather 15;16;17;18;19 never - +native_agg native_agg premise: the deletes removed rows at both ends, the same rows from each 15;16;17;18;19 never - +native_agg native_agg premise: the timestamptz table holds every row inserted 15;16;17;18;19 never - +native_agg native_agg sum(bigint) fallback parity 15;16;17;18;19 never - +native_agg native_agg sum(int4) 15;16;17;18;19 never - +native_agg native_agg sum(int4,nulls) 15;16;17;18;19 never - +native_agg native_agg sum/min/max uses the metadata agg node 15;16;17;18;19 never - native_chunk_length_bound native_chunk_length_bound a sequential scan of the same poisoned chunk is refused (XX001) 15;16;17;18;19 never - native_chunk_length_bound native_chunk_length_bound an index fetch of a chunk whose page_length is 2^32 too large is refused (XX001) 15;16;17;18;19 never - native_chunk_length_bound native_chunk_length_bound backend survived the sequential refusal 15;16;17;18;19 never - @@ -2213,6 +2248,15 @@ projection_scan_io projection_scan_io premise: the empty projection is found and projection_scan_io projection_scan_io premise: the plan uses the covering projection 15;16;17;18;19 never - projection_scan_io projection_scan_io premise: the projection row still exists after its storage id is cleared 15;16;17;18;19 never - projection_scan_io projection_scan_io premise: the table holds every inserted row 15;16;17;18;19 never - +projection_update projection_update covering projection scan matches heap after updating a non-projected column 15;16;17;18;19 2026-10-14 projection rows storing the first projected column's value in every projected column +projection_update projection_update covering projection scan matches heap after updating a projected column 15;16;17;18;19 2026-10-14 projection rows storing the first projected column's value in every projected column +projection_update projection_update every column matches heap after updating a non-projected column 15;16;17;18;19 never - +projection_update projection_update full-table projection scan still matches heap 15;16;17;18;19 never - +projection_update projection_update planner uses the covering projection 15;16;17;18;19 2026-10-14 the planner never offering a covering projection scan +projection_update projection_update projection matches the heap before any update 15;16;17;18;19 2026-10-14 projection rows storing the first projected column's value in every projected column +projection_update projection_update read_projection matches the live base after that update 15;16;17;18;19 2026-10-14 projection rows storing the first projected column's value in every projected column +projection_update projection_update read_projection still matches the live base 15;16;17;18;19 2026-10-14 projection rows storing the first projected column's value in every projected column +projection_update projection_update reconstruct via the projection still rebuilds every live row 15;16;17;18;19 2026-10-14 projection rows storing the first projected column's value in every projected column range_pruning range_pruning a clustered overlap near the end skips the four vectors only their upper bounds rule out 15;16;17;18;19 2026-10-13 native_range_excludes never using max_upper (haveUpper forced false) range_pruning range_pruning a clustered overlap skips vectors instead of decoding them 15;16;17;18;19 never - range_pruning range_pruning a scattered column skips nothing, which is what the documentation says 15;16;17;18;19 never - diff --git a/test/check_ledger_budget.txt b/test/check_ledger_budget.txt index 0e9094fe5..c130dd4e3 100644 --- a/test/check_ledger_budget.txt +++ b/test/check_ledger_budget.txt @@ -15,7 +15,7 @@ # # Adding a check to a suite that is already covered does not move it, which is # what makes it safe to bound. -suites_not_covered 240 +suites_not_covered 238 # # checks_never_observed_red -- A CENSUS. NOT a ceiling, and it must not become # one. @@ -2089,4 +2089,29 @@ suites_not_covered 240 # never 1988 - 2 = 1986 # dated 596 + 2 = 598 # 1986 + 598 == 2584 -checks_never_observed_red 1986 +# +# #1339 audit, five premises a product change reddens (jdatcmd): 1986 -> 2020, and +# suites_not_covered 240 -> 238. Five checks named `premise:` test product code and +# lose the prefix in both twins (#1236); #1356 already renamed two of them, the max(ts) +# and wide-fetch checks. native_agg and projection_update had no rows; +# they enter with all their checks from five-major runs (35/35 and 9/9 on each of +# 15-19), because a renamed check in an unseeded suite has no row to date. Dated here: +# - "max(ts) over timestamptz plans the metadata agg node", with the two block-count +# arms beside it, by the metadata min/max aggregate refusing timestamptz; +# - "the wide fetch returns the projected values" was already renamed and dated by +# #1356, with the same mutation, so this PR leaves its row as main has it; +# - "planner uses the covering projection", by the planner never offering a +# covering projection scan; +# - "projection matches the heap before any update", with the five projection arms +# after it, by projection rows storing the first projected column's value in +# every projected column. +# The fifth, "the rolled-back delete left the row in place", exists only in +# native_delete_visibility_paths' pytest twin, which the ledger does not record; its +# red is the delete-vector read seeing aborted catalog rows. The other 34 seeded rows +# arrive never: seeding a suite moves the census up by its undated rows. +# +# ledger rows 2584 + 35 + 9 = 2628 +# never 1986 + 35 + 9 - 10 = 2020 +# dated 598 + 10 = 608 +# 2020 + 608 == 2628 +checks_never_observed_red 2020 diff --git a/test/projection_update.sh b/test/projection_update.sh index e497c8977..a2f4230d6 100755 --- a/test/projection_update.sh +++ b/test/projection_update.sh @@ -24,9 +24,9 @@ psql_run "ANALYZE pu;" psql_run "CREATE TABLE pu_h (a int, b text, c int) USING heap;" psql_run "INSERT INTO pu_h SELECT g, 'r'||g, (g*7)%1000 FROM generate_series(1,20000) g;" -check "premise: planner uses the covering projection" \ +check "planner uses the covering projection" \ "$(q "EXPLAIN (COSTS OFF) SELECT a, c FROM pu WHERE c BETWEEN 100 AND 200;" | grep -c 'Columnar Projection: pc')" "1" -check "premise: projection matches the heap before any update" \ +check "projection matches the heap before any update" \ "$(pgc_set_hash "SELECT a, c FROM pu WHERE c BETWEEN 100 AND 200")" \ "$(pgc_set_hash "SELECT a, c FROM pu_h WHERE c BETWEEN 100 AND 200")" diff --git a/test/pytest/test_native_delete_visibility_paths.py b/test/pytest/test_native_delete_visibility_paths.py index b01072285..28d39f414 100644 --- a/test/pytest/test_native_delete_visibility_paths.py +++ b/test/pytest/test_native_delete_visibility_paths.py @@ -155,7 +155,7 @@ def test_native_delete_visibility_paths(pgc_conn, expect): with pgc_conn.cursor() as cur: cur.execute("SELECT count(*) FROM t WHERE id = 8") expect.num(cur.fetchone()[0], 1, - "premise: the rolled-back delete left the row in place") + "the rolled-back delete left the row in place") def test_a_delete_whose_qual_deletes_another_row_matches_heap(pgc_conn, expect): diff --git a/test/pytest/test_projection_update.py b/test/pytest/test_projection_update.py index a84ae78fb..2425f7a75 100644 --- a/test/pytest/test_projection_update.py +++ b/test/pytest/test_projection_update.py @@ -68,12 +68,12 @@ def test_update_fans_the_new_row_number_out_to_projections(pgc_conn, expect): cur.execute("EXPLAIN (COSTS OFF) SELECT a, c FROM pu WHERE c BETWEEN 100 AND 200") plan = "\n".join(r[0] for r in cur.fetchall()) expect.num(plan.count("Columnar Projection: pc"), 1, - "premise: planner uses the covering projection") + "planner uses the covering projection") q_c = "SELECT a, c FROM pu WHERE c BETWEEN 100 AND 200" q_h = "SELECT a, c FROM pu_h WHERE c BETWEEN 100 AND 200" expect.rows(_set(cur, q_c), _set(cur, q_h), - "premise: projection matches the heap before any update") + "projection matches the heap before any update") # --- updating a PROJECTED column ------------------------------------ cur.execute("UPDATE pu SET a = a + 1 WHERE a % 10 = 0") From 73551f51022a962dbef167261f13150fc27e02d7 Mon Sep 17 00:00:00 2001 From: "Joshua D. Drake" Date: Wed, 14 Oct 2026 20:37:16 +0000 Subject: [PATCH 2/2] test: native_agg's seeded ledger row carries #1356's new name (#1389) The seed was taken from logs made before #1356 renamed "premise: the deletes removed rows at both ends, the same rows from each", so the ledger named a check that no longer exists, and the suites job refused it as an orphan. The row has no history; renamed and re-sorted. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_019VvWuX1zUwk6Y513waRd4N --- test/check_ledger.tsv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/check_ledger.tsv b/test/check_ledger.tsv index 5d39a2ec8..8dfd9fe22 100644 --- a/test/check_ledger.tsv +++ b/test/check_ledger.tsv @@ -1949,12 +1949,12 @@ native_agg native_agg min(ts) reads under a tenth of the blocks a decode of ts r native_agg native_agg multi-agg 15;16;17;18;19 never - native_agg native_agg multi-agg beats a parallel plan 15;16;17;18;19 never - native_agg native_agg multi-agg plan has no Gather 15;16;17;18;19 never - -native_agg native_agg premise: the deletes removed rows at both ends, the same rows from each 15;16;17;18;19 never - native_agg native_agg premise: the timestamptz table holds every row inserted 15;16;17;18;19 never - native_agg native_agg sum(bigint) fallback parity 15;16;17;18;19 never - native_agg native_agg sum(int4) 15;16;17;18;19 never - native_agg native_agg sum(int4,nulls) 15;16;17;18;19 never - native_agg native_agg sum/min/max uses the metadata agg node 15;16;17;18;19 never - +native_agg native_agg the deletes removed rows at both ends, the same rows from each 15;16;17;18;19 never - native_chunk_length_bound native_chunk_length_bound a sequential scan of the same poisoned chunk is refused (XX001) 15;16;17;18;19 never - native_chunk_length_bound native_chunk_length_bound an index fetch of a chunk whose page_length is 2^32 too large is refused (XX001) 15;16;17;18;19 never - native_chunk_length_bound native_chunk_length_bound backend survived the sequential refusal 15;16;17;18;19 never -