Fix dependency on FDW's connection function.

Missed in commit 8185bb5347.

Catalog version bump.

Discussion: https://postgr.es/m/fd49b44dc65da8e71ab20c1cf1ec7e65921c20f5.camel@j-davis.com
This commit is contained in:
Jeff Davis 2026-03-20 12:42:59 -07:00
parent b3cf461b3c
commit 4a0b46b6e1
6 changed files with 75 additions and 4 deletions

View file

@ -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);

View file

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202603191
#define CATALOG_VERSION_NO 202603201
#endif

View file

@ -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

View file

@ -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';

View file

@ -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;

View file

@ -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