Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7ac79e5
fix: in the upgrade window, a refusal for a missing catalog table nam…
jdatcmd Oct 16, 2026
110aa0b
test: fk_referencing gets its pytest twin, and a referenced table may…
jdatcmd Oct 16, 2026
4ee6e1f
test: fk_referencing seeds the ledger, 17 of 28 arms dated by four mu…
jdatcmd Oct 16, 2026
110ccd4
test: truncate_cleanup gets its pytest twin (#1341)
jdatcmd Oct 16, 2026
50a8c31
test: truncate_cleanup seeds the ledger, 16 of 25 arms dated by four …
jdatcmd Oct 16, 2026
c0f4263
test: native_dml gets its pytest twin, and its min/max arm can see a …
jdatcmd Oct 16, 2026
091f982
test: native_dml seeds the ledger, 8 of 15 arms dated by three mutati…
jdatcmd Oct 16, 2026
25ce0ef
test: native_dict_underfill gets its pytest twin, and a crash can no …
jdatcmd Oct 16, 2026
2548d98
test: native_dict_underfill seeds the ledger, 2 of 4 arms dated (#1341)
jdatcmd Oct 16, 2026
e16ec69
test: native_decode_gating gets its pytest twin, and its filter count…
jdatcmd Oct 16, 2026
fb1f6e2
test: native_decode_gating seeds the ledger, 11 of 29 arms dated by f…
jdatcmd Oct 16, 2026
d095dc9
test: native_decode_gate_width gets its pytest twin, and the unshippe…
jdatcmd Oct 16, 2026
0cb4e37
test: native_decode_gate_width seeds the ledger, 3 of 35 arms dated b…
jdatcmd Oct 16, 2026
1d346de
test: pg_dump_roundtrip gets its pytest twin, and its index and sort_…
jdatcmd Oct 16, 2026
1da9bbf
test: pg_dump_roundtrip seeds the ledger, 16 of 40 arms dated by five…
jdatcmd Oct 16, 2026
58313d3
test: pg_upgrade gets its pytest twin, and its index arm takes the in…
jdatcmd Oct 16, 2026
d70e5d6
test: test_pg_upgrade runs its server tools as postgres under root, a…
jdatcmd Oct 16, 2026
a25fdff
test: replication gets its pytest twin, and its vacuum and compact ar…
jdatcmd Oct 16, 2026
3f27e47
test: replication seeds the ledger, 11 of 44 arms dated by four mutat…
jdatcmd Oct 16, 2026
8b0b582
test: native_recluster gets its pytest twin, and its index arm can se…
jdatcmd Oct 16, 2026
1ef6ec6
test: native_recluster seeds the ledger, 8 of 14 arms dated by five m…
jdatcmd Oct 16, 2026
ad2fd2a
test: alter_am_cleanup gets its pytest twin, and each arm reddens for…
jdatcmd Oct 16, 2026
62c80a4
test: alter_am_cleanup seeds the ledger, 21 of 47 arms dated by seven…
jdatcmd Oct 16, 2026
fd5c9cb
test: native_reclaim gets its pytest twin, and its reuse arms can see…
jdatcmd Oct 16, 2026
8c74c45
test: native_reclaim re-dates 17 arms by sixteen mutations of reuse a…
jdatcmd Oct 16, 2026
7e8d310
test: native_repack gets its pytest twin, and "the supported alternat…
jdatcmd Oct 16, 2026
0692d95
test: native_repack seeds the ledger, 11 of 22 rows dated by four mut…
jdatcmd Oct 16, 2026
abc7c8d
test: native_join_vector_agg gets its pytest twin (#1341)
jdatcmd Oct 16, 2026
a803ee6
test: native_writer gets its pytest twin (#1341)
jdatcmd Oct 16, 2026
79eb5cc
test: native_writer seeds the ledger, 7 of 10 arms dated by six mutat…
jdatcmd Oct 16, 2026
98837cb
test: native_batch_fold_projection gets its pytest twin, and its refe…
jdatcmd Oct 16, 2026
80af30a
test: native_batch_fold_projection seeds the ledger, 2 of 6 arms date…
jdatcmd Oct 16, 2026
4d88bb3
test: native_encdesc_golden gets its pytest twin, and a decoding read…
jdatcmd Oct 16, 2026
5b03158
test: native_encdesc_golden seeds the ledger, 9 of 17 arms dated by f…
jdatcmd Oct 16, 2026
75ac07e
test: native_parquet_schema gets its pytest twin, and bad magic must …
jdatcmd Oct 16, 2026
b20dbb2
test: native_parquet_schema seeds the ledger, 5 of 35 arms dated by f…
jdatcmd Oct 16, 2026
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
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,18 @@ true until the next version shipped.
Reported by @OffgridwithJD.

### Fixed
- **In the upgrade window, a refusal for a missing catalog table names `ALTER
EXTENSION UPDATE`.** After the new library is installed and the server restarted,
but before `ALTER EXTENSION pgcolumnar UPDATE`, `DROP TABLE`, `TRUNCATE` and
`pgcolumnar.vacuum()` on a columnar table fail, because the 1.0-alpha5 library
needs `pgcolumnar.retired_group` and a 1.0-alpha4 catalog lacks it. They change
nothing. The error used to name only the missing table, and it now carries a hint:
`The pgcolumnar catalog in this database may be older than the installed library.
Run ALTER EXTENSION pgcolumnar UPDATE in this database.` Reads and writes work
throughout, and after the update every one of these succeeds on the same rows
(#1341 item 66). `test/native_upgrade_converge.sh` and
`test_native_upgrade_converge.py`.


- **A join whose runtime-filter build is empty no longer reads the fact table.** When
a large dimension filtered to no row was joined to a columnar table, the hash join
Expand Down
12 changes: 12 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,18 @@ The fix is step 3. Run `ALTER EXTENSION pgcolumnar UPDATE;` in that database and
the error goes away. **Your data is not affected.** The tables are intact and no
conversion happens. Only the catalog entry is stale.

Between releases that add a catalog table, the new library can also need a table
the old catalog does not have. Upgrading from `1.0-alpha4` to `1.0-alpha5`,
`DROP TABLE`, `TRUNCATE` and `pgcolumnar.vacuum()` on a columnar table fail until
step 3, and change nothing; reads and writes keep working:

```
ERROR: columnar metadata table "pgcolumnar.retired_group" does not exist
HINT: The pgcolumnar catalog in this database may be older than the installed library. Run ALTER EXTENSION pgcolumnar UPDATE in this database.
```

The fix is the same: step 3.

Do not use `DROP EXTENSION` instead. A plain `DROP EXTENSION pgcolumnar` fails
while columnar tables exist, because they depend on the access method. The
form that succeeds is `DROP EXTENSION pgcolumnar CASCADE`, and it drops every
Expand Down
13 changes: 12 additions & 1 deletion src/columnar_metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,22 @@ open_columnar_table(const char *name, LOCKMODE lockmode)
nspOid = pgcolumnar_schema_oid();
relOid = get_relname_relid(name, nspOid);

/*
* NAME THE REMEDY (#1341 item 66). The usual way here is the upgrade window:
* the new library is installed and the server restarted (docs/installation.md
* steps 1 and 2), but this database's catalog is still the previous release's
* until ALTER EXTENSION UPDATE (step 3). A catalog table this library added,
* such as retired_group in 1.0-alpha5, is then missing, and DROP TABLE,
* TRUNCATE and pgcolumnar.vacuum() stop here. The error alone named only the
* table, which says neither why nor what to do.
*/
if (!OidIsValid(relOid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_TABLE),
errmsg("columnar metadata table \"%s.%s\" does not exist",
COLUMNAR_SCHEMA_NAME, name)));
COLUMNAR_SCHEMA_NAME, name),
errhint("The pgcolumnar catalog in this database may be older than the installed library. "
"Run ALTER EXTENSION pgcolumnar UPDATE in this database.")));

rel = table_open(relOid, lockmode);

Expand Down
28 changes: 22 additions & 6 deletions test/alter_am_cleanup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@ psql_run "DROP TABLE aac_t;"
check "DROP after SET ACCESS METHOD heap leaves no options or declarations" \
"$(snapshot)" "$base"

# Each cleanup arm below compares with the snapshot taken just before ITS table
# was made, not with the suite's starting one (#1341). Against $base, one leak
# above reddened every arm after it: measured, with the cleanup gated on the
# columnar AM, the never-columnar heap arm went red on aac_t's leftover rows.
#
# Round-trip: convert away and back, then DROP a still-columnar table.
pre_rt="$(snapshot)"
psql_run "CREATE TABLE aac_rt (id int) USING pgcolumnar;"
psql_run "SELECT pgcolumnar.set_options('aac_rt', stripe_row_limit => 8000);"
psql_run "ALTER TABLE aac_rt SET ACCESS METHOD heap;"
Expand All @@ -64,15 +70,16 @@ check "options survive a heap round-trip" \
"$(q "SELECT stripe_row_limit FROM pgcolumnar.options
WHERE regclass = 'aac_rt'::regclass")" "8000"
psql_run "DROP TABLE aac_rt;"
check "a round-tripped table still cleans up on DROP" "$(snapshot)" "$base"
check "a round-tripped table still cleans up on DROP" "$(snapshot)" "$pre_rt"

# Control: a never-columnar heap must not be charged for this either.
pre_h="$(snapshot)"
psql_run "CREATE TABLE aac_h (id int);"
psql_run "DROP TABLE aac_h;"
# kept alive for the VACUUM FULL control further down
psql_run "CREATE TABLE aac_h_ctl (id int);"
check "dropping a heap table that was never columnar leaves the catalogs alone" \
"$(snapshot)" "$base"
"$(snapshot)" "$pre_h"

# ---- the hook is armed in EVERY database, not only where the extension is ----
#
Expand Down Expand Up @@ -136,8 +143,12 @@ 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"
# REFRESH gets a matview of its own, made WITH NO DATA, so it does not inherit the
# CREATE arm's failure: measured, it went red as 'relation "rwm" does not exist'.
check "premise: a matview to refresh exists, made WITH NO DATA" \
"$(aac_dbrun aac_nocx 'CREATE MATERIALIZED VIEW rwr AS SELECT * FROM rw WITH NO DATA;')" "rc=0"
check "and REFRESH MATERIALIZED VIEW does too, without the extension" \
"$(aac_dbrun aac_nocx 'REFRESH MATERIALIZED VIEW rwm;')" "rc=0"
"$(aac_dbrun aac_nocx 'REFRESH MATERIALIZED VIEW rwr;')" "rc=0"
check "TRUNCATE succeeds without the extension" \
"$(aac_dbrun aac_nocx 'TRUNCATE rw;')" "rc=0"

Expand All @@ -153,14 +164,15 @@ check "control: VACUUM FULL still succeeds where the extension IS installed" \
# different set: DROP EXTENSION drops those as ordinary relations, and opening
# options while options is itself being dropped would fail.

pre_in="$(snapshot)"
psql_run "CREATE TABLE pgcolumnar.aac_inschema (id int) USING pgcolumnar;"
psql_run "SELECT pgcolumnar.set_options('pgcolumnar.aac_inschema', stripe_row_limit => 7000);"
check "premise: a table in the extension's schema recorded its options" \
"$(q "SELECT count(*) FROM pgcolumnar.options
WHERE regclass = 'pgcolumnar.aac_inschema'::regclass")" "1"
psql_run "DROP TABLE pgcolumnar.aac_inschema;"
check "dropping a table that lives in the extension's schema still cleans up" \
"$(snapshot)" "$base"
"$(snapshot)" "$pre_in"

# ---- a relation that predates CREATE EXTENSION is not an extension member ----
#
Expand Down Expand Up @@ -226,7 +238,9 @@ check "DROP EXTENSION succeeds with those catalogs populated" \

check "premise: DROP EXTENSION left the schema behind" \
"$(aac_dbq aac_dropx "SELECT count(*) FROM pg_namespace WHERE nspname='pgcolumnar'")" "1"
check "premise: and took pgcolumnar.options with it" \
# An arm, not a premise (#1236): a hook that opened options while DROP EXTENSION
# was dropping it aborted the DROP, and this read the options table still there.
check "and took pgcolumnar.options with it" \
"$(aac_dbq aac_dropx "SELECT count(*) FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'pgcolumnar' AND c.relname = 'options'")" "0"

Expand All @@ -248,8 +262,10 @@ 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 "premise: a matview to refresh exists after DROP EXTENSION, made WITH NO DATA" \
"$(aac_dbrun aac_dropx 'CREATE MATERIALIZED VIEW dxr_m AS SELECT * FROM dxr WITH NO DATA;')" "rc=0"
check "and REFRESH MATERIALIZED VIEW does too, after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'REFRESH MATERIALIZED VIEW dxm;')" "rc=0"
"$(aac_dbrun aac_dropx 'REFRESH MATERIALIZED VIEW dxr_m;')" "rc=0"
check "TRUNCATE succeeds after DROP EXTENSION" \
"$(aac_dbrun aac_dropx 'TRUNCATE dxr;')" "rc=0"

Expand Down
Loading
Loading