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
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1932,6 +1932,52 @@ true until the next version shipped.
covers, so its check names have no rows. That is also why the twenty-four collisions
matter for #432 rather than for the census today -- twenty-one of them are in suites
that become covered only when the 240 are seeded.
- The last five suites' continuation checks name the case they continue, closing the
rename half of #982 (ten records, five files).

Ten checks across five suites shared five ledger keys with another check. Measured by
running every one of the five on clean `main` and on this branch, on the same box:

suite control (clean main) this branch
sorted_pathkeys 113 records 110 keys 3 lost 113 113 0
vector_agg_tlist_shape 68 records 65 keys 3 lost 68 68 0
alter_am_cleanup 45 records 43 keys 2 lost 45 45 0
eager_ordering_record 31 records 30 keys 1 lost 31 31 0
objstore_userinfo 7 records 6 keys 1 lost 7 7 0

Every record count is unchanged, so this renames and nothing else. All five suites:
`rc=0`, `FAIL=0`, on both trees.

**This is not a new convention. It is each file's own convention, applied where it
lapsed.** Every one of the five already names the case at a neighbouring site --
`and DESC still answers correctly`, `and NULLS FIRST still answers correctly`,
`and FILTER still answers correctly`, `and DISTINCT still answers correctly` -- and then
falls back to a bare `and it still answers correctly` for the next four. The fix is to
finish the pattern the author started:

REFUSE: a non-prefix of the key is not an order the rows are in
and it still answers correctly -> and a non-prefix still answers correctly
REFUSE: a column that is not in the key at all
and it still answers correctly -> and a non-key column still answers correctly
REFUSE: FILTER inside an expression over aggregates
and it still answers correctly -> and FILTER inside an expression still answers correctly

Two sites took the discriminator from the value expression instead, because their
headline names no table: `control: and it moved the layout` becomes
`... moved the tailgate layout` and `... moved the lexgate layout`, matching the
`layout tailgate` and `layout lexgate` the checks actually read.

No ledger change: none of the five is one of the two suites `test/check_ledger.tsv`
covers, and both ledger files are byte-identical to `main`.

One coupling, found by review rather than by either PR's own checks: #998 added a skip
loop to `sorted_pathkeys.sh` that lists its arms by name, and one of those names is the
arm this change renames. The two merge cleanly, so nothing would have presented a
conflict -- #998's own guard would simply have gone red in `main`. The loop is updated
here, and its guard reports no mismatch. Counting the old name is how you MISS this: an
unanchored `grep -F` finds 3 occurrences because both renames EXTEND the name rather
than replace it, so each renamed line still matches its own old form. Anchoring on the
closing quote gives 1, which is the one that matters.

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

Expand Down
Binary file added b983.bundle
Binary file not shown.
Binary file added b983r.bundle
Binary file not shown.
Binary file added b990.bundle
Binary file not shown.
Binary file added b991.bundle
Binary file not shown.
Binary file added b993r2.bundle
Binary file not shown.
Binary file added b995.bundle
Binary file not shown.
Binary file added b997r.bundle
Binary file not shown.
Binary file added b998.bundle
Binary file not shown.
Binary file added b998b.bundle
Binary file not shown.
8 changes: 4 additions & 4 deletions test/alter_am_cleanup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ check "premise: and installed in this suite's own database" \

check "a plain table is created in a database without the extension" \
"$(aac_dbrun aac_nocx 'CREATE TABLE nx (i int primary key, t text);')" "rc=0"
check "and dropped there" \
check "and dropped there, without the extension" \
"$(aac_dbrun aac_nocx 'DROP TABLE nx;')" "rc=0"
check "an explicit DROP of a temp table succeeds there" \
"$(aac_dbrun aac_nocx 'CREATE TEMP TABLE nxt (i int); DROP TABLE nxt;')" "rc=0"
Expand All @@ -136,7 +136,7 @@ check "ALTER COLUMN TYPE succeeds without the extension" \
"$(aac_dbrun aac_nocx 'ALTER TABLE rw ALTER COLUMN t TYPE varchar(64);')" "rc=0"
check "CREATE MATERIALIZED VIEW succeeds without the extension" \
"$(aac_dbrun aac_nocx 'CREATE MATERIALIZED VIEW rwm AS SELECT * FROM rw;')" "rc=0"
check "and REFRESH MATERIALIZED VIEW does too" \
check "and REFRESH MATERIALIZED VIEW does too, without the extension" \
"$(aac_dbrun aac_nocx 'REFRESH MATERIALIZED VIEW rwm;')" "rc=0"
check "TRUNCATE succeeds without the extension" \
"$(aac_dbrun aac_nocx 'TRUNCATE rw;')" "rc=0"
Expand Down Expand Up @@ -232,7 +232,7 @@ check "premise: and took pgcolumnar.options with it" \

