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
53 changes: 53 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,59 @@ true until the next version shipped.
differ between majors in at least one suite, the ledger has no major dimension, and
a gate seeded from one major would refuse runs on another.

- The last fifty-eight checks in those ten suites record too, so all ten are now
complete (#965).

The previous change converted each suite's own `check` helper and recorded 236 of
the 293. The rest went through four further helpers with four different displays,
which is why they needed a second pass rather than the same substitution:

| suite | helper | checks |
| --- | --- | --- |
| `phase6` | `eq_on_off` | 39 |
| `phase4` | `expect_fail` 5, `assert_plan` 2, `assert_plan_seq` 1, one written inline | 9 |
| `audit` | `expect_error` | 5 |
| `phase5` | `assert_plan` | 5 |

Measured on PG18, each suite's records now equal both its own human check lines and
its `checks run:` total, and every human line is byte-for-byte what it was:

suite records before -> after checks run: human lines
audit 26 -> 31 31 31
phase4 29 -> 38 38 38
phase5 31 -> 36 36 36
phase6 4 -> 43 43 43

`phase6`'s `eq_on_off` has three outcomes and two of them `return` early. Each one
records, because a `return` that skips the record leaves the check counted nowhere,
which is the state this conversion exists to end.

Two displays span more than one line -- `assert_plan` in both `phase4` and `phase5`
prints the whole plan under a header when it fails. The dump is passed as part of
the display rather than echoed after the record, so a failing run's output is also
byte-identical instead of having a record line wedged between the header and the
plan.

It also makes a version-gated arm visible to the ledger. `audit.sh` gates its
partitioned-parent arm on `server_version_num >= 170000`, because PG16 and earlier
refuse `PARTITION BY ... USING pgcolumnar`, and the gated branch printed a bare
note and recorded nothing. So on PG16 the ledger received three fewer rows for
`audit` with nothing saying why. It now records a SKIP with its reason, the way
`unique_conc.sh` already does for its own version gate, and PG16's human output
gains that SKIP line in place of the note.

One SKIP for the block, not one per gated check. Naming each of the four checks in
a branch that never runs them would make the count the same on every major, and
would also put four check names somewhere nothing exercises them, where they would
drift. Comparing counts across majors needs a major dimension in the ledger, which
belongs to #432.

Every count here is a PG18 number. On PG16 the same suites give 28 records for
`audit` rather than 31, because that gated arm holds three `check` calls and the
`expect_error` above, and one of those records is now the SKIP standing in for all
four. The per-major table is in #965, which is where the remainder should be read
from rather than from either run alone.

## [1.0-alpha3] - 2026-09-02

### Added
Expand Down
14 changes: 11 additions & 3 deletions test/audit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ check() {
expect_error() {
local name="$1" sql="$2"
if run_pg "$PSQL -c \"$sql\"" >/dev/null 2>&1; then
echo "FAIL $name: statement unexpectedly succeeded"
pgc_record FAIL "$name" "FAIL $name: statement unexpectedly succeeded"
fail=1
else
echo "PASS $name (rejected)"
pgc_record PASS "$name" "PASS $name (rejected)"
fi
}

Expand Down Expand Up @@ -310,7 +310,15 @@ if [ "$audit_srv" -ge 170000 ]; then
"$(q "SELECT count(*) FROM pgcolumnar.options WHERE regclass = 'opt_part_1'::regclass;")" "1"
q "DROP TABLE opt_part;" >/dev/null
else
echo "-- PG$((audit_srv / 10000)) refuses PARTITION BY ... USING pgcolumnar; parent arm not applicable"
# ONE SKIP FOR THE BLOCK, not one per gated check, which is the shape
# unique_conc.sh:546 already uses for its own version gate. Naming each of the
# four checks here would make the count major-invariant and would also duplicate
# four check names in a branch that never runs them, so they would drift. The
# real fix for comparing counts across majors is a major dimension in the
# ledger, which is #432's problem and not this file's.
check_skip "the partitioned-parent arm" \
"SKIP the partitioned-parent arm (PG$((audit_srv / 10000)) refuses PARTITION BY ... USING pgcolumnar)" \
"PG$((audit_srv / 10000)) refuses PARTITION BY ... USING pgcolumnar"
fi

# valid values are accepted, and delete/update work (no divide-by-zero)
Expand Down
23 changes: 14 additions & 9 deletions test/phase4.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,14 @@ assert_plan() {
# index scan so the plan shape can be asserted.
plan="$(run_pg "$PSQL -c \"SET enable_seqscan=off; SET pgcolumnar.enable_custom_scan=off; EXPLAIN (COSTS OFF) $sql\"")"
if grep -q "$want" <<<"$plan" && ! grep -q "$notwant" <<<"$plan"; then
echo "PASS $name: $(echo "$plan" | grep -E 'Scan' | head -1 | sed 's/^ *//')"
pgc_record PASS "$name" "PASS $name: $(echo "$plan" | grep -E 'Scan' | head -1 | sed 's/^ *//')"
else
echo "FAIL $name: plan was:"
echo "$plan" | sed 's/^/ /'
# The plan dump is part of the display, so the record line lands after the
# whole thing rather than between the header and the dump. A red run's output
# stays byte-identical that way, which is the property the green runs already
# have.
pgc_record FAIL "$name" "FAIL $name: plan was:
$(echo "$plan" | sed 's/^/ /')"
fail=1
fi
}
Expand All @@ -130,10 +134,10 @@ assert_plan() {
expect_fail() {
local name="$1" sql="$2"
if run_pg "$PSQL -c \"$sql\"" >/dev/null 2>&1; then
echo "FAIL $name: expected error, got success"
pgc_record FAIL "$name" "FAIL $name: expected error, got success"
fail=1
else
echo "PASS $name: rejected"
pgc_record PASS "$name" "PASS $name: rejected"
fi
}

Expand Down Expand Up @@ -246,9 +250,10 @@ q "CREATE INDEX ios_a_idx ON ios (a);" >/dev/null
# The custom scan is turned off so the planner picks the index scan (see assert_plan).
iosoff_plan="$(run_pg "$PSQL -c \"SET pgcolumnar.enable_index_only_scan=off; SET enable_seqscan=off; SET pgcolumnar.enable_custom_scan=off; EXPLAIN (COSTS OFF) SELECT a FROM ios WHERE a = 100;\"")"
if grep -q "Index Scan" <<<"$iosoff_plan" && ! grep -q "Index Only Scan" <<<"$iosoff_plan"; then
echo "PASS IOS off: plain index scan"
pgc_record PASS "IOS off: plain index scan" "PASS IOS off: plain index scan"
else
echo "FAIL IOS off: plain index scan: plan was:"; echo "$iosoff_plan" | sed 's/^/ /'; fail=1
pgc_record FAIL "IOS off: plain index scan" "FAIL IOS off: plain index scan: plan was:
$(echo "$iosoff_plan" | sed 's/^/ /')"; fail=1
fi
check "covering value" "$(q 'SET enable_seqscan=off; SELECT a FROM ios WHERE a = 100;')" "100"
# a full-table scan is still available when index/bitmap scans are disabled.
Expand All @@ -258,9 +263,9 @@ assert_plan_seq() {
local plan
plan="$(run_pg "$PSQL -c \"SET enable_indexscan=off; SET enable_bitmapscan=off; EXPLAIN (COSTS OFF) SELECT * FROM ios WHERE a = 100;\"")"
if grep -qE "Seq Scan|Custom Scan \(PgColumnarScan\)" <<<"$plan"; then
echo "PASS full-table scan available"
pgc_record PASS "full-table scan available" "PASS full-table scan available"
else
echo "FAIL full-table scan available: $plan"; fail=1
pgc_record FAIL "full-table scan available" "FAIL full-table scan available: $plan"; fail=1
fi
}
assert_plan_seq
Expand Down
6 changes: 3 additions & 3 deletions test/phase5.sh
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,10 @@ assert_plan() {
local plan
plan="$(run_pg "$PSQL -c \"$sql\"")"
if grep -q "$want" <<<"$plan" && { [ -z "$notwant" ] || ! grep -q "$notwant" <<<"$plan"; }; then
echo "PASS $name"
pgc_record PASS "$name" "PASS $name"
else
echo "FAIL $name: plan was:"
echo "$plan" | sed 's/^/ /'
pgc_record FAIL "$name" "FAIL $name: plan was:
$(echo "$plan" | sed 's/^/ /')"
fail=1
fi
}
Expand Down
9 changes: 6 additions & 3 deletions test/phase6.sh
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,20 @@ eq_on_off() {
local on off
on="$(run_pg "$PSQL -c \"SET pgcolumnar.enable_vectorization=on; $query\"")"
off="$(run_pg "$PSQL -c \"SET pgcolumnar.enable_vectorization=off; $query\"")"
# THREE OUTCOMES, ONE RECORD EACH, including both early returns. A `return`
# that skips the record would leave the check counted nowhere, which is the
# state this whole conversion exists to end.
if [ -z "$on" ] || [ "$on" != "$off" ]; then
echo "FAIL $name: vectorized [$on] != scalar [$off]"
pgc_record FAIL "$name" "FAIL $name: vectorized [$on] != scalar [$off]"
fail=1
return
fi
if [ -n "$expect" ] && [ "$on" != "$expect" ]; then
echo "FAIL $name: got [$on] want [$expect]"
pgc_record FAIL "$name" "FAIL $name: got [$on] want [$expect]"
fail=1
return
fi
echo "PASS $name: $on"
pgc_record PASS "$name" "PASS $name: $on"
}

q "CREATE EXTENSION pgcolumnar;" >/dev/null
Expand Down
Loading