Skip to content

Release cat_tools 0.2.2: fix PG11+ and PG12+ compatibility#7

Open
jnasbyupgrade wants to merge 37 commits intoPostgres-Extensions:masterfrom
jnasbyupgrade:v0.2.2
Open

Release cat_tools 0.2.2: fix PG11+ and PG12+ compatibility#7
jnasbyupgrade wants to merge 37 commits intoPostgres-Extensions:masterfrom
jnasbyupgrade:v0.2.2

Conversation

@jnasbyupgrade
Copy link
Copy Markdown
Contributor

@jnasbyupgrade jnasbyupgrade commented Apr 14, 2026

Why This Release Exists

cat_tools 0.2.1 only installs correctly on PostgreSQL 9.2 – 10. Newer versions of
PostgreSQL changed system catalog internals in ways that break the 0.2.1 install script:

  • PG 11 added pg_attribute.attmissingval (pseudo-type anyarray). Views cannot
    have anyarray columns; the 0.2.1 SELECT a.* from pg_attribute picks it up and
    fails at install time.
  • PG 12 made system catalog oid columns visible as regular columns. Views using
    SELECT c.* alongside an explicit c.oid alias produce duplicate column names.

This means anyone on cat_tools 0.2.1 who upgrades PostgreSQL to version 11 or later
ends up with a broken extension. And there is no direct upgrade path from 0.2.1 to
0.3.0 — PostgreSQL automatically chains 0.2.1 → 0.2.2 → 0.3.0 when you run
ALTER EXTENSION cat_tools UPDATE, but only once 0.2.2 exists.

0.2.2 is that stepping stone. It installs and upgrades correctly on PostgreSQL 9.2
through 18+ (all currently supported versions).

Root Causes Fixed

PG 11+ (_cat_tools.pg_attribute_v): pg_attribute.attmissingval is anyarray,
which cannot be a view column. Fix: use omit_column() to exclude it from the SELECT *
expansion, then re-add it explicitly cast to text[] (or as NULL::text[] on PG ≤ 10).

PG 12+ (_cat_tools.pg_class_v, cat_tools.pg_extension_v): oid became a visible
column in system catalogs, causing SELECT c.oid AS reloid, c.* to produce duplicate
oid names. Fix: use omit_column() to exclude oid from the SELECT * expansion.

Upgrade Safety

Internal _cat_tools.* views are never directly accessed by users, so changes to them
are not a concern for user-owned views.

cat_tools.column is public, and it transitively exposes all columns of
_cat_tools.pg_attribute_v (via _cat_tools.column). Adding attmissingval anywhere
other than the end of the view chain would shift existing column positions, causing
CREATE OR REPLACE VIEW to fail with "cannot change name of view column" — even without
any user-dependent views.

The upgrade script handles this by using omit_column('_cat_tools.pg_attribute_v', array['attmissingval']) when rebuilding _cat_tools.column, so attmissingval is
appended after all pre-existing columns (column_type, base_type, pk_columns,
is_pk_member, column_default). This allows CREATE OR REPLACE VIEW on both
_cat_tools.column and cat_tools.column to succeed without requiring users to drop
views that depend on cat_tools.column.

Changes

  • sql/cat_tools.sql.in: Three views rebuilt with omit_column() for dynamic column
    lists; attmissingval exposed as text[] in _cat_tools.pg_attribute_v (and
    transitively in _cat_tools.column / cat_tools.column)
  • sql/cat_tools--0.2.1--0.2.2.sql.in: New upgrade script — safe CREATE OR REPLACE VIEW throughout; attmissingval placed at end of view chain via omit_column() on
    _cat_tools.pg_attribute_v
  • cat_tools.control: default_version = '0.2.2'
  • META.json / META.in.json: Version bumped to 0.2.2

Closes #2

🤖 Generated with Claude Code

