Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,81 @@ true until the next version shipped.

### Added

- `test/pytest/test_projections.py`: the multiple-projections DDL, catalog and read
path, ported from `test/projections.sh` (#432). All 75 of its check names, one for
one.

A projection is a second copy of some columns, and every property is about the copy
staying honest: it holds the rows the base holds, it loses the rows the base loses, it
survives a vacuum that renumbers every row underneath it, and the planner reads it only
when it can answer the whole query from it. A wrong projection is a WRONG ANSWER rather
than a slow one, because nothing downstream re-checks.

THE PORT IS STRICTLY STRONGER IN ONE PLACE, and it is worth saying which way. The
original's `expect_fail` helper runs the statement and passes when it errors AT ALL, so
a misspelt table name satisfies every one of its eight refusal arms. The port asserts
the SQLSTATE, and every code was measured against this build rather than guessed --
42710, 42703, 22023, 42701, 22023, 42809, 22023, 42704, 42704. The names are the bash
suite's; the assertions are not.

Three other mechanism changes assert the same property by a stronger means: the
`EXPLAIN` grep becomes a typed JSON field and reads the projection NAME rather than its
presence; `pgc_set_hash` becomes `expect.row_set`, order-blind by declaration rather
than by construction; and the second MVCC session becomes a second connection rather
than a background `psql` on a fifo polled for a token, which removes the wait rather
than shortening it.

Mutation proof, each asserting it applied before its result was believed: removing the
#875 projection-writer reset reddens both directions of the latch (`got 105 want 116`
on the mid-transaction add, and the orphan storage the mid-transaction drop leaves);
forcing the planner to refuse every projection reddens the covering query and the
post-vacuum planner arm with `got None want 'pc'`, which is what proves the port reads
the name rather than the presence. Restored, byte-identical: 75 checks, 0 fail.

- `test/pytest/test_sorted_pathkeys.py`: the ordered-scan surface, ported from
`test/sorted_pathkeys.sh` (#432). All 110 of its check names, one for one.

The bash suite pins one decision: when a columnar scan may hand the planner
PATHKEYS, the promise that its rows already arrive in a stated order. The planner
then drops the Sort above the scan, and nothing downstream re-checks. So a wrong
promise is not a slow plan, it is WRONG ROWS.

The port keeps the original's three shapes rather than reorganising by feature: a
CLAIM arm (the Sort goes), a REFUSAL arm (something made the claim untrue and the
Sort comes back), and an ANSWER arm (the rows themselves, against a heap table
built from the same data). The ANSWER arm is not a duplicate of the CLAIM arm --
dropping the Sort is only correct if the rows arrive sorted anyway, and a plan
check alone cannot say whether they did.

THE ONE ARM THAT NEEDED MORE THAN A PORT is `pgcolumnar.parallel_copy`, which
prepares one transaction per worker. `max_prepared_transactions` cannot be raised
without restarting the postmaster, and the default is 0, so asking for fewer
workers does not help. `pgc_cluster` now sets it where it writes
`postgresql.conf`, at the value `lib.sh` gives this suite through
`PGC_EXTRA_CONF`. Refusing the arm instead was measured and rejected: it loses
three names outright (`cannot_run` records under the REASON CODE, #1040 phase 0b)
AND turns the `pytest (cluster tests)` job red, because an unrunnable check exits
67 and the job runs pytest under `set -euo pipefail`. That half exits 0 today with
zero unrun, so this file would have been the first to break it.

- `test_docs_cover_the_corpus.py` now refuses a NUMBERED SECTION WITH NO BODY.

The arm above it asks whether each test file is NAMED by a numbered heading. A
heading with no body is still a heading, so a section inserted into the gap between
another heading and its body leaves both files named and one of them documented
under the wrong title -- every existing arm green. `## 37. test_iceberg_fdw.py`
reached `main` sitting directly above `## 38.`, with the Iceberg body attached to
the userinfo heading. Fixed here, and the section order now matches the bodies.

### Fixed

- `compare_to_bash.py`'s corpus arm called a WRAPPED name fabricated. A name too long
for one line is written as adjacent literals, and Python joins them at parse time,
so the joined name is text the file contains but not text `in src` can find. The
arm exists to catch a reader that CONSTRUCTS a name, so it now collapses the file's
own concatenation and keeps exactly that guarantee: an f-string name still yields a
`{}` template, which the collapse does not rescue. Both directions are asserted.

- `orphan-scan` is armed in the matrix runner, so a ledger row naming a deleted
check is refused rather than reported (#983, #1015).

Expand Down
Loading
Loading