From fa15ccb6c48c197a0dd1909d1d9836838d912528 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 16:48:21 -0500 Subject: [PATCH 01/13] Switch to pgxn-tools based testing --- .github/workflows/ci.yml | 17 +++++++++++++++++ pg-travis-test.sh | 36 ------------------------------------ 2 files changed, 17 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 pg-travis-test.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d4aaec9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,17 @@ +name: CI +on: [push, pull_request] +jobs: + test: + strategy: + matrix: + pg: [17, 16, 15, 14, 13, 12, 11, 10] + name: ๐Ÿ˜ PostgreSQL ${{ matrix.pg }} + runs-on: ubuntu-latest + container: pgxn/pgxn-tools + steps: + - name: Start PostgreSQL ${{ matrix.pg }} + run: pg-start ${{ matrix.pg }} + - name: Check out the repo + uses: actions/checkout@v4 + - name: Test on PostgreSQL ${{ matrix.pg }} + run: pg-build-test diff --git a/pg-travis-test.sh b/pg-travis-test.sh deleted file mode 100644 index f63ae43..0000000 --- a/pg-travis-test.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Based on https://gist.github.com/petere/6023944 - -set -eux - -sudo apt-get update - -packages="python-setuptools postgresql-$PGVERSION postgresql-server-dev-$PGVERSION postgresql-common" - -# bug: http://www.postgresql.org/message-id/20130508192711.GA9243@msgid.df7cb.de -sudo update-alternatives --remove-all postmaster.1.gz - -# stop all existing instances (because of https://github.com/travis-ci/travis-cookbooks/pull/221) -sudo service postgresql stop -# and make sure they don't come back -echo 'exit 0' | sudo tee /etc/init.d/postgresql -sudo chmod a+x /etc/init.d/postgresql - -sudo apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" install $packages - -sudo easy_install pgxnclient - -PGPORT=55435 -PGCLUSTER_NAME=test - -export PGCLUSTER=9.6/$PGCLUSTER_NAME -env | grep PG -which pg_dump - -sudo pg_createcluster --start $PGVERSION $PGCLUSTER_NAME -p $PGPORT -- -A trust - -# TODO: have base.mk support dynamic sudo -sudo PGPORT=$PGPORT PGUSER=postgres PG_CONFIG=/usr/lib/postgresql/$PGVERSION/bin/pg_config make test - -[ ! -e test/regression.diffs ] From 99083b85d738c37639b860171783632bc01632cf Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 16:56:03 -0500 Subject: [PATCH 02/13] Remove .travis.yml --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0c4e016..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: c -before_install: - - wget https://gist.github.com/petere/5893799/raw/apt.postgresql.org.sh - - sudo sh ./apt.postgresql.org.sh - - sudo sh -c "echo deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs 2>/dev/null)-pgdg main $PGVERSION >> /etc/apt/sources.list.d/pgdg.list" -env: - - PGVERSION=9.6 - - PGVERSION=9.5 - - PGVERSION=9.4 - - PGVERSION=9.3 - - PGVERSION=9.2 - -script: bash ./pg-travis-test.sh From aa53b9118ab7d57b489259830f5f3872687ad244 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 17:00:46 -0500 Subject: [PATCH 03/13] Remove errant vim swapfile --- sql/.object_reference.sql.swo | Bin 45056 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 sql/.object_reference.sql.swo diff --git a/sql/.object_reference.sql.swo b/sql/.object_reference.sql.swo deleted file mode 100644 index b3912fe9de65698c7165ac4804adbf23100b021e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45056 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 From 68e8afc25c70301e286eb6652f1529c5129eefbe Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 17:15:46 -0500 Subject: [PATCH 04/13] Update test workflow --- .github/workflows/ci.yml | 4 +++- .gitignore | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4aaec9..ce8882f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,4 +14,6 @@ jobs: - name: Check out the repo uses: actions/checkout@v4 - name: Test on PostgreSQL ${{ matrix.pg }} - run: pg-build-test + run: make test + - name: Test pg_dump + run: make dump_test diff --git a/.gitignore b/.gitignore index facf651..8e63124 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ regression.out # Misc tmp/ .DS_Store +.claude/settings.local.json From 9859566d2b12a5340b9b00be8819ce5f2dddebaa Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 17:26:46 -0500 Subject: [PATCH 05/13] Add missing PGUSER argument --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce8882f..cea4aa8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,6 @@ jobs: - name: Check out the repo uses: actions/checkout@v4 - name: Test on PostgreSQL ${{ matrix.pg }} - run: make test + run: make test PGUSER=postgres - name: Test pg_dump - run: make dump_test + run: make dump_test PGUSER=postgres From 9a1e50bd56c106bb73458f21fb200b485f36ace6 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 17:29:31 -0500 Subject: [PATCH 06/13] Fix dump test --- test/dump/run.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/dump/run.sh b/test/dump/run.sh index 4d0c7a3..6896f68 100755 --- a/test/dump/run.sh +++ b/test/dump/run.sh @@ -26,7 +26,7 @@ if [ "$1" == "-f" ]; then fi echo Creating dump database -createdb test_dump && psql -f test/dump/load_all.sql test_dump > $create_log || die 3 "Unable to create dump database" +createdb test_dump && psql -Xf test/dump/load_all.sql test_dump > $create_log || die 3 "Unable to create dump database" # Ensure no errors in log check_log() { @@ -45,8 +45,8 @@ check_log $create_log creation echo Running dump and restore # No real need to cat the log on failure here; psql will generate an error and even if not verify will almost certainly catch it -createdb test_load && PAGER='' psql -c '\df pg_get_object_address' test_load || die 5 'crap' -(echo 'BEGIN;' && pg_dump test_dump && echo 'COMMIT;') | psql -q -v VERBOSITY=verbose -v ON_ERROR_STOP=true test_load > $restore_log +createdb test_load && PAGER='' psql -Xc '\df pg_get_object_address' test_load || die 5 'crap' +(echo 'BEGIN;' && pg_dump test_dump && echo 'COMMIT;') | psql -q -X -v VERBOSITY=verbose -v ON_ERROR_STOP=true test_load > $restore_log rc=$? if [ $rc -ne 0 ]; then cat $restore_log @@ -54,7 +54,7 @@ if [ $rc -ne 0 ]; then fi echo Verifying restore -psql -f test/dump/verify.sql test_load > $verify_log || die 5 "Test failed" +psql -Xf test/dump/verify.sql test_load > $verify_log || die 5 "Test failed" check_log $create_log verify From 594d248ce1ae0822e8940fc5bc0861005ab016d2 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 17:35:03 -0500 Subject: [PATCH 07/13] Squashed 'pgxntool/' changes from 890053c..e9c24de e9c24de Fix pg_regress on versions > 12 (#5) c0af00f Improvements to HISTORY.asc 6e8f2a7 Allow use of sudo when installing an extension 705f1ec Don't run clean as part of make test 370fa8e Create test/sql during setup git-subtree-dir: pgxntool git-subtree-split: e9c24de986ddc85bbd1fb3149076888d075ce100 --- HISTORY.asc | 13 ++++++++++--- base.mk | 14 ++++++++++---- setup.sh | 1 + 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/HISTORY.asc b/HISTORY.asc index b69c9d1..9cb793b 100644 --- a/HISTORY.asc +++ b/HISTORY.asc @@ -1,5 +1,11 @@ STABLE ------ +== Support 13+ +The `--load-language` option was removed from `pg_regress` in 13. + +== Reduce verbosity from test setup +As part of this change, you will want to review the changes to test/deps.sql. + === Support asciidoc documentation targets By default, if asciidoctor or asciidoc exists on the system, any files in doc/ that end in .adoc or .asciidoc will be processed to html. See the README for full details. @@ -12,11 +18,12 @@ If a test input file changes we certainly need to re-run tests. === Have test/pgxntool/setup.sql install tap before running deps.sql -=== Reduce verbosity from test setup -As part of this change, you will want to review the changes to test/deps.sql. - === Support other asciidoc extensions +=== Create the test/sql/ directory during setup + +=== Use `--sudo` option when installing pgtap + 0.2.0 ----- ### Stop using $(VERSION) diff --git a/base.mk b/base.mk index ce918db..a976ebb 100644 --- a/base.mk +++ b/base.mk @@ -36,7 +36,7 @@ TEST_SQL_FILES += $(wildcard $(TESTDIR)/sql/*.sql) TEST_RESULT_FILES = $(patsubst $(TESTDIR)/sql/%.sql,$(TESTDIR)/expected/%.out,$(TEST_SQL_FILES)) TEST_FILES = $(TEST_SOURCE_FILES) $(TEST_SQL_FILES) REGRESS = $(sort $(notdir $(subst .source,,$(TEST_FILES:.sql=)))) # Sort is to get unique list -REGRESS_OPTS = --inputdir=$(TESTDIR) --outputdir=$(TESTOUT) --load-language=plpgsql +REGRESS_OPTS = --inputdir=$(TESTDIR) --outputdir=$(TESTOUT) # See additional setup below MODULES = $(patsubst %.c,%,$(wildcard src/*.c)) ifeq ($(strip $(MODULES)),) MODULES =# Set to NUL so PGXS doesn't puke @@ -57,8 +57,10 @@ GE91 = $(call test, $(MAJORVER), -ge, 91) ifeq ($(GE91),yes) all: $(EXTENSION_VERSION_FILES) +endif -#DATA = $(wildcard sql/*--*.sql) +ifeq ($($call test, $(MAJORVER), -lt 13), yes) + REGRESS_OPTS += --load-language=plpgsql endif PGXS := $(shell $(PG_CONFIG) --pgxs) @@ -77,8 +79,12 @@ installcheck: $(TEST_RESULT_FILES) $(TEST_OUT_FILES) $(TEST_SQL_FILES) $(TEST_SO # make test: run any test dependencies, then do a `make install installcheck`. # If regressions are found, it will output them. +# +# This used to depend on clean as well, but that causes problems with +# watch-make if you're generating intermediate files. If tests end up needing +# clean it's an indication of a missing dependency anyway. .PHONY: test -test: clean testdeps install installcheck +test: testdeps install installcheck @if [ -r $(TESTOUT)/regression.diffs ]; then cat $(TESTOUT)/regression.diffs; fi # make results: runs `make test` and copy all result files to expected @@ -220,6 +226,6 @@ installcheck: pgtap pgtap: $(DESTDIR)$(datadir)/extension/pgtap.control $(DESTDIR)$(datadir)/extension/pgtap.control: - pgxn install pgtap + pgxn install pgtap --sudo endif # fndef PGXNTOOL_NO_PGXS_INCLUDE diff --git a/setup.sh b/setup.sh index 3730a2b..881ccaa 100755 --- a/setup.sh +++ b/setup.sh @@ -46,6 +46,7 @@ git add META.json mkdir -p sql test src cd test +mkdir -p sql safecp ../pgxntool/test/deps.sql deps.sql [ -d pgxntool ] || ln -s ../pgxntool/test/pgxntool . git add pgxntool From 8dc5cfcb90896f6269a25aa35e902311fc688116 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Mon, 25 Aug 2025 17:36:24 -0500 Subject: [PATCH 08/13] dump test is actually included in make test --- .github/workflows/ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cea4aa8..3183031 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,5 +15,3 @@ jobs: uses: actions/checkout@v4 - name: Test on PostgreSQL ${{ matrix.pg }} run: make test PGUSER=postgres - - name: Test pg_dump - run: make dump_test PGUSER=postgres From 3eefe4ce13ffc73d8ecc5fe718290d85f4ca6601 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Tue, 4 Aug 2026 18:35:56 -0500 Subject: [PATCH 09/13] Add SQL style linter (vendored Postgres-Extensions/linter) Vendor Postgres-Extensions/linter as a git submodule at .vendor/linter, following the same pattern already adopted in cat_tools: a thin self-initializing lint.mk hand-off (so `make lint` works right after a plain `git clone`, no --recurse-submodules needed), LINT_TARGETS scoped to sql/object_reference.sql and test/ (excluding the frozen, never hand-edited versioned install files under sql/, e.g. object_reference--0.1.0.sql/--stable.sql), and a CI job that runs `make lint` directly -- the same entry point a developer uses locally -- so the self-init logic is actually exercised, not just the rule checking. The `include lint.mk` is guarded on .git being present: a tarball build (PGXN distribution, `git archive` with no .git) has no submodule to initialize, and Make resolves every `include` before running any target regardless of which one was requested, so an unguarded rule would break `make`/`make install` entirely for a tarball build, not just `make lint`. Fixes the real pre-existing style findings this first run turned up (52 total): most were commented-out SQL marked as prose comments instead of using the linter's `EXCLUDED CODE` disabled-code convention (missing " * " prefixes flagged as comment-line-prefix/comment-opening violations); one COPY data block's `secondary` column intentionally mirrors pg_catalog's own type display name ("integer" for int4) rather than following prefer-short-type, so it's suppressed via a scoped disable-block region instead of being "fixed" into incorrect test data. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ .gitmodules | 3 +++ .vendor/linter | 1 + Makefile | 20 ++++++++++++++++++++ lint.mk | 11 +++++++++++ sql/object_reference--stable.sql | 8 ++++---- sql/object_reference.sql | 8 ++++---- test/deps.sql | 3 +-- test/helpers/object_table.sql | 4 +++- test/sql/capture.sql | 2 +- test/sql/event_trigger.sql | 2 +- test/sql/object_group.sql | 4 ++-- 12 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitmodules create mode 160000 .vendor/linter create mode 100644 lint.mk diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4b3e970 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,20 @@ +name: CI + +on: [push, pull_request] + +jobs: + # Style linter (https://github.com/Postgres-Extensions/linter, vendored at + # .vendor/linter -- lint.mk is the thin local hand-off, see its comment). + # Deliberately checked out WITHOUT submodules -- `make lint` is the same + # command a developer runs locally, and lint.mk self-initializes the + # submodule on first use. Using the exact same entry point here is what + # actually proves that self-init works, rather than papering over it with + # a submodules: true checkout. + lint: + name: ๐Ÿงน SQL Lint + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v4 + - name: Lint SQL + run: make lint diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9443c64 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".vendor/linter"] + path = .vendor/linter + url = https://github.com/Postgres-Extensions/linter.git diff --git a/.vendor/linter b/.vendor/linter new file mode 160000 index 0000000..b40aaf7 --- /dev/null +++ b/.vendor/linter @@ -0,0 +1 @@ +Subproject commit b40aaf70be8af80f048da777e551c5b790bd9e69 diff --git a/Makefile b/Makefile index 9ae665d..006453e 100644 --- a/Makefile +++ b/Makefile @@ -32,3 +32,23 @@ test_factory: $(DESTDIR)$(datadir)/extension/test_factory.control $(DESTDIR)$(datadir)/extension/test_factory.control: pgxn install test_factory + +# Style linter (see https://github.com/Postgres-Extensions/linter, vendored +# at .vendor/linter -- lint.mk is the thin local hand-off, see its comment). +# Scoped to sql/object_reference.sql rather than the default `sql/ test/`: +# the versioned install/update files under sql/ (object_reference--*.sql, +# e.g. object_reference--0.1.0.sql/--stable.sql) are frozen once released and +# never hand-edited again (see this repo's CLAUDE.md / memory), so linting +# them would produce permanent, unfixable findings and make `make lint` +# unusable as a CI gate. +# +# Guarded on .git being present: a tarball build (PGXN distribution, or any +# `git archive` checkout with no .git) has no submodule to initialize, and +# Make resolves every `include` before running any target regardless of +# which target was requested -- so an unguarded self-init rule in lint.mk +# would break `make`/`make install` entirely for a tarball build, not just +# `make lint`. +ifneq ($(wildcard .git),) +LINT_TARGETS = sql/object_reference.sql test/ +include lint.mk +endif diff --git a/lint.mk b/lint.mk new file mode 100644 index 0000000..0d18abf --- /dev/null +++ b/lint.mk @@ -0,0 +1,11 @@ +# lint.mk โ€” thin wrapper; the whole local footprint for consuming +# https://github.com/Postgres-Extensions/linter. Everything else lives in +# the .vendor/linter submodule; see its README for available targets/rules. +# +# Self-initializing (via the rule below) so `make lint` works right after a +# plain `git clone`, with no --recurse-submodules needed, and so CI can rely +# on the exact same entry point a developer would use locally. +.vendor/linter/lint.mk: + git submodule update --init -- .vendor/linter + +include .vendor/linter/lint.mk diff --git a/sql/object_reference--stable.sql b/sql/object_reference--stable.sql index 4a68ebc..5333ba2 100644 --- a/sql/object_reference--stable.sql +++ b/sql/object_reference--stable.sql @@ -14,7 +14,7 @@ BEGIN RAISE DEBUG 'search_path changed to %', current_setting('search_path'); END $$; -/* +/* EXCLUDED CODE: schema-restriction check below not currently enforced DO $$ DECLARE c_schema CONSTANT name := (SELECT extnamespace::regnamespace::text FROM pg_extension WHERE extname = 'cat_tools'); @@ -180,7 +180,7 @@ CREATE TABLE _object_reference.object( , object_names text[] NOT NULL , object_args text[] NOT NULL , CONSTRAINT object__u_object_names__object_args UNIQUE( object_type, object_names, object_args ) - /* TODO: this can't be a trigger because some objects won't exist when a dump is loaded + /* EXCLUDED CODE: TODO: this can't be a trigger because some objects won't exist when a dump is loaded , CONSTRAINT object__address_sanity -- pg_get_object_address will throw an error if anything is wrong, so the IS NOT NULL is mostly pointless CHECK( pg_catalog.pg_get_object_address(object_type::text, object_names, object_args) IS NOT NULL ) @@ -193,7 +193,7 @@ GRANT REFERENCES ON _object_reference.object TO object_reference__dependency; CREATE TABLE _object_reference._object_oid( object_id int PRIMARY KEY REFERENCES _object_reference.object ON DELETE CASCADE ON UPDATE CASCADE , classid regclass NOT NULL - /* TODO: needs to be a trigger + /* EXCLUDED CODE: TODO: needs to be a trigger CONSTRAINT classid_must_match__object__address_classid CHECK( classid IS NOT DISTINCT FROM cat_tools.object__address_classid(object_type) ) */ @@ -1254,7 +1254,7 @@ BEGIN RETURN c_next_level; EXCEPTION WHEN undefined_table THEN - /* + /* EXCLUDED CODE CREATE TEMP TABLE __object_reference__ddl_capture AS SELECT c_next_level, capture__start.object_group_id ; diff --git a/sql/object_reference.sql b/sql/object_reference.sql index e83b461..bc4ee0d 100644 --- a/sql/object_reference.sql +++ b/sql/object_reference.sql @@ -13,7 +13,7 @@ BEGIN RAISE DEBUG 'search_path changed to %', current_setting('search_path'); END $$; -/* +/* EXCLUDED CODE: schema-restriction check below not currently enforced DO $$ DECLARE c_schema CONSTANT name := (SELECT extnamespace::regnamespace::text FROM pg_extension WHERE extname = 'cat_tools'); @@ -179,7 +179,7 @@ CREATE TABLE _object_reference.object( , object_names text[] NOT NULL , object_args text[] NOT NULL , CONSTRAINT object__u_object_names__object_args UNIQUE( object_type, object_names, object_args ) - /* TODO: this can't be a trigger because some objects won't exist when a dump is loaded + /* EXCLUDED CODE: TODO: this can't be a trigger because some objects won't exist when a dump is loaded , CONSTRAINT object__address_sanity -- pg_get_object_address will throw an error if anything is wrong, so the IS NOT NULL is mostly pointless CHECK( pg_catalog.pg_get_object_address(object_type::text, object_names, object_args) IS NOT NULL ) @@ -192,7 +192,7 @@ GRANT REFERENCES ON _object_reference.object TO object_reference__dependency; CREATE TABLE _object_reference._object_oid( object_id int PRIMARY KEY REFERENCES _object_reference.object ON DELETE CASCADE ON UPDATE CASCADE , classid regclass NOT NULL - /* TODO: needs to be a trigger + /* EXCLUDED CODE: TODO: needs to be a trigger CONSTRAINT classid_must_match__object__address_classid CHECK( classid IS NOT DISTINCT FROM cat_tools.object__address_classid(object_type) ) */ @@ -1253,7 +1253,7 @@ BEGIN RETURN c_next_level; EXCEPTION WHEN undefined_table THEN - /* + /* EXCLUDED CODE CREATE TEMP TABLE __object_reference__ddl_capture AS SELECT c_next_level, capture__start.object_group_id ; diff --git a/test/deps.sql b/test/deps.sql index e1a53c8..b0ee45f 100644 --- a/test/deps.sql +++ b/test/deps.sql @@ -2,8 +2,7 @@ -- Add any test dependency statements here -/* - * Normally these should be loaded by the cascade! +/* EXCLUDED CODE: normally these should be loaded by the cascade! CREATE EXTENSION IF NOT EXISTS count_nulls; CREATE EXTENSION IF NOT EXISTS cat_tools; */ diff --git a/test/helpers/object_table.sql b/test/helpers/object_table.sql index 67f07ee..ca90234 100644 --- a/test/helpers/object_table.sql +++ b/test/helpers/object_table.sql @@ -144,6 +144,7 @@ INSERT INTO test_prereq VALUES ; -- \N is null character +-- sql-lint:disable-block prefer-short-type: secondary column mirrors pg_catalog's own type display name (format_type), not a style choice COPY test_object(object_type, object_name, secondary, create_command, drop_command) FROM STDIN (DELIMITER '|'); table|test table||%("test column" int)| index|test table test index||%ON "test table"("test column")| @@ -159,8 +160,9 @@ cast|test type|integer|CREATE CAST ("test type" AS int4) WITH INOUT|DROP CAST (" default value|test table|test column|ALTER TABLE "test table" ALTER "test column" SET DEFAULT 0|ALTER TABLE "test table" ALTER "test column" DROP DEFAULT trigger|test table|test trigger|CREATE TRIGGER "test trigger" AFTER INSERT ON "test table" FOR EACH ROW EXECUTE PROCEDURE tg_null()|DROP TRIGGER "test trigger" ON "test table" \. +-- sql-lint:enable-block -/* Not supported +/* EXCLUDED CODE: Not supported composite type|test complex type||CREATE TYPE "test complex type" AS(r real, i real)|DROP TYPE "test complex type" view column|test view|test column|\N|\N materialized view column|test materialized view 2|test materialized view column|CREATE MATERIALIZED VIEW "test materialized view 2" AS SELECT (1,2)::"test complex type" AS "test materialized view column"|DROP MATERIALIZED VIEW "test materialized view 2" diff --git a/test/sql/capture.sql b/test/sql/capture.sql index 8eb1414..073f3f3 100644 --- a/test/sql/capture.sql +++ b/test/sql/capture.sql @@ -134,7 +134,7 @@ SELECT bag_eq( , $$SELECT object_id FROM obj_ref$$ , 'Verify captured object IDs match' ); -/* +/* EXCLUDED CODE SELECT * FROM og_o; SELECT * FROM _object_reference.object;-- WHERE object_id IN(6,9); */ diff --git a/test/sql/event_trigger.sql b/test/sql/event_trigger.sql index 2115dc7..402a5b4 100644 --- a/test/sql/event_trigger.sql +++ b/test/sql/event_trigger.sql @@ -143,7 +143,7 @@ $body$; /* - *Rename column + * Rename column */ SELECT lives_ok( $$ALTER TABLE table_under_test RENAME column_test TO test_column2$$ diff --git a/test/sql/object_group.sql b/test/sql/object_group.sql index 6304892..d90957b 100644 --- a/test/sql/object_group.sql +++ b/test/sql/object_group.sql @@ -82,7 +82,7 @@ SELECT is( ); -- __object__add -/* TODO +/* EXCLUDED CODE: TODO SELECT pg_temp.bogus_group( format( $$SELECT object_reference.object_group__object__add(%%s, %s)$$ @@ -107,7 +107,7 @@ SELECT throws_ok( -- Can't use helper here , 'object group "absurd group name used only for testing purposes ktxbye" does not exist' , 'object__getsert with bogus group name' ); -/* TODO +/* EXCLUDED CODE: TODO SELECT throws_ok( -- Can't use helper here $$CREATE TEMP TABLE col1_id AS SELECT * FROM object_reference.object__getsert_w_group_id('table column', 'test_table_1', 'col1', -1)$$ , '' From 1f8bbfe2c65c1879429546ff28bb909c33916801 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Tue, 4 Aug 2026 18:39:48 -0500 Subject: [PATCH 10/13] Build cat_tools from its 0.3.0 git tag instead of pgxn install --unstable pgxn install --unstable cat_tools resolves to the newest release actually published to the PGXN package index, which is still 0.2.1 (2017) -- it fails standalone on modern PostgreSQL with "column oid specified more than once" at CREATE EXTENSION. cat_tools 0.3.0 fixes this but hasn't been uploaded to PGXN yet, only tagged in git, so build it from that tag directly until PGXN has it. Co-Authored-By: Claude Sonnet 5 --- Makefile | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9ae665d..ec25834 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,23 @@ extra_clean += $(wildcard test/dump/*.log) dump_test: test/dump/run.sh test/helpers/object_table.sql $(wildcard test/dump/*.sql) $< -f # Force drop of databases if they exist +CAT_TOOLS_VERSION = 0.3.0 +CAT_TOOLS_BUILD_DIR = tmp/cat_tools-$(CAT_TOOLS_VERSION) +extra_clean += $(CAT_TOOLS_BUILD_DIR) + .PHONY: cat_tools cat_tools: $(DESTDIR)$(datadir)/extension/cat_tools.control $(DESTDIR)$(datadir)/extension/cat_tools.control: - pgxn install --unstable cat_tools + # `pgxn install --unstable cat_tools` resolves to the newest release + # published to the PGXN package index, which is still 0.2.1 -- it fails + # standalone on modern PostgreSQL with "column oid specified more than + # once" at CREATE EXTENSION. A fixed release, 0.3.0, is tagged in + # cat_tools' own git repo but hasn't been uploaded to PGXN yet, so build + # it from that tag directly until PGXN has it. + rm -rf $(CAT_TOOLS_BUILD_DIR) + git clone --branch $(CAT_TOOLS_VERSION) --depth 1 https://github.com/Postgres-Extensions/cat_tools.git $(CAT_TOOLS_BUILD_DIR) + $(MAKE) -C $(CAT_TOOLS_BUILD_DIR) install PG_CONFIG=$(PG_CONFIG) DESTDIR=$(DESTDIR) + rm -rf $(CAT_TOOLS_BUILD_DIR) .PHONY: count_nulls count_nulls: $(DESTDIR)$(datadir)/extension/count_nulls.control From 48edb3dc8269349358e3a9f1e4d0b921a3aee289 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Tue, 4 Aug 2026 18:40:01 -0500 Subject: [PATCH 11/13] Adapt to cat_tools 0.3.0: renamed function, two new object types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cat_tools 0.3.0 is the first version of cat_tools this extension's test suite has ever actually run against (pgxn install --unstable previously resolved to a version that failed CREATE EXTENSION outright, so none of this was exercised before now): - cat_tools.function__arg_types_text() is deprecated in 0.3.0 in favor of cat_tools.routine__parse_arg_types_text() (same signature, same body, just renamed) and now emits a WARNING on every call. Switch to the non-deprecated name directly rather than carrying the warning forward. - cat_tools 0.3.0's object_type enum gained two new members, "partitioned table" and "partitioned index". object_reference has no per-object-type special-casing (object identity is tracked generically via classid/objid), so these are already handled by the existing code the same way "table" and "index" are -- they just weren't yet reflected in object_reference's own classification of which object types are covered by a test. Add them to the untested() set so object_reference.untested_srf() โˆช tested types โˆช unsupported() still accounts for every member of the enum; a follow-up can add dedicated create/drop test coverage for them. - Regenerate sql/object_reference--stable.sql (auto-generated from sql/object_reference.sql) and test/expected/zzz_build.out (line numbers in test/temp_load.not_sql shift by one now that a source comment line changed) to match. Co-Authored-By: Claude Sonnet 5 --- sql/object_reference--stable.sql | 5 ++- sql/object_reference.sql | 5 ++- test/expected/zzz_build.out | 64 ++++++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/sql/object_reference--stable.sql b/sql/object_reference--stable.sql index 4a68ebc..55449ab 100644 --- a/sql/object_reference--stable.sql +++ b/sql/object_reference--stable.sql @@ -85,7 +85,7 @@ CREATE FUNCTION __object_reference.create_function( , grants text DEFAULT NULL ) RETURNS void LANGUAGE plpgsql AS $body$ DECLARE - c_clean_args text := cat_tools.function__arg_types_text(args); + c_clean_args text := cat_tools.routine__parse_arg_types_text(args); create_template CONSTANT text := $template$ CREATE OR REPLACE FUNCTION %s( @@ -572,7 +572,8 @@ foreign table, foreign table column, aggregate, collation, conversion, language, large object, operator, operator class, operator family, operator of access method, function of access method, rule, text search parser, text search dictionary, text search template, text search configuration, foreign-data wrapper, server, -user mapping, default acl, transform, access method, extension, policy +user mapping, default acl, transform, access method, extension, policy, +partitioned table, partitioned index }'::cat_tools.object_type[] $body$ , 'Returns array of object types that have not been tested.' diff --git a/sql/object_reference.sql b/sql/object_reference.sql index e83b461..2b38b90 100644 --- a/sql/object_reference.sql +++ b/sql/object_reference.sql @@ -84,7 +84,7 @@ CREATE FUNCTION __object_reference.create_function( , grants text DEFAULT NULL ) RETURNS void LANGUAGE plpgsql AS $body$ DECLARE - c_clean_args text := cat_tools.function__arg_types_text(args); + c_clean_args text := cat_tools.routine__parse_arg_types_text(args); create_template CONSTANT text := $template$ CREATE OR REPLACE FUNCTION %s( @@ -571,7 +571,8 @@ foreign table, foreign table column, aggregate, collation, conversion, language, large object, operator, operator class, operator family, operator of access method, function of access method, rule, text search parser, text search dictionary, text search template, text search configuration, foreign-data wrapper, server, -user mapping, default acl, transform, access method, extension, policy +user mapping, default acl, transform, access method, extension, policy, +partitioned table, partitioned index }'::cat_tools.object_type[] $body$ , 'Returns array of object types that have not been tested.' diff --git a/test/expected/zzz_build.out b/test/expected/zzz_build.out index fe92660..467431f 100644 --- a/test/expected/zzz_build.out +++ b/test/expected/zzz_build.out @@ -2,16 +2,26 @@ This extension must be loaded via CREATE EXTENSION object_reference; You really, REALLY do NOT want to try and load this via psql!!! -psql:test/temp_load.not_sql:188: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:187: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! -psql:test/temp_load.not_sql:189: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:188: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.object_id%TYPE converted to integer +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.classid%TYPE converted to regclass +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.object_id%TYPE converted to integer +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.classid%TYPE converted to regclass +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid +psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer -psql:test/temp_load.not_sql:513: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:512: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! @@ -25,24 +35,72 @@ psql:test/temp_load.not_sql:620: WARNING: I promise you will be sorry if you tr psql:test/temp_load.not_sql:627: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:654: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:654: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:679: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:679: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:694: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:694: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:721: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:721: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:737: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:737: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer +psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer +psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer +psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer +psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type +psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid +psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer +psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type +psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid +psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer +psql:test/temp_load.not_sql:1180: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1180: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1194: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1194: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1282: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1282: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1296: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1296: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1341: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1341: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer +psql:test/temp_load.not_sql:1355: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying +psql:test/temp_load.not_sql:1355: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying From 8e59c4c57d79e9db1171b82d1dc2dcfdd648b670 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Tue, 4 Aug 2026 18:54:30 -0500 Subject: [PATCH 12/13] Regenerate test/expected/zzz_build.out after merging the linter PR The linter PR's comment-style edits (block comments -> "EXCLUDED CODE") land in sql/object_reference.sql, which test/build's raw-load sanity check (zzz_build) re-parses independently of pg_regress's own SQL loading and reports line numbers for. Regenerated via `make results` after confirming zero raw "not ok" TAP assertions anywhere in test/results/*.out (the earlier copy of this file, committed before the linter-PR merge, was captured while a leftover extension install from prior manual testing was still on disk in the sandbox, which produced extra NOTICEs that don't appear in a real clean run -- this version comes from a fully clean rebuild). Co-Authored-By: Claude Sonnet 5 --- test/expected/zzz_build.out | 58 ------------------------------------- 1 file changed, 58 deletions(-) diff --git a/test/expected/zzz_build.out b/test/expected/zzz_build.out index 467431f..921e340 100644 --- a/test/expected/zzz_build.out +++ b/test/expected/zzz_build.out @@ -7,16 +7,6 @@ psql:test/temp_load.not_sql:187: WARNING: I promise you will be sorry if you tr psql:test/temp_load.not_sql:188: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.object_id%TYPE converted to integer -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.classid%TYPE converted to regclass -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.object_id%TYPE converted to integer -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.classid%TYPE converted to regclass -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid -psql:test/temp_load.not_sql:404: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer @@ -35,72 +25,24 @@ psql:test/temp_load.not_sql:620: WARNING: I promise you will be sorry if you tr psql:test/temp_load.not_sql:627: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! -psql:test/temp_load.not_sql:654: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:654: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:679: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:679: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:694: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:694: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:721: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:721: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:737: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:737: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer -psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:754: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer -psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer -psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:788: NOTICE: type reference _object_reference.object_group__object.object_id%TYPE converted to integer -psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type -psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid -psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer -psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference.object.object_type%TYPE converted to cat_tools.object_type -psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objid%TYPE converted to oid -psql:test/temp_load.not_sql:953: NOTICE: type reference _object_reference._object_oid.objsubid%TYPE converted to integer -psql:test/temp_load.not_sql:1180: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1180: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1194: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1194: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1221: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1235: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1282: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1282: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1296: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1296: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1341: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1341: NOTICE: type reference _object_reference.object_group.object_group_id%TYPE converted to integer -psql:test/temp_load.not_sql:1355: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying -psql:test/temp_load.not_sql:1355: NOTICE: type reference _object_reference.object_group.object_group_name%TYPE converted to character varying From 4fe08c0301a3d2fc0bc522c4f06ad253899ce39e Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Tue, 4 Aug 2026 18:59:47 -0500 Subject: [PATCH 13/13] Classify partitioned table/index as unsupported, not untested Verified directly: pg_get_object_address('partitioned table', ...) throws "unrecognized object type" -- PostgreSQL's real object-address API only knows the base "table"/"index" object types cat_tools's "partitioned table"/ "partitioned index" are derived from. object_reference actively calls pg_get_object_address() on every object_type it tracks (not just in the disabled sanity CHECK), so these two types would break identity tracking outright rather than merely lacking test coverage -- the earlier "untested" classification undersold the actual constraint. Matches the classification (and the exact reasoning/wording) already landed independently on the separate, longer-running new_features branch (PR #2), which reaches unsupported() via the same cat_tools 0.3.0 enum growth. Update test/sql/all.sql's own sanity-check of the unsupported set to match. Co-Authored-By: Claude Sonnet 5 --- sql/object_reference--stable.sql | 10 +++++++--- sql/object_reference.sql | 10 +++++++--- test/expected/zzz_build.out | 4 ++-- test/sql/all.sql | 7 +++++++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/sql/object_reference--stable.sql b/sql/object_reference--stable.sql index 5fcb589..26d1d0f 100644 --- a/sql/object_reference--stable.sql +++ b/sql/object_reference--stable.sql @@ -523,7 +523,12 @@ SELECT __object_reference.create_function( , $body$ SELECT cat_tools.objects__shared() || cat_tools.objects__address_unsupported() - || '{event trigger}' + /* + * pg_get_object_address() doesn't recognize "partitioned table" or + * "partitioned index" (only the base "table"/"index" types it derives + * from), so object identity tracking can't round-trip them. + */ + || '{event trigger, partitioned table, partitioned index}' $body$ , 'Returns array of object types that are not supported.' , 'object_reference__usage' @@ -572,8 +577,7 @@ foreign table, foreign table column, aggregate, collation, conversion, language, large object, operator, operator class, operator family, operator of access method, function of access method, rule, text search parser, text search dictionary, text search template, text search configuration, foreign-data wrapper, server, -user mapping, default acl, transform, access method, extension, policy, -partitioned table, partitioned index +user mapping, default acl, transform, access method, extension, policy }'::cat_tools.object_type[] $body$ , 'Returns array of object types that have not been tested.' diff --git a/sql/object_reference.sql b/sql/object_reference.sql index 7aee0db..c88a79f 100644 --- a/sql/object_reference.sql +++ b/sql/object_reference.sql @@ -522,7 +522,12 @@ SELECT __object_reference.create_function( , $body$ SELECT cat_tools.objects__shared() || cat_tools.objects__address_unsupported() - || '{event trigger}' + /* + * pg_get_object_address() doesn't recognize "partitioned table" or + * "partitioned index" (only the base "table"/"index" types it derives + * from), so object identity tracking can't round-trip them. + */ + || '{event trigger, partitioned table, partitioned index}' $body$ , 'Returns array of object types that are not supported.' , 'object_reference__usage' @@ -571,8 +576,7 @@ foreign table, foreign table column, aggregate, collation, conversion, language, large object, operator, operator class, operator family, operator of access method, function of access method, rule, text search parser, text search dictionary, text search template, text search configuration, foreign-data wrapper, server, -user mapping, default acl, transform, access method, extension, policy, -partitioned table, partitioned index +user mapping, default acl, transform, access method, extension, policy }'::cat_tools.object_type[] $body$ , 'Returns array of object types that have not been tested.' diff --git a/test/expected/zzz_build.out b/test/expected/zzz_build.out index 921e340..d9612d3 100644 --- a/test/expected/zzz_build.out +++ b/test/expected/zzz_build.out @@ -21,9 +21,9 @@ psql:test/temp_load.not_sql:512: WARNING: I promise you will be sorry if you tr -psql:test/temp_load.not_sql:620: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:624: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! -psql:test/temp_load.not_sql:627: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! +psql:test/temp_load.not_sql:631: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! diff --git a/test/sql/all.sql b/test/sql/all.sql index e00f04b..8e96fe2 100644 --- a/test/sql/all.sql +++ b/test/sql/all.sql @@ -53,6 +53,13 @@ SELECT bag_eq( UNION -- Intentionally not UNION ALL; we want to know if object_reference.unsupported has dupes SELECT * FROM cat_tools.objects__address_unsupported_srf() UNION SELECT 'event trigger' + /* + * pg_identify_object_as_address() returns these as plain "table"/"index", + * and pg_get_object_address() doesn't recognize "partitioned table" or + * "partitioned index" at all, so the round-trip is broken. + */ + UNION SELECT 'partitioned table' + UNION SELECT 'partitioned index' $$ , 'Verify object_reference.unsupported()' );