From 039241dba8a44920580f2c5c752c18a12c5398fb Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Fri, 30 Oct 2026 01:48:53 -0500 Subject: [PATCH 1/2] Refuse to track objects that are members of object_reference itself `object__getsert()` (via `_object_v__for_update()`) now raises feature_not_supported for any object belonging to the object_reference extension. Letting the tracking machinery observe its own members means the extension's own DDL -- including its update scripts restructuring the extension -- becomes something that machinery reacts to. `_object_reference._is_own_object()` checks `pg_depend` membership (`deptype = 'e'`), plus the two objects that are never 'e' members: the extension's declared schema and its own `pg_extension` row. `_etg_capture` also skips objects in the object_reference, _object_reference and __object_reference schemas: an object created by the extension's own install/update script isn't recorded as an 'e' member until the surrounding CREATE/ALTER EXTENSION finishes, so `_is_own_object()` can't see it yet when ddl_command_end fires. The 0.1.0 -> stable update script creates `_is_own_object()` and the updated `_etg_capture` inside its existing session_replication_role section. Part of #40 --- sql/object_reference--0.1.0--stable.sql | 130 +++++++++++++++++++++++- sql/object_reference.sql | 76 +++++++++++++- test/build/expected/build.out | 11 +- test/expected/base.out | 13 ++- test/sql/base.sql | 43 +++++++- 5 files changed, 260 insertions(+), 13 deletions(-) diff --git a/sql/object_reference--0.1.0--stable.sql b/sql/object_reference--0.1.0--stable.sql index b965953..1923bd5 100644 --- a/sql/object_reference--0.1.0--stable.sql +++ b/sql/object_reference--0.1.0--stable.sql @@ -132,6 +132,126 @@ $body$; SELECT set_config('object_reference.saved_session_replication_role', current_setting('session_replication_role'), true); SET LOCAL session_replication_role = replica; +/* + * New: refuse to track objects that are themselves members of the + * object_reference extension (see the guard added to + * _object_v__for_update() below). + */ +SELECT __object_reference.create_function( + '_object_reference._is_own_object' + , $args$ + classid oid + , objid oid +$args$ + , 'boolean LANGUAGE sql STABLE' + , $body$ +SELECT + EXISTS( + SELECT 1 + FROM pg_catalog.pg_depend d + WHERE d.classid = _is_own_object.classid + AND d.objid = _is_own_object.objid + AND d.deptype = 'e' + AND d.refclassid = 'pg_catalog.pg_extension'::regclass + AND d.refobjid = e.oid + ) + /* + * The extension's own declared schema (object_reference) is a special + * case: CREATE EXTENSION records the EXTENSION as depending on it (a + * plain DEPENDENCY_NORMAL row, extension -> schema), not the schema as + * an 'e' member of the extension the way every other object it creates + * is -- so it never matches the pg_depend check above. + */ + OR (_is_own_object.classid = 'pg_catalog.pg_namespace'::regclass AND _is_own_object.objid = e.extnamespace) + /* + * The extension's own pg_extension row is also its own special case: it + * isn't a member of itself (no 'e' row with itself as both member and + * owner), so treat it as one explicitly. + */ + OR (_is_own_object.classid = 'pg_catalog.pg_extension'::regclass AND _is_own_object.objid = e.oid) +FROM (SELECT oid, extnamespace FROM pg_catalog.pg_extension WHERE extname = 'object_reference') e +$body$ + , 'Is the object a member of the object_reference extension itself? (pg_depend deptype = e membership, not just co-installation.)' +); + +/* + * _etg_capture: never capture objects in this extension's own schemas + * (see the comment in its body). Same signature as 0.1.0, so a plain + * CREATE OR REPLACE (via create_function) is enough. + */ +SELECT __object_reference.create_function( + '_object_reference._etg_capture' + , '' + , 'event_trigger SECURITY DEFINER LANGUAGE plpgsql' + , $body$ +DECLARE + c_group_id CONSTANT int := object_group_id FROM object_reference.capture__get_current(); + r record; +BEGIN + + IF c_group_id IS NOT NULL THEN -- Would be NULL if table is empty + RAISE DEBUG E'\n\n*** START ***'; + BEGIN + FOR r IN + SELECT classid, objid, objsubid, command_tag, object_type, schema_name, object_identity, in_extension + -- Have to manually exclude command field :/ + FROM pg_catalog.pg_event_trigger_ddl_commands() + LOOP + RAISE DEBUG 'ddl: %', row_to_json(r); + END LOOP; + END; + + FOR r IN SELECT + _object_reference._object_v__for_update( + object_type::cat_tools.object_type + , objid, objsubid + , c_group_id + , classid + ) + , classid, objid, objsubid, command_tag, object_type, schema_name, object_identity, in_extension + FROM pg_catalog.pg_event_trigger_ddl_commands() + WHERE command_tag ~ '^CREATE' --'^(ALTER|CREATE)' + AND NOT object_reference.unsupported(object_type::cat_tools.object_type) + AND (schema_name IS NULL + OR schema_name NOT LIKE 'pg_temp%' -- pg_my_temp_schema() doesn't seem worth it... + ) + /* + * __object_reference is this extension's own scratch install/update + * schema (created and dropped within a single script, never an + * extension member), so _is_own_object() never recognizes it -- + * exclude it here instead. + * + * object_reference/_object_reference are excluded outright rather + * than relying on _object_v__for_update()'s own _is_own_object() + * guard: a brand-new object created by this extension's own + * update/install script isn't yet recorded as an 'e' member in + * pg_depend at the point its CREATE fires ddl_command_end (that + * happens once the surrounding CREATE/ALTER EXTENSION completes), + * so _is_own_object() can't see it as self-owned yet either -- + * confirmed by running into it: an active capture group during + * ALTER EXTENSION UPDATE otherwise ends up with this extension's + * own new functions as members. + * + * The schema-creation statement itself (CREATE SCHEMA + * __object_reference/etc.) has schema_name = NULL, with the name + * only available via object_identity -- checked separately, and + * restricted to object_type = 'schema', so an unrelated object of + * some other type whose identity happens to match one of these + * three exact strings (e.g. a same-named extension) isn't caught + * by this fallback. + */ + AND coalesce(schema_name, '') NOT IN ('__object_reference', 'object_reference', '_object_reference') + AND NOT (object_type = 'schema' AND object_identity IN ('__object_reference', 'object_reference', '_object_reference')) + LOOP + RAISE DEBUG 'registered %', row_to_json(r); + END LOOP; + RAISE DEBUG E'*** END ***\n\n'; + END IF; +END +$body$ + , 'Event trigger function to capture newly created objects in an object group.' +); + /* * _object_reference.object: no column changes, just a missing * extension_config_dump marking on its sequence (added alongside the table @@ -293,6 +413,14 @@ BEGIN ; END IF; + -- Refuse to track objects that are themselves members of this extension + IF _object_reference._is_own_object(c_classid, objid) THEN + RAISE 'cannot track an object that is a member of the object_reference extension itself' + USING DETAIL = format('object %s belongs to the object_reference extension', r_identity.identity) + , ERRCODE = 'feature_not_supported' + ; + END IF; + -- Ensure the object record exists SELECT INTO r_object_v * @@ -365,7 +493,7 @@ BEGIN RETURN r_object_v; END $body$ - , 'Return details of a object record, creating a new record if one does not exist.' + , 'Return details of a object record, creating a new record if one does not exist. Heavy-weight compared to a plain read of _object_reference._object_v -- use that instead when an existing record is all that''s needed.' ); SELECT __object_reference.create_function( diff --git a/sql/object_reference.sql b/sql/object_reference.sql index cbed4f5..e7e00e9 100644 --- a/sql/object_reference.sql +++ b/sql/object_reference.sql @@ -161,6 +161,43 @@ $body$ , 'Execute arbitrary SQL with logging.' ); +SELECT __object_reference.create_function( + '_object_reference._is_own_object' + , $args$ + classid oid + , objid oid +$args$ + , 'boolean LANGUAGE sql STABLE' + , $body$ +SELECT + EXISTS( + SELECT 1 + FROM pg_catalog.pg_depend d + WHERE d.classid = _is_own_object.classid + AND d.objid = _is_own_object.objid + AND d.deptype = 'e' + AND d.refclassid = 'pg_catalog.pg_extension'::regclass + AND d.refobjid = e.oid + ) + /* + * The extension's own declared schema (object_reference) is a special + * case: CREATE EXTENSION records the EXTENSION as depending on it (a + * plain DEPENDENCY_NORMAL row, extension -> schema), not the schema as + * an 'e' member of the extension the way every other object it creates + * is -- so it never matches the pg_depend check above. + */ + OR (_is_own_object.classid = 'pg_catalog.pg_namespace'::regclass AND _is_own_object.objid = e.extnamespace) + /* + * The extension's own pg_extension row is also its own special case: it + * isn't a member of itself (no 'e' row with itself as both member and + * owner), so treat it as one explicitly. + */ + OR (_is_own_object.classid = 'pg_catalog.pg_extension'::regclass AND _is_own_object.objid = e.oid) +FROM (SELECT oid, extnamespace FROM pg_catalog.pg_extension WHERE extname = 'object_reference') e +$body$ + , 'Is the object a member of the object_reference extension itself? (pg_depend deptype = e membership, not just co-installation.)' +); + CREATE TABLE _object_reference.object( object_id serial PRIMARY KEY , object_type cat_tools.object_type NOT NULL @@ -886,6 +923,14 @@ BEGIN ; END IF; + -- Refuse to track objects that are themselves members of this extension + IF _object_reference._is_own_object(c_classid, objid) THEN + RAISE 'cannot track an object that is a member of the object_reference extension itself' + USING DETAIL = format('object %s belongs to the object_reference extension', r_identity.identity) + , ERRCODE = 'feature_not_supported' + ; + END IF; + -- Ensure the object record exists SELECT INTO r_object_v * @@ -958,7 +1003,7 @@ BEGIN RETURN r_object_v; END $body$ - , 'Return details of a object record, creating a new record if one does not exist.' + , 'Return details of a object record, creating a new record if one does not exist. Heavy-weight compared to a plain read of _object_reference._object_v -- use that instead when an existing record is all that''s needed.' ); SELECT __object_reference.create_function( @@ -1397,7 +1442,7 @@ BEGIN END LOOP; END; - FOR r IN SELECT + FOR r IN SELECT _object_reference._object_v__for_update( object_type::cat_tools.object_type , objid, objsubid @@ -1411,6 +1456,33 @@ BEGIN AND (schema_name IS NULL OR schema_name NOT LIKE 'pg_temp%' -- pg_my_temp_schema() doesn't seem worth it... ) + /* + * __object_reference is this extension's own scratch install/update + * schema (created and dropped within a single script, never an + * extension member), so _is_own_object() never recognizes it -- + * exclude it here instead. + * + * object_reference/_object_reference are excluded outright rather + * than relying on _object_v__for_update()'s own _is_own_object() + * guard: a brand-new object created by this extension's own + * update/install script isn't yet recorded as an 'e' member in + * pg_depend at the point its CREATE fires ddl_command_end (that + * happens once the surrounding CREATE/ALTER EXTENSION completes), + * so _is_own_object() can't see it as self-owned yet either -- + * confirmed by running into it: an active capture group during + * ALTER EXTENSION UPDATE otherwise ends up with this extension's + * own new functions as members. + * + * The schema-creation statement itself (CREATE SCHEMA + * __object_reference/etc.) has schema_name = NULL, with the name + * only available via object_identity -- checked separately, and + * restricted to object_type = 'schema', so an unrelated object of + * some other type whose identity happens to match one of these + * three exact strings (e.g. a same-named extension) isn't caught + * by this fallback. + */ + AND coalesce(schema_name, '') NOT IN ('__object_reference', 'object_reference', '_object_reference') + AND NOT (object_type = 'schema' AND object_identity IN ('__object_reference', 'object_reference', '_object_reference')) LOOP RAISE DEBUG 'registered %', row_to_json(r); END LOOP; diff --git a/test/build/expected/build.out b/test/build/expected/build.out index fadaba6..21ac942 100644 --- a/test/build/expected/build.out +++ b/test/build/expected/build.out @@ -2,17 +2,17 @@ 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:176: 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:177: 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:213: 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:214: 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:425: 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:462: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! @@ -21,9 +21,10 @@ psql:test/temp_load.not_sql:425: WARNING: I promise you will be sorry if you tr -psql:test/temp_load.not_sql:537: 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:544: 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:574: 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:581: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! diff --git a/test/expected/base.out b/test/expected/base.out index d5180ba..b2054ef 100644 --- a/test/expected/base.out +++ b/test/expected/base.out @@ -1,5 +1,5 @@ \set ECHO none -1..12 +1..17 ok 1 - Role object_reference__dependency should be granted USAGE on schema _object_reference ok 2 - Role object_reference__dependency should be granted REFERENCES on table _object_reference.object ok 3 - CREATE TEMP TABLE test_object AS SELECT object_reference.object__getsert('table', 'test_table') AS object_id; @@ -9,7 +9,12 @@ ok 6 - object__identity returns same result as pg_identify_object ok 7 - Existing object works, provides correct ID ok 8 - secondary may not be specified for table objects ok 9 - temp objects are rejected -ok 10 - CREATE EXTENSION test_factory -ok 11 - object_reference schema must not be part of the resolved search_path -ok 12 - _object_reference schema must not be part of the resolved search_path +ok 10 - own tracking table is rejected +ok 11 - own event trigger function is rejected +ok 12 - own declared schema is rejected (extension depends on it, not the other way around) +ok 13 - own private schema is rejected (an ordinary 'e' pg_depend member, unlike the declared schema above) +ok 14 - _is_own_object() recognizes its own pg_extension row +ok 15 - CREATE EXTENSION test_factory +ok 16 - object_reference schema must not be part of the resolved search_path +ok 17 - _object_reference schema must not be part of the resolved search_path # TRANSACTION INTENTIONALLY LEFT OPEN! diff --git a/test/sql/base.sql b/test/sql/base.sql index 538f4f8..2f5bce1 100644 --- a/test/sql/base.sql +++ b/test/sql/base.sql @@ -9,7 +9,7 @@ SELECT plan( +1 -- schema +3 -- initial +2 -- new functions - +3 -- errors (includes temp object test) + +8 -- errors (includes temp object + self-tracking rejection tests) +1 -- create extensions +2 -- schema-qualification (search_path) ); @@ -74,6 +74,47 @@ SELECT throws_ok( , 'temp objects are rejected' ); +-- Test rejection of object_reference's own extension-member objects +SELECT throws_ok( + $$SELECT object_reference.object__getsert('table', '_object_reference.object')$$ + , '0A000' -- feature_not_supported + , 'cannot track an object that is a member of the object_reference extension itself' + , 'own tracking table is rejected' +); +SELECT throws_ok( + $$SELECT object_reference.object__getsert('function', '_object_reference._etg_drop', '')$$ + , '0A000' -- feature_not_supported + , 'cannot track an object that is a member of the object_reference extension itself' + , 'own event trigger function is rejected' +); +SELECT throws_ok( + $$SELECT object_reference.object__getsert('schema', 'object_reference')$$ + , '0A000' -- feature_not_supported + , 'cannot track an object that is a member of the object_reference extension itself' + , 'own declared schema is rejected (extension depends on it, not the other way around)' +); +SELECT throws_ok( + $$SELECT object_reference.object__getsert('schema', '_object_reference')$$ + , '0A000' -- feature_not_supported + , 'cannot track an object that is a member of the object_reference extension itself' + , 'own private schema is rejected (an ordinary ''e'' pg_depend member, unlike the declared schema above)' +); +/* + * Exercised directly against _is_own_object() rather than through + * object__getsert('extension', ...): the latter's generic by-name OID + * lookup for object types with no reg-type cast (extension included) + * derives the wrong catalog column name and fails before ever reaching + * this check -- a pre-existing, unrelated bug (see + * object__getsert_w_group_id's v_name_field derivation, predating this PR). + */ +SELECT ok( + _object_reference._is_own_object( + 'pg_catalog.pg_extension'::regclass + , (SELECT oid FROM pg_catalog.pg_extension WHERE extname = 'object_reference') + ) + , '_is_own_object() recognizes its own pg_extension row' +); + -- Create extensions SELECT lives_ok( $$CREATE EXTENSION test_factory$$ From 8233c1fd331ca9e23374747e869af91675b683de Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Fri, 30 Oct 2026 12:40:28 -0500 Subject: [PATCH 2/2] Remove _etg_capture changes; tighten comments _etg_capture is back to its prior definition: nothing in this PR can reach the exclusion clauses. Reword the _is_own_object comments and drop the "predating this PR" remark in test/sql/base.sql. build.out line numbers follow the removed lines. Co-Authored-By: Claude Sonnet 5.5 --- sql/object_reference--0.1.0--stable.sql | 88 ++----------------------- sql/object_reference.sql | 34 +--------- test/build/expected/build.out | 10 +-- test/sql/base.sql | 3 +- 4 files changed, 13 insertions(+), 122 deletions(-) diff --git a/sql/object_reference--0.1.0--stable.sql b/sql/object_reference--0.1.0--stable.sql index 1923bd5..18915fb 100644 --- a/sql/object_reference--0.1.0--stable.sql +++ b/sql/object_reference--0.1.0--stable.sql @@ -133,9 +133,8 @@ SELECT set_config('object_reference.saved_session_replication_role', current_set SET LOCAL session_replication_role = replica; /* - * New: refuse to track objects that are themselves members of the - * object_reference extension (see the guard added to - * _object_v__for_update() below). + * _is_own_object(): true for members of the object_reference extension itself; + * _object_v__for_update() uses it to refuse tracking them. */ SELECT __object_reference.create_function( '_object_reference._is_own_object' @@ -164,9 +163,8 @@ SELECT */ OR (_is_own_object.classid = 'pg_catalog.pg_namespace'::regclass AND _is_own_object.objid = e.extnamespace) /* - * The extension's own pg_extension row is also its own special case: it - * isn't a member of itself (no 'e' row with itself as both member and - * owner), so treat it as one explicitly. + * The extension's own pg_extension row has no 'e' row of its own, so match it + * by oid. */ OR (_is_own_object.classid = 'pg_catalog.pg_extension'::regclass AND _is_own_object.objid = e.oid) FROM (SELECT oid, extnamespace FROM pg_catalog.pg_extension WHERE extname = 'object_reference') e @@ -174,84 +172,6 @@ $body$ , 'Is the object a member of the object_reference extension itself? (pg_depend deptype = e membership, not just co-installation.)' ); -/* - * _etg_capture: never capture objects in this extension's own schemas - * (see the comment in its body). Same signature as 0.1.0, so a plain - * CREATE OR REPLACE (via create_function) is enough. - */ -SELECT __object_reference.create_function( - '_object_reference._etg_capture' - , '' - , 'event_trigger SECURITY DEFINER LANGUAGE plpgsql' - , $body$ -DECLARE - c_group_id CONSTANT int := object_group_id FROM object_reference.capture__get_current(); - r record; -BEGIN - - IF c_group_id IS NOT NULL THEN -- Would be NULL if table is empty - RAISE DEBUG E'\n\n*** START ***'; - BEGIN - FOR r IN - SELECT classid, objid, objsubid, command_tag, object_type, schema_name, object_identity, in_extension - -- Have to manually exclude command field :/ - FROM pg_catalog.pg_event_trigger_ddl_commands() - LOOP - RAISE DEBUG 'ddl: %', row_to_json(r); - END LOOP; - END; - - FOR r IN SELECT - _object_reference._object_v__for_update( - object_type::cat_tools.object_type - , objid, objsubid - , c_group_id - , classid - ) - , classid, objid, objsubid, command_tag, object_type, schema_name, object_identity, in_extension - FROM pg_catalog.pg_event_trigger_ddl_commands() - WHERE command_tag ~ '^CREATE' --'^(ALTER|CREATE)' - AND NOT object_reference.unsupported(object_type::cat_tools.object_type) - AND (schema_name IS NULL - OR schema_name NOT LIKE 'pg_temp%' -- pg_my_temp_schema() doesn't seem worth it... - ) - /* - * __object_reference is this extension's own scratch install/update - * schema (created and dropped within a single script, never an - * extension member), so _is_own_object() never recognizes it -- - * exclude it here instead. - * - * object_reference/_object_reference are excluded outright rather - * than relying on _object_v__for_update()'s own _is_own_object() - * guard: a brand-new object created by this extension's own - * update/install script isn't yet recorded as an 'e' member in - * pg_depend at the point its CREATE fires ddl_command_end (that - * happens once the surrounding CREATE/ALTER EXTENSION completes), - * so _is_own_object() can't see it as self-owned yet either -- - * confirmed by running into it: an active capture group during - * ALTER EXTENSION UPDATE otherwise ends up with this extension's - * own new functions as members. - * - * The schema-creation statement itself (CREATE SCHEMA - * __object_reference/etc.) has schema_name = NULL, with the name - * only available via object_identity -- checked separately, and - * restricted to object_type = 'schema', so an unrelated object of - * some other type whose identity happens to match one of these - * three exact strings (e.g. a same-named extension) isn't caught - * by this fallback. - */ - AND coalesce(schema_name, '') NOT IN ('__object_reference', 'object_reference', '_object_reference') - AND NOT (object_type = 'schema' AND object_identity IN ('__object_reference', 'object_reference', '_object_reference')) - LOOP - RAISE DEBUG 'registered %', row_to_json(r); - END LOOP; - RAISE DEBUG E'*** END ***\n\n'; - END IF; -END -$body$ - , 'Event trigger function to capture newly created objects in an object group.' -); - /* * _object_reference.object: no column changes, just a missing * extension_config_dump marking on its sequence (added alongside the table diff --git a/sql/object_reference.sql b/sql/object_reference.sql index e7e00e9..48591c5 100644 --- a/sql/object_reference.sql +++ b/sql/object_reference.sql @@ -188,9 +188,8 @@ SELECT */ OR (_is_own_object.classid = 'pg_catalog.pg_namespace'::regclass AND _is_own_object.objid = e.extnamespace) /* - * The extension's own pg_extension row is also its own special case: it - * isn't a member of itself (no 'e' row with itself as both member and - * owner), so treat it as one explicitly. + * The extension's own pg_extension row has no 'e' row of its own, so match it + * by oid. */ OR (_is_own_object.classid = 'pg_catalog.pg_extension'::regclass AND _is_own_object.objid = e.oid) FROM (SELECT oid, extnamespace FROM pg_catalog.pg_extension WHERE extname = 'object_reference') e @@ -1442,7 +1441,7 @@ BEGIN END LOOP; END; - FOR r IN SELECT + FOR r IN SELECT _object_reference._object_v__for_update( object_type::cat_tools.object_type , objid, objsubid @@ -1456,33 +1455,6 @@ BEGIN AND (schema_name IS NULL OR schema_name NOT LIKE 'pg_temp%' -- pg_my_temp_schema() doesn't seem worth it... ) - /* - * __object_reference is this extension's own scratch install/update - * schema (created and dropped within a single script, never an - * extension member), so _is_own_object() never recognizes it -- - * exclude it here instead. - * - * object_reference/_object_reference are excluded outright rather - * than relying on _object_v__for_update()'s own _is_own_object() - * guard: a brand-new object created by this extension's own - * update/install script isn't yet recorded as an 'e' member in - * pg_depend at the point its CREATE fires ddl_command_end (that - * happens once the surrounding CREATE/ALTER EXTENSION completes), - * so _is_own_object() can't see it as self-owned yet either -- - * confirmed by running into it: an active capture group during - * ALTER EXTENSION UPDATE otherwise ends up with this extension's - * own new functions as members. - * - * The schema-creation statement itself (CREATE SCHEMA - * __object_reference/etc.) has schema_name = NULL, with the name - * only available via object_identity -- checked separately, and - * restricted to object_type = 'schema', so an unrelated object of - * some other type whose identity happens to match one of these - * three exact strings (e.g. a same-named extension) isn't caught - * by this fallback. - */ - AND coalesce(schema_name, '') NOT IN ('__object_reference', 'object_reference', '_object_reference') - AND NOT (object_type = 'schema' AND object_identity IN ('__object_reference', 'object_reference', '_object_reference')) LOOP RAISE DEBUG 'registered %', row_to_json(r); END LOOP; diff --git a/test/build/expected/build.out b/test/build/expected/build.out index 21ac942..f86b240 100644 --- a/test/build/expected/build.out +++ b/test/build/expected/build.out @@ -3,16 +3,16 @@ 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:213: 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:212: 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:214: 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:213: 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:462: 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:461: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! @@ -22,9 +22,9 @@ psql:test/temp_load.not_sql:462: WARNING: I promise you will be sorry if you tr -psql:test/temp_load.not_sql:574: 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:573: 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:581: 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:580: WARNING: I promise you will be sorry if you try to use this as anything other than an extension! diff --git a/test/sql/base.sql b/test/sql/base.sql index 2f5bce1..072693d 100644 --- a/test/sql/base.sql +++ b/test/sql/base.sql @@ -104,8 +104,7 @@ SELECT throws_ok( * object__getsert('extension', ...): the latter's generic by-name OID * lookup for object types with no reg-type cast (extension included) * derives the wrong catalog column name and fails before ever reaching - * this check -- a pre-existing, unrelated bug (see - * object__getsert_w_group_id's v_name_field derivation, predating this PR). + * this check (see object__getsert_w_group_id's v_name_field derivation). */ SELECT ok( _object_reference._is_own_object(