check "a plain table is created after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'CREATE TABLE dxh (i int primary key, t text);')" "rc=0"
check "and dropped there" \
check "and dropped there, after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'DROP TABLE dxh;')" "rc=0"
check "an explicit DROP of a temp table succeeds after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'CREATE TEMP TABLE dxt (i int); DROP TABLE dxt;')" "rc=0"
Expand All @@ -248,7 +248,7 @@ check "ALTER COLUMN TYPE succeeds after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'ALTER TABLE dxr ALTER COLUMN t TYPE varchar(64);')" "rc=0"
check "CREATE MATERIALIZED VIEW succeeds after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'CREATE MATERIALIZED VIEW dxm AS SELECT * FROM dxr;')" "rc=0"
check "and REFRESH MATERIALIZED VIEW does too" \
check "and REFRESH MATERIALIZED VIEW does too, after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'REFRESH MATERIALIZED VIEW dxm;')" "rc=0"
check "TRUNCATE succeeds after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'TRUNCATE dxr;')" "rc=0"
Expand Down
4 changes: 2 additions & 2 deletions test/eager_ordering_record.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ check "premise: the insert appended past the recorded run" \
"$([ "$(q "SELECT appended_groups FROM pgcolumnar.sort_status('tailgate');")" -gt 0 ] && echo yes || echo no)" "yes"
check "control: recluster with an appended tail does not skip" \
"$([ "$(q "SELECT pgcolumnar.recluster('tailgate', 'k', 'j');")" -gt 0 ] && echo yes || echo no)" "yes"
check "control: and it moved the layout" \
check "control: and it moved the tailgate layout" \
"$([ "$(layout tailgate)" != "$TAIL_BEFORE" ] && echo moved || echo unchanged)" "moved"

# And the mirror: a lexicographic run is not a Z-order run, so recluster must
Expand All @@ -152,7 +152,7 @@ psql_run "SELECT pgcolumnar.vacuum_sorted('lexgate', 'k');"
LEXGATE_BEFORE="$(layout lexgate)"
check "control: recluster does not skip a LEXICOGRAPHIC run of the same lead column" \
"$(q "SELECT pgcolumnar.recluster('lexgate', 'k');")" "5"
check "control: and it moved the layout" \
check "control: and it moved the lexgate layout" \
"$([ "$(layout lexgate)" != "$LEXGATE_BEFORE" ] && echo moved || echo unchanged)" "moved"

# ------------------------------------------------- an unsorted rewrite records nothing
Expand Down
4 changes: 2 additions & 2 deletions test/objstore_userinfo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ URL="http://u:p@127.0.0.1:1/x.parquet"
# --- premise: the read path refuses userinfo with the parse guard ------------
check "read_parquet refuses userinfo (22023, the parse guard)" \
"$(sqlstate_of "SELECT * FROM pgcolumnar.read_parquet('$URL') AS t(v int)")" "22023"
check "and its message names userinfo" \
check "and the read_parquet message names userinfo" \
"$(msg_of "SELECT * FROM pgcolumnar.read_parquet('$URL') AS t(v int)")" "1"

# --- the gap: the write path must refuse with the SAME guard -----------------
# Pre-fix these read 42501: the parse admits the URL and the '@'-carrying host
# then fails the allow-list at connect -- fail closed, wrong reason.
check "export_parquet refuses userinfo (22023, not an allow-list 42501)" \
"$(sqlstate_of "SELECT pgcolumnar.export_parquet('ex', '$URL')")" "22023"
check "and its message names userinfo" \
check "and the export_parquet message names userinfo" \
"$(msg_of "SELECT pgcolumnar.export_parquet('ex', '$URL')")" "1"
check "export_arrow refuses userinfo through the same handle (22023)" \
"$(sqlstate_of "SELECT pgcolumnar.export_arrow('ex', 'http://u@127.0.0.1:1/x.arrow')")" "22023"
Expand Down
12 changes: 6 additions & 6 deletions test/sorted_pathkeys.sh
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ ans "and NULLS FIRST still answers correctly" 'SELECT k, id FROM %T ORDER BY k

check "REFUSE: a non-prefix of the key is not an order the rows are in" \
"$(sorts 'SELECT j FROM c ORDER BY j')" "yes"
ans "and it still answers correctly" 'SELECT j, id FROM %T ORDER BY j, id LIMIT 300'
ans "and a non-prefix still answers correctly" 'SELECT j, id FROM %T ORDER BY j, id LIMIT 300'

check "REFUSE: a column that is not in the key at all" \
"$(sorts 'SELECT id FROM c ORDER BY id')" "yes"
ans "and it still answers correctly" 'SELECT id FROM %T ORDER BY id LIMIT 300'
ans "and a non-key column still answers correctly" 'SELECT id FROM %T ORDER BY id LIMIT 300'