jnasbyupgrade and others added 30 commits November 6, 2024 12:23
bed3604 Fix pg_regress on versions > 12 (#5) (#6)

git-subtree-dir: pgxntool
git-subtree-split: bed36044679d6b53ad7cd2875272552a4ad6508a
- Add __cat_tools.omit_column() helper to list catalog columns dynamically
- Add ALTER DEFAULT PRIVILEGES IN SCHEMA cat_tools GRANT USAGE ON TYPES
- Fix _cat_tools.pg_class_v: use omit_column to exclude duplicate oid (PG12+)
- Fix _cat_tools.pg_attribute_v: omit attmissingval (anyarray, PG11+), include it
  cast to text::text[] so the column is preserved across PG versions
- Fix cat_tools.pg_extension_v: use omit_column to exclude duplicate oid (PG12+)
- Add control.mk to drive version file generation
- Add sql/cat_tools--0.2.1--0.2.2.sql upgrade script

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use /* */ block comments (was --)
- pg_attribute_v always includes attmissingval column as text[]:
  NULL::text[] on PG10 (column absent), a.attmissingval::text::text[]
  on PG11+. Uses hardcoded OID 1249 (pg_catalog.pg_attribute).
- Add committed sql/cat_tools--0.2.1.sql for upgrade test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pgxntool/run-test-build.sh uses rsync to sync test/build/*.sql into
test/build/sql/ for pg_regress. The pgxn/pgxn-tools container doesn't
include rsync, so install it explicitly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- trigger__parse: handle EXECUTE FUNCTION (PG11+) and pg_temp schema alias mismatch
- extension.sql test: avoid duplicate oid column (e.oid, e.*) on PG12+
- attribute.sql test: skip anyarray column (attmissingval) in results_eq comparison
- object_type.sql test: grant CREATE on public schema for PG15+ compatibility
- general.out: update expected output (test count was stale)
- zzz_build.out: update expected output for new exec() calls
- Add CLAUDE.md with SQL block comment style standard
- Update .gitignore to track .claude/ but ignore *.local.json and worktrees/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Version-specific upgrade scripts are now committed directly as .sql files
rather than generated from .sql.in sources. Remove the versioned_in/versioned_out
machinery and switch DATA to pick up all historical install scripts via wildcard,
filtering out files already provided by pgxntool/base.mk (EXTENSION_VERSION_FILES
and sql/*--*--*.sql upgrade scripts).

Note: pgxs DATA is not cleaned by `make clean` (only DATA_built is), so static
committed SQL files are safe to include in DATA.

Also add explanatory comment to sql/.gitignore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace DROP VIEW ... CASCADE with CREATE OR REPLACE VIEW throughout the
0.2.1→0.2.2 upgrade script. On PG < 12 the column lists for pg_class_v
and pg_extension_v are unchanged, so CREATE OR REPLACE VIEW works with no
disruption to dependents. For pg_attribute_v, attmissingval is moved to the
end of the column list (matching the new install script) so it can be added
as a trailing column without invalidating any existing dependent views.

Also removes the now-unnecessary recreation of pg_extension__get and the
__cat_tools.create_function helper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…icts

Kept pgext/master's Makefile approach (versioned_in/versioned_out) since
sql/cat_tools--0.2.0.sql.in and sql/cat_tools--0.2.1.sql.in exist.
Merged both sets of .gitignore additions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pgxntool 2.0 added -include control.mk to base.mk. Having it again in
the Makefile caused control.mk to be processed twice, doubling up
EXTENSION_VERSION_FILES (duplicate sql/cat_tools--0.2.2.sql in DATA)
and triggering "overriding recipe" warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
::regnamespace was hardcoded but that type only exists on PG 9.5+.
The upgrade script is pre-built SQL (no SED processing), so use the
same runtime EXISTS check pattern as the attmissingval fix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The upgrade script is now SED-processed like the install scripts.
Replaces the runtime EXISTS/regnamespace check with proper
-- SED: REQUIRES 9.5! / -- SED: PRIOR TO 9.5! markers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add LT11 and LT12 SED variables to Makefile. Replace the CASE-in-format
EXISTS check for attmissingval with -- SED: REQUIRES 11! / PRIOR TO 11!
markers in both the install and upgrade scripts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restore -- SED: PRIOR TO 9.5! on nspname line; it had been left in
already-processed form (-- Not used prior to 9.5:).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The install script for version 0.2.2 must be named cat_tools--0.2.2.sql,
not cat_tools--0.2.1.sql. Add the required header line per control.mk rule.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_tools.column

- Add 'oid' to omit_column for pg_attribute (prevents duplicate on PG12+)
- Add comment explaining attmissingval is manually included in the view
- HISTORY.asc: document that cat_tools.column now exposes attmissingval

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Explain which PG versions each release supports, why 0.2.1 breaks on
PG11+ and PG12+, and how 0.2.2 enables the 0.2.1 → 0.2.2 → 0.3.0
upgrade chain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Using plain SELECT * to rebuild _cat_tools.column would insert
attmissingval before column_type (shifting its position), causing
CREATE OR REPLACE VIEW to fail with "cannot change name of view
column". Fix: use omit_column() on _cat_tools.pg_attribute_v to
enumerate all columns except attmissingval, then append it explicitly
after column_default.

This ensures the upgrade does not require users to drop views
built on cat_tools.column.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0.3.0 is not yet released. The forward-reference is inaccurate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pg-upgrade-test: verify cat_tools survives pg_upgrade across the
PG10→11 (attmissingval) and PG11→12 (oid visibility) boundaries,
testing both the next minor version and the latest PG (18).

extension-update-test: verify ALTER EXTENSION cat_tools UPDATE walks
the full upgrade chain from 0.1.0 to current on PG 9.6–18.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
jnasbyupgrade and others added 7 commits April 20, 2026 18:09
Debian's pg_upgradecluster handles data directories, config files,
and port management automatically — cleaner and more correct than
the manual pg_upgrade invocation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pg-upgrade-test: add postgresql-server-dev-<new_pg> to the apt-get
install step; pg_upgradecluster requires it when the old version's
server-dev package is present.

extension-update-test: remove CREATE SCHEMA cat_tools from historical
install scripts (0.1.0, 0.1.3, 0.1.4, 0.1.5). Since the control file
has `schema = cat_tools`, PostgreSQL auto-creates that schema before
running the install script, causing "schema already exists" when the
script also tries to create it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cluster

pg_upgradecluster requires the server-dev package for both the old and
new PostgreSQL versions. pg-start installs postgresql-server-dev-<old>
automatically; we need to explicitly install postgresql-server-dev-<new>
alongside postgresql-<new>.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
omit_column: fix != ANY → NOT (= ANY) so multi-element omit arrays
actually work. != ANY(array) means "not equal to at least one element"
(always true for arrays with 2+ elements); the correct form is
NOT (= ANY(array)). This was harmless before since we only passed
single-element arrays; broken by the array['oid', 'attmissingval'] change.

test/sql/attribute.sql: fix attmissingval::text[] → ::text::text[] to
avoid "cannot cast type anyarray to text[]" on PG 17. Mirrors the
double-cast already used in the install script.

ci.yml:
- Drop PG 9.2–9.6 from test matrices (not available in trixie-pgdg)
- extension-update-test: start from VERSION '0.2.0' (oldest version
  compatible with schema = 'cat_tools' in the control file)
- pg-upgrade-test: query regression database by name pattern for
  version verify step (extension lives in cat_tools_* db, not postgres)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cleaner SQL idiom, same semantics.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pg_upgrade

extension-update-test: limit to pg: [11, 10] — PG 12+ exposed oid as a
visible column in SELECT *, breaking cat_tools 0.2.0 and 0.2.1 fresh
installs with "column oid specified more than once". No pre-0.2.2 version
installs on PG 12+, so the upgrade path test only applies to PG ≤ 11.

pg-upgrade-test: add "make install" step for the new PG version before
running pg_upgradecluster. The extension files must exist in the new
cluster's extension directory so the pg_dumpall restore can recreate the
extension. The old install only covered the old PG version's directory.

CLAUDE.md: document why the extension-update-test matrix is limited and
that it should be expanded when working on new versions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant