From: Jeff Davis Date: Fri, 20 Mar 2026 19:42:59 +0000 (-0700) Subject: Fix dependency on FDW's connection function. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a0b46b6e1e4988a317c8ec9a8917e3f6831e427;p=thirdparty%2Fpostgresql.git Fix dependency on FDW's connection function. Missed in commit 8185bb5347. Catalog version bump. Discussion: https://postgr.es/m/fd49b44dc65da8e71ab20c1cf1ec7e65921c20f5.camel@j-davis.com --- diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 0b31afd8a79..c4852be2eb2 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -707,6 +707,14 @@ CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt) recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + if (OidIsValid(fdwconnection)) + { + referenced.classId = ProcedureRelationId; + referenced.objectId = fdwconnection; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } + recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId); /* dependency on extension */ @@ -819,6 +827,28 @@ AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt) { repl_val[Anum_pg_foreign_data_wrapper_fdwconnection - 1] = ObjectIdGetDatum(fdwconnection); repl_repl[Anum_pg_foreign_data_wrapper_fdwconnection - 1] = true; + + /* + * If the connection function is changed, behavior of dependent + * subscriptions can change. If NO CONNECTION, dependent + * subscriptions will fail. + */ + if (OidIsValid(fdwForm->fdwconnection)) + { + if (OidIsValid(fdwconnection)) + ereport(WARNING, + (errmsg("changing the foreign-data wrapper connection function can cause " + "the options for dependent objects to become invalid"))); + else + ereport(WARNING, + (errmsg("removing the foreign-data wrapper connection function will cause " + "dependent subscriptions to fail"))); + } + } + else + { + /* connection function unchanged */ + fdwconnection = fdwForm->fdwconnection; } /* @@ -859,7 +889,7 @@ AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt) ObjectAddressSet(myself, ForeignDataWrapperRelationId, fdwId); /* Update function dependencies if we changed them */ - if (handler_given || validator_given) + if (handler_given || validator_given || connection_given) { ObjectAddress referenced; @@ -889,6 +919,14 @@ AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt) referenced.objectSubId = 0; recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); } + + if (OidIsValid(fdwconnection)) + { + referenced.classId = ProcedureRelationId; + referenced.objectId = fdwconnection; + referenced.objectSubId = 0; + recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL); + } } InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, fdwId, 0); diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index fd8472cb5a5..420850293f8 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202603191 +#define CATALOG_VERSION_NO 202603201 #endif diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out index 35d75180dff..305a9f9e54e 100644 --- a/src/test/regress/expected/foreign_data.out +++ b/src/test/regress/expected/foreign_data.out @@ -9,6 +9,10 @@ CREATE FUNCTION test_fdw_handler() RETURNS fdw_handler AS :'regresslib', 'test_fdw_handler' LANGUAGE C; +CREATE FUNCTION test_fdw_connection(oid, oid, internal) + RETURNS text + AS :'regresslib', 'test_fdw_connection' + LANGUAGE C; -- Clean up in case a prior regression run failed -- Suppress NOTICE messages when roles don't exist SET client_min_messages TO 'warning'; @@ -106,13 +110,18 @@ ERROR: conflicting or redundant options LINE 1: ...GN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER in... ^ CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler; --- should preserve dependency on test_fdw_handler +-- should preserve dependencies on test_fdw_handler and test_fdw_connection +ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; ALTER FOREIGN DATA WRAPPER test_fdw VALIDATOR postgresql_fdw_validator; WARNING: changing the foreign-data wrapper validator can cause the options for dependent objects to become invalid DROP FUNCTION test_fdw_handler(); -- ERROR ERROR: cannot drop function test_fdw_handler() because other objects depend on it DETAIL: foreign-data wrapper test_fdw depends on function test_fdw_handler() HINT: Use DROP ... CASCADE to drop the dependent objects too. +DROP FUNCTION test_fdw_connection(oid, oid, internal); -- ERROR +ERROR: cannot drop function test_fdw_connection(oid,oid,internal) because other objects depend on it +DETAIL: foreign-data wrapper test_fdw depends on function test_fdw_connection(oid,oid,internal) +HINT: Use DROP ... CASCADE to drop the dependent objects too. DROP FOREIGN DATA WRAPPER test_fdw; -- ALTER FOREIGN DATA WRAPPER ALTER FOREIGN DATA WRAPPER foo OPTIONS (nonexistent 'fdw'); -- ERROR diff --git a/src/test/regress/expected/subscription.out b/src/test/regress/expected/subscription.out index f57f359127b..7e3cabdb93f 100644 --- a/src/test/regress/expected/subscription.out +++ b/src/test/regress/expected/subscription.out @@ -185,6 +185,15 @@ DROP SUBSCRIPTION regress_testsub6; SET SESSION AUTHORIZATION regress_subscription_user; REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3; DROP SERVER test_server; +-- fail, FDW is dependent +DROP FUNCTION test_fdw_connection(oid, oid, internal); +ERROR: cannot drop function test_fdw_connection(oid,oid,internal) because other objects depend on it +DETAIL: foreign-data wrapper test_fdw depends on function test_fdw_connection(oid,oid,internal) +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- warn +ALTER FOREIGN DATA WRAPPER test_fdw NO CONNECTION; +WARNING: removing the foreign-data wrapper connection function will cause dependent subscriptions to fail +DROP FUNCTION test_fdw_connection(oid, oid, internal); DROP FOREIGN DATA WRAPPER test_fdw; -- fail - invalid connection string during ALTER ALTER SUBSCRIPTION regress_testsub CONNECTION 'foobar'; diff --git a/src/test/regress/sql/foreign_data.sql b/src/test/regress/sql/foreign_data.sql index 0080bfb8856..ed78052b1e2 100644 --- a/src/test/regress/sql/foreign_data.sql +++ b/src/test/regress/sql/foreign_data.sql @@ -13,6 +13,11 @@ CREATE FUNCTION test_fdw_handler() AS :'regresslib', 'test_fdw_handler' LANGUAGE C; +CREATE FUNCTION test_fdw_connection(oid, oid, internal) + RETURNS text + AS :'regresslib', 'test_fdw_connection' + LANGUAGE C; + -- Clean up in case a prior regression run failed -- Suppress NOTICE messages when roles don't exist @@ -68,9 +73,11 @@ CREATE FOREIGN DATA WRAPPER test_fdw HANDLER invalid_fdw_handler; -- ERROR CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler HANDLER invalid_fdw_handler; -- ERROR CREATE FOREIGN DATA WRAPPER test_fdw HANDLER test_fdw_handler; --- should preserve dependency on test_fdw_handler +-- should preserve dependencies on test_fdw_handler and test_fdw_connection +ALTER FOREIGN DATA WRAPPER test_fdw CONNECTION test_fdw_connection; ALTER FOREIGN DATA WRAPPER test_fdw VALIDATOR postgresql_fdw_validator; DROP FUNCTION test_fdw_handler(); -- ERROR +DROP FUNCTION test_fdw_connection(oid, oid, internal); -- ERROR DROP FOREIGN DATA WRAPPER test_fdw; diff --git a/src/test/regress/sql/subscription.sql b/src/test/regress/sql/subscription.sql index a642b368183..6c3d9632e8a 100644 --- a/src/test/regress/sql/subscription.sql +++ b/src/test/regress/sql/subscription.sql @@ -138,6 +138,14 @@ SET SESSION AUTHORIZATION regress_subscription_user; REVOKE CREATE ON DATABASE REGRESSION FROM regress_subscription_user3; DROP SERVER test_server; + +-- fail, FDW is dependent +DROP FUNCTION test_fdw_connection(oid, oid, internal); +-- warn +ALTER FOREIGN DATA WRAPPER test_fdw NO CONNECTION; + +DROP FUNCTION test_fdw_connection(oid, oid, internal); + DROP FOREIGN DATA WRAPPER test_fdw; -- fail - invalid connection string during ALTER