diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 336f866..2185e7c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -211,6 +211,26 @@ jobs: # (pgxntool marks installcheck `.IGNORE`), so failures would pass silently. make verify-results + # Style linter (https://github.com/Postgres-Extensions/linter, vendored at + # .vendor/linter). 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 (see its comment). 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. The + # linter's own test suite (fixtures + scanner edge cases) is that repo's + # own CI's job, not this one's. No PostgreSQL needed -- sql-lint is a + # standalone Perl script -- so this doesn't use the pgxn-tools container. + lint: + needs: [changes] + if: needs.changes.outputs.docs_only != 'true' + name: ๐Ÿงน SQL Lint + runs-on: ubuntu-latest + steps: + - name: Check out the repo + uses: actions/checkout@v6 + - name: Lint SQL + run: make lint + # Proves cat_tools survives a BINARY pg_upgrade (in-place catalog migration to a # newer PostgreSQL major), not just an in-place extension update. Each leg is a # SINGLE jump: install an old cat_tools on an old cluster, plant a dependency @@ -555,7 +575,7 @@ jobs: # the heavy jobs gated off by the `changes` job on a docs-only push), and # fails if any failed or were cancelled. all-checks-passed: - needs: [changes, test, pg-upgrade-test, pg-upgrade-stepwise, extension-update-test] + needs: [changes, test, lint, pg-upgrade-test, pg-upgrade-stepwise, extension-update-test] if: always() runs-on: ubuntu-latest steps: 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..b8632c2 --- /dev/null +++ b/.vendor/linter @@ -0,0 +1 @@ +Subproject commit b8632c2a3d93de664a45f4622235871e8f19cf78 diff --git a/Makefile b/Makefile index bb7e699..5d894e6 100644 --- a/Makefile +++ b/Makefile @@ -92,3 +92,16 @@ $(DESTDIR)$(datadir)/extension/cat_tools--0.2.0.sql: .PHONY: clean_old_version clean_old_version: pgxn uninstall --unstable 'cat_tools=0.2.0' + +# 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 the actively-maintained source rather than the default +# `sql/ test/`: version-specific install/update scripts under sql/ are +# frozen once released (SQL file conventions rule 5 in CLAUDE.md โ€” never +# hand-edited again), so linting them would produce permanent, unfixable +# findings and make `make lint` unusable as a CI gate. Lint the current +# source instead; a version file still under active development can be +# linted directly, e.g. +# `.vendor/linter/sql/bin/sql-lint sql/cat_tools--0.3.0.sql.in`. +LINT_TARGETS = sql/cat_tools.sql.in sql/omit_column.sql test/ +include lint.mk 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.mk b/sql.mk index bd079ef..9ac4483 100644 --- a/sql.mk +++ b/sql.mk @@ -199,23 +199,51 @@ define _apply_version_seds {print}' $@.tmp > $@.tmp2 && mv $@.tmp2 $@.tmp endef -# The recipe builds $@.tmp then moves it into place atomically. +# ---------------------------------------------------------------------------- +# Two .sql.in sources feed the same .sql.in -> .sql transform below (wrap with +# @generated@ markers, then _apply_version_seds), producing two different +# targets: +# +# sql/cat_tools.sql.in (hand-maintained master, committed) +# --pattern rule--> sql/cat_tools.sql +# +# sql/cat_tools.sql.in +# --copy rule, tags @generated@ as "VERSIONED FILE!"--> +# sql/cat_tools--X.Y.Z.sql.in (committed per-version snapshot; frozen +# once released, see CLAUDE.md's SQL file conventions) +# --override rule, same transform as the pattern rule--> +# sql/cat_tools--X.Y.Z.sql = $(EXTENSION_VERSION_FILES) +# (what CREATE EXTENSION actually installs) +# +# The bottom (override) rule can't just be left to the sql/%.sql pattern rule +# matching it: control.mk (auto-generated by pgxntool from cat_tools.control, +# see pgxntool/base.mk) already defines its OWN recipe for +# $(EXTENSION_VERSION_FILES) -- straight from cat_tools.sql, no .sql.in layer, +# no version seds -- and GNU Make always prefers an explicit rule over a +# pattern rule for the same target. Overriding it here is the only way to +# route that target through the same .sql.in / version-sed pipeline as +# everything else; its "overriding recipe" warning is expected. Both final +# steps build $@.tmp then move it into place atomically. +# # TODO: refactor the version handling into a function. +# ---------------------------------------------------------------------------- + +# @generated@ becomes the "-- GENERATED FILE! DO NOT EDIT!" marker below via a +# plain, unanchored substring match -- it also fires on a handful of +# coincidental @generated@ occurrences inside real-code comments in +# cat_tools.sql.in, which is harmless (already inside a -- comment). sql/%.sql: sql/%.sql.in pgxntool/safesed (echo @generated@ && cat $< && echo @generated@) | sed -e 's#@generated@#-- GENERATED FILE! DO NOT EDIT! See $<#' > $@.tmp $(_apply_version_seds) mv $@.tmp $@ -# Make the current version's .sql.in by copying the base source; the pattern -# rule above then turns it into the final .sql with SED substitutions applied. -# (EXTENSION_VERSION_FILES is just sql/cat_tools--.sql) +# Appends " VERSIONED FILE!" after every @generated@ occurrence; the pattern +# rule above resolves the leading @generated@ either way, so the tag rides +# through into the final marker text untouched. $(EXTENSION_VERSION_FILES:.sql=.sql.in): sql/cat_tools.sql.in cat_tools.control - cp $< $@ + sed -e 's/@generated@/@generated@ VERSIONED FILE!/' $< > $@ -# Override control.mk's rule (which builds EXTENSION_VERSION_FILES straight from -# cat_tools.sql, skipping SED) so we build from the .sql.in above instead, with -# version-conditional substitutions applied. GNU Make's "overriding recipe" -# warning for this target is expected. +# See the overview above for why this duplicates the pattern rule's recipe. $(EXTENSION_VERSION_FILES): $(EXTENSION_VERSION_FILES:.sql=.sql.in) pgxntool/safesed (echo @generated@ && cat $< && echo @generated@) | sed -e 's#@generated@#-- GENERATED FILE! DO NOT EDIT! See $<#' > $@.tmp $(_apply_version_seds) diff --git a/sql/cat_tools--0.3.0.sql.in b/sql/cat_tools--0.3.0.sql.in index 9d66d63..1603d89 100644 --- a/sql/cat_tools--0.3.0.sql.in +++ b/sql/cat_tools--0.3.0.sql.in @@ -1,4 +1,4 @@ -@generated@ +@generated@ VERSIONED FILE! DO $$ BEGIN @@ -21,7 +21,7 @@ GRANT USAGE ON SCHEMA cat_tools TO cat_tools__usage; ALTER DEFAULT PRIVILEGES IN SCHEMA cat_tools GRANT USAGE ON TYPES TO cat_tools__usage; CREATE SCHEMA _cat_tools; -@generated@ +@generated@ VERSIONED FILE! CREATE FUNCTION __cat_tools.exec( sql text @@ -50,7 +50,7 @@ SELECT array_to_string(array( ) $body$; -@generated@ +@generated@ VERSIONED FILE! /* * Starting in PG12 oid columns in catalog tables are no longer hidden, so we @@ -117,7 +117,7 @@ COMMENT ON FUNCTION %s( $template$ ; -@generated@ +@generated@ VERSIONED FILE! BEGIN PERFORM __cat_tools.exec( format( @@ -157,7 +157,7 @@ BEGIN END $body$; -@generated@ +@generated@ VERSIONED FILE! /* * These _cat_tools helper functions are created via __cat_tools.create_function @@ -194,7 +194,7 @@ BEGIN */ IF current_user != session_user THEN RAISE EXCEPTION USING - ERRCODE = '28000' /* invalid_authorization_specification */ + ERRCODE = '28000' -- invalid_authorization_specification , MESSAGE = 'potential use of SECURITY DEFINER detected' , DETAIL = format('current_user is %s, session_user is %s', current_user, session_user) , HINT = 'Helper functions must not be called from SECURITY DEFINER context.'; @@ -250,7 +250,7 @@ BEGIN */ IF current_user != session_user THEN RAISE EXCEPTION USING - ERRCODE = '28000' /* invalid_authorization_specification */ + ERRCODE = '28000' -- invalid_authorization_specification , MESSAGE = 'potential use of SECURITY DEFINER detected' , DETAIL = format('API function %s must not be called from a SECURITY DEFINER function', api_function_name) , HINT = 'We detect SECURITY DEFINER context by comparing current_user and session_user, which can cause false positives if SET ROLE is used'; @@ -264,7 +264,7 @@ $body$ GRANT USAGE ON SCHEMA _cat_tools TO cat_tools__usage; -@generated@ +@generated@ VERSIONED FILE! -- Data type definitions CREATE TYPE cat_tools.constraint_type AS ENUM( @@ -520,7 +520,7 @@ $body$ , 'Mapping from cat_tools.routine_proparallel to cat_tools.routine_parallel_safety' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__arg_types' @@ -535,7 +535,7 @@ $body$ , 'Returns all argument types for a function as an array of regtype' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__arg_names' @@ -577,7 +577,7 @@ $body$ , 'Returns all argument names for a function as an array of text. Empty strings are converted to NULL.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__arg_types_text' @@ -590,7 +590,7 @@ $body$ , 'Returns all argument types for a function as a comma-separated text string' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__arg_names_text' @@ -603,7 +603,7 @@ $body$ , 'Returns all argument names for a function as a comma-separated text string' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__parse_arg_types' @@ -628,7 +628,7 @@ $body$ defining a function.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__parse_arg_names' @@ -653,7 +653,7 @@ $body$ behavior). Unnamed arguments appear as NULL in the result array.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__parse_arg_types_text' @@ -669,7 +669,7 @@ $body$ ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.routine__parse_arg_names_text' @@ -685,7 +685,7 @@ $body$ ); -@generated@ +@generated@ VERSIONED FILE! -- Deprecated wrapper functions for backwards compatibility SELECT __cat_tools.create_function( @@ -705,7 +705,7 @@ $body$ includes IN, INOUT, and VARIADIC arguments.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.function__arg_types_text' @@ -724,7 +724,7 @@ $body$ includes IN, INOUT, and VARIADIC arguments.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.regprocedure' @@ -746,10 +746,10 @@ $body$ ); -@generated@ +@generated@ VERSIONED FILE! -@generated@ +@generated@ VERSIONED FILE! CREATE TYPE cat_tools.object_type AS ENUM( -- pg_class @@ -815,7 +815,7 @@ CREATE TYPE cat_tools.object_type AS ENUM( ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.objects__shared' @@ -858,7 +858,7 @@ $body$ , 'Returns true if object_type is a shared object.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.objects__address_unsupported' @@ -884,7 +884,7 @@ $body$ , 'cat_tools__usage' , 'Returns set of object types not supported by pg_get_object_address().' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.object__is_address_unsupported' , 'object_type cat_tools.object_type' @@ -906,7 +906,7 @@ $body$ , 'Returns true if object type is not supported by pg_get_object_address().' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.object__catalog' @@ -937,7 +937,6 @@ SELECT ( THEN 'pg_attribute' ELSE CASE object_type -- Unusual cases - -- s/, \(.\{-}\) -- \(.*\)/ WHEN \1 THEN '\2'/ WHEN 'default value' THEN 'pg_attrdef' WHEN 'large object' THEN 'pg_largeobject' WHEN 'operator class' THEN 'pg_opclass' @@ -965,7 +964,7 @@ $body$ , 'cat_tools__usage' , 'Returns catalog table that is used to store objects' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.object__catalog' , 'object_type text' @@ -975,7 +974,7 @@ SELECT __cat_tools.create_function( , 'Returns catalog table that is used to store objects' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.object__address_classid' @@ -1000,7 +999,7 @@ SELECT __cat_tools.create_function( , 'Returns the classid used by the pg_*_object*() functions for an object_type' ); -@generated@ +@generated@ VERSIONED FILE! CREATE TABLE _cat_tools.catalog_metadata( object_catalog pg_catalog.regclass @@ -1029,7 +1028,7 @@ $body$ , 'cat_tools__usage' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.object__reg_type' @@ -1058,7 +1057,7 @@ SELECT __cat_tools.create_function( , 'Returns the object identifier type (ie: regclass) associated with a system catalog (ie: pg_class).' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.object__reg_type_catalog' @@ -1095,9 +1094,9 @@ $body$ , 'Returns the system catalog that stores a particular object identifier type.' ); -@generated@ +@generated@ VERSIONED FILE! -@generated@ +@generated@ VERSIONED FILE! CREATE OR REPLACE VIEW _cat_tools.pg_depend_identity_v AS -- SED: REQUIRES 9.3! SELECT o.type AS object_type -- SED: REQUIRES 9.3! @@ -1125,7 +1124,7 @@ CREATE OR REPLACE VIEW _cat_tools.pg_depend_identity_v AS -- SED: REQUIRES 9.3! WHERE classid = 0 -- SED: REQUIRES 9.3! ; -- SED: REQUIRES 9.3! -@generated@ +@generated@ VERSIONED FILE! CREATE OR REPLACE VIEW cat_tools.pg_class_v AS SELECT * @@ -1140,7 +1139,7 @@ CREATE OR REPLACE VIEW cat_tools.pg_class_v AS ; GRANT SELECT ON cat_tools.pg_class_v TO cat_tools__usage; -@generated@ +@generated@ VERSIONED FILE! /* * On PG11+, pg_attribute gained attmissingval (pseudo-type anyarray, not usable in views). @@ -1204,7 +1203,7 @@ $fmt$ )); REVOKE ALL ON _cat_tools.column FROM public; -@generated@ +@generated@ VERSIONED FILE! /* * Starting in PG12, oid became a visible column in system catalogs. @@ -1259,7 +1258,7 @@ SELECT __cat_tools.create_function( $$ ); -@generated@ +@generated@ VERSIONED FILE! -- Borrowed from newsysviews: http://pgfoundry.org/projects/newsysviews/ SELECT __cat_tools.create_function( @@ -1280,9 +1279,10 @@ SELECT __cat_tools.create_function( $$ ); -@generated@ +@generated@ VERSIONED FILE! -- Borrowed from newsysviews: http://pgfoundry.org/projects/newsysviews/ +-- sql-lint:disable-block all: copied verbatim from newsysviews, do not reformat CREATE OR REPLACE VIEW cat_tools.pg_all_foreign_keys AS SELECT n1.nspname AS fk_schema_name, @@ -1301,7 +1301,7 @@ AS WHEN 'u' THEN 'NONE' else null END AS match_type, - CASE k1.confdeltype WHEN 'a' THEN 'NO ACTION' -- @generated@ + CASE k1.confdeltype WHEN 'a' THEN 'NO ACTION' -- @generated@ VERSIONED FILE! WHEN 'c' THEN 'CASCADE' WHEN 'd' THEN 'SET DEFAULT' WHEN 'n' THEN 'SET NULL' @@ -1315,7 +1315,7 @@ AS WHEN 'r' THEN 'RESTRICT' ELSE NULL END AS on_update, - k1.condeferrable AS is_deferrable, -- @generated@ + k1.condeferrable AS is_deferrable, -- @generated@ VERSIONED FILE! k1.condeferred AS is_deferred FROM pg_catalog.pg_constraint k1 JOIN pg_catalog.pg_namespace n1 ON (n1.oid = k1.connamespace) @@ -1323,7 +1323,7 @@ AS JOIN pg_catalog.pg_class c2 ON (c2.oid = k1.confrelid) JOIN pg_catalog.pg_namespace n2 ON (n2.oid = c2.relnamespace) JOIN pg_catalog.pg_depend d ON ( - d.classid = 'pg_constraint'::pg_catalog.regclass -- @generated@ + d.classid = 'pg_constraint'::pg_catalog.regclass -- @generated@ VERSIONED FILE! AND d.objid = k1.oid AND d.objsubid = 0 AND d.deptype = 'n' @@ -1332,14 +1332,14 @@ AS ) JOIN pg_catalog.pg_class ci ON (ci.oid = d.refobjid AND ci.relkind = 'i') LEFT JOIN pg_depend d2 ON ( - d2.classid = 'pg_class'::pg_catalog.regclass -- @generated@ + d2.classid = 'pg_class'::pg_catalog.regclass -- @generated@ VERSIONED FILE! AND d2.objid = ci.oid AND d2.objsubid = 0 AND d2.deptype = 'i' AND d2.refclassid = 'pg_constraint'::pg_catalog.regclass AND d2.refobjsubid = 0 ) - LEFT JOIN pg_catalog.pg_constraint k2 ON ( -- @generated@ + LEFT JOIN pg_catalog.pg_constraint k2 ON ( -- @generated@ VERSIONED FILE! k2.oid = d2.refobjid AND k2.contype IN ('p', 'u') ) @@ -1348,9 +1348,10 @@ AS AND k1.contype = 'f' AND _cat_tools._pg_sv_table_accessible(n1.oid, c1.oid) ; +-- sql-lint:enable-block GRANT SELECT ON cat_tools.pg_all_foreign_keys TO cat_tools__usage; -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.pg_attribute__get' @@ -1379,7 +1380,7 @@ $body$ , 'cat_tools__usage' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.pg_extension__get' @@ -1430,7 +1431,7 @@ $body$ , 'cat_tools__usage' ); -@generated@ +@generated@ VERSIONED FILE! -- Text versions SELECT __cat_tools.create_function( @@ -1463,7 +1464,7 @@ $body$ ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.get_serial_sequence' @@ -1494,7 +1495,7 @@ $body$ , 'Return sequence that is associated with a column. Unlike the pg_get_serial_sequence, throw an exception if there is no sequence associated with the column.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.sequence__last' @@ -1519,7 +1520,7 @@ $$ , 'Return the last value assigned to a column with an associated sequence.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.sequence__next' @@ -1544,7 +1545,7 @@ $$ , 'Return the next value to assign to a column with an associated sequence. THIS ADVANCES THE SEQUENCE.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.setval' @@ -1584,7 +1585,7 @@ $$ , 'Changes the value for a sequence associated with a column. next_value is the next value the sequence will assign. See also sequence__last_value.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.enum_range' @@ -1601,7 +1602,7 @@ $body$ , 'cat_tools__usage' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.enum_range_srf' @@ -1623,7 +1624,7 @@ $body$ , 'cat_tools__usage' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.relation__is_temp' @@ -1666,7 +1667,7 @@ $body$ , 'Returns an array of quoted column names for a relation in ordinal position order.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.name__check' @@ -1682,7 +1683,7 @@ $body$ , 'cat_tools__usage' ); -@generated@ +@generated@ VERSIONED FILE! /* * Trigger functions @@ -1712,7 +1713,7 @@ $body$ , 'Return the OID for a trigger. Returns NULL if trigger does not exist.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.trigger__get_oid' @@ -1741,7 +1742,7 @@ $body$ , 'Return the OID for a trigger. Throws an undefined_object error if the trigger does not exist.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.trigger__parse' @@ -1869,7 +1870,7 @@ $body$ , 'Provide details about a trigger.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.trigger__parse' @@ -1903,7 +1904,7 @@ $body$ , 'Provide details about a trigger.' ); -@generated@ +@generated@ VERSIONED FILE! SELECT __cat_tools.create_function( 'cat_tools.trigger__args_as_text' @@ -1922,7 +1923,7 @@ $body$ , 'Convert function_arguments as returned by trigger__parse() to text (for backwards compatibility).' ); -@generated@ +@generated@ VERSIONED FILE! INSERT INTO _cat_tools.catalog_metadata(object_catalog, reg_type, namespace_field) SELECT object__catalog @@ -1957,7 +1958,7 @@ UPDATE _cat_tools.catalog_metadata -- Cluster to get rid of dead rows CLUSTER _cat_tools.catalog_metadata USING catalog_metadata__pk_object_catalog; -@generated@ +@generated@ VERSIONED FILE! /* * Drop "temporary" objects diff --git a/sql/cat_tools.sql.in b/sql/cat_tools.sql.in index 9d66d63..339ff00 100644 --- a/sql/cat_tools.sql.in +++ b/sql/cat_tools.sql.in @@ -194,7 +194,7 @@ BEGIN */ IF current_user != session_user THEN RAISE EXCEPTION USING - ERRCODE = '28000' /* invalid_authorization_specification */ + ERRCODE = '28000' -- invalid_authorization_specification , MESSAGE = 'potential use of SECURITY DEFINER detected' , DETAIL = format('current_user is %s, session_user is %s', current_user, session_user) , HINT = 'Helper functions must not be called from SECURITY DEFINER context.'; @@ -250,7 +250,7 @@ BEGIN */ IF current_user != session_user THEN RAISE EXCEPTION USING - ERRCODE = '28000' /* invalid_authorization_specification */ + ERRCODE = '28000' -- invalid_authorization_specification , MESSAGE = 'potential use of SECURITY DEFINER detected' , DETAIL = format('API function %s must not be called from a SECURITY DEFINER function', api_function_name) , HINT = 'We detect SECURITY DEFINER context by comparing current_user and session_user, which can cause false positives if SET ROLE is used'; @@ -937,7 +937,6 @@ SELECT ( THEN 'pg_attribute' ELSE CASE object_type -- Unusual cases - -- s/, \(.\{-}\) -- \(.*\)/ WHEN \1 THEN '\2'/ WHEN 'default value' THEN 'pg_attrdef' WHEN 'large object' THEN 'pg_largeobject' WHEN 'operator class' THEN 'pg_opclass' @@ -1283,6 +1282,7 @@ $$ @generated@ -- Borrowed from newsysviews: http://pgfoundry.org/projects/newsysviews/ +-- sql-lint:disable-block all: copied verbatim from newsysviews, do not reformat CREATE OR REPLACE VIEW cat_tools.pg_all_foreign_keys AS SELECT n1.nspname AS fk_schema_name, @@ -1348,6 +1348,7 @@ AS AND k1.contype = 'f' AND _cat_tools._pg_sv_table_accessible(n1.oid, c1.oid) ; +-- sql-lint:enable-block GRANT SELECT ON cat_tools.pg_all_foreign_keys TO cat_tools__usage; @generated@ diff --git a/test/sql/pg_depends.sql b/test/sql/pg_depends.sql index ff149f7..d279917 100644 --- a/test/sql/pg_depends.sql +++ b/test/sql/pg_depends.sql @@ -11,15 +11,6 @@ CREATE TEMP VIEW views AS ; GRANT SELECT ON views TO public; -/* -CREATE TEMP VIEW func_calls AS - SELECT * FROM (VALUES - ('pg_attribute__get'::name, $$'pg_class', 'relname'$$::text) - ) v(fname, args) -; -GRANT SELECT ON func_calls TO public; -*/ - /* * The pg_depends tests are problematic, because bag_eq creates temp objects, * which then do not show up in pg_dep or the view. So we need to capture what