check "REFUSE: the key columns in the wrong order" \
"$(sorts 'SELECT k, j FROM c ORDER BY j, k')" "yes"
Expand Down Expand Up @@ -189,7 +189,7 @@ check "REFUSE: a run with an appended tail is not an ordered relation" \
# not the first ten rows.
ansp "and ORDER BY k LIMIT still returns the true first rows" tailh tailc \
'SELECT k, id FROM %T ORDER BY k NULLS LAST, id LIMIT 10'
ansp "and the whole ordered result matches heap" tailh tailc \
ansp "and the whole ordered result matches heap with the tail appended" tailh tailc \
'SELECT k, j, id FROM %T ORDER BY k NULLS LAST, j, id'

# --- a Z-order run: an order, but not a sort on any one column --------------
Expand All @@ -211,7 +211,7 @@ check "premise: and it is NOT in k order" \
"$([ "$(inv zc k)" -gt 0 ] && echo yes || echo no)" "yes"
check "REFUSE: a Z-order run is not a sort on its lead column" \
"$(sorts 'SELECT k FROM zc ORDER BY k')" "yes"
ansp "and it still answers correctly" zh zc \
ansp "and the Z-order run still answers correctly" zh zc \
'SELECT k, j, id FROM %T ORDER BY k, j, id LIMIT 300'

# --- an unsorted relation ---------------------------------------------------
Expand Down Expand Up @@ -286,7 +286,7 @@ if [ -z "$ALTCOLL" ] || \
"premise: and the column's collation really did change" \
"REFUSE: the order the rows are in is no longer the order the column asks for" \
"and ORDER BY k LIMIT returns the new collation's first rows, matching heap" \
"and the whole ordered result matches heap"; do
"and the whole ordered result matches heap under the new collation"; do
check_skip "$_sp_n" \
"SKIP $_sp_n (this server has no collation that disagrees with C on ASCII)" \
"this server has no suitable collation"
Expand Down Expand Up @@ -315,7 +315,7 @@ else
# the answer is aa10|aa1002|AA1003. A wrong answer from a plan with no Sort.
ansp "and ORDER BY k LIMIT returns the new collation's first rows, matching heap" colh colc \
'SELECT k, id FROM %T ORDER BY k, id LIMIT 3'
ansp "and the whole ordered result matches heap" colh colc \
ansp "and the whole ordered result matches heap under the new collation" colh colc \
'SELECT k, id FROM %T ORDER BY k, id'
fi

Expand Down
8 changes: 4 additions & 4 deletions test/vector_agg_tlist_shape.sh
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ ansq "and GROUP BY still answers correctly" \

check "REFUSE: an unsupported aggregate declines the whole target list" \
"$([ "$(vec "SELECT count(*)::text, string_agg(t, ',') FROM c")" -gt 0 ] && echo yes || echo no)" "no"
ansq "and it still answers correctly" \
ansq "and the unsupported aggregate still answers correctly" \
"SELECT count(*)::text, length(string_agg(t, ',')) FROM %T"

# --- the surface this change OPENS ------------------------------------------
Expand Down Expand Up @@ -168,11 +168,11 @@ ansq "and DISTINCT still answers correctly" 'SELECT count(DISTINCT b)::text FROM

check "REFUSE: FILTER inside an expression over aggregates" \
"$([ "$(vec 'SELECT avg(a) FILTER (WHERE b < 50) + 1 FROM c')" -gt 0 ] && echo yes || echo no)" "no"
ansq "and it still answers correctly" 'SELECT avg(a) FILTER (WHERE b < 50) + 1 FROM %T'
ansq "and FILTER inside an expression still answers correctly" 'SELECT avg(a) FILTER (WHERE b < 50) + 1 FROM %T'

check "REFUSE: ORDER BY inside an aggregate, wrapped" \
"$([ "$(vec "SELECT length(string_agg(t, ',' ORDER BY a)) FROM c")" -gt 0 ] && echo yes || echo no)" "no"
ansq "and it still answers correctly" \
ansq "and a wrapped ORDER BY still answers correctly" \
"SELECT length(string_agg(t, ',' ORDER BY a NULLS LAST, id)) FROM %T"

# --- empty and all-NULL, which a projection can get wrong quietly -----------
Expand All @@ -194,7 +194,7 @@ check_text "an all-NULL relation answers the wrapped shape as heap does" \

check "REFUSE: an aggregate over an expression of two columns" \
"$([ "$(vec 'SELECT sum(a + b) FROM c')" -gt 0 ] && echo yes || echo no)" "no"
ansq "and it still answers correctly" 'SELECT sum(a + b) FROM %T'
ansq "and an aggregate over an expression still answers correctly" 'SELECT sum(a + b) FROM %T'

# --- the parallel arm, which this change also unblocked ---------------------
#
Expand Down
Loading