diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c index c6f75c5aa8..a9da621f5a 100644 --- a/src/backend/catalog/pg_depend.c +++ b/src/backend/catalog/pg_depend.c @@ -485,6 +485,49 @@ getExtensionOfObject(Oid classId, Oid objectId) return result; } +/* + * Return (possibly NIL) list of extensions that the given object depends on + * in DEPENDENCY_AUTO_EXTENSION mode. + */ +List * +getAutoExtensionsOfObject(Oid classId, Oid objectId) +{ + List *result = NIL; + Relation depRel; + ScanKeyData key[2]; + SysScanDesc scan; + HeapTuple tup; + + depRel = heap_open(DependRelationId, AccessShareLock); + + ScanKeyInit(&key[0], + Anum_pg_depend_classid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(classId)); + ScanKeyInit(&key[1], + Anum_pg_depend_objid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objectId)); + + scan = systable_beginscan(depRel, DependDependerIndexId, true, + NULL, 2, key); + + while (HeapTupleIsValid((tup = systable_getnext(scan)))) + { + Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup); + + if (depform->refclassid == ExtensionRelationId && + depform->deptype == DEPENDENCY_AUTO_EXTENSION) + result = lappend_oid(result, depform->refobjid); + } + + systable_endscan(scan); + + heap_close(depRel, AccessShareLock); + + return result; +} + /* * Detect whether a sequence is marked as "owned" by a column * diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 302f496b7d..4505ab0130 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -427,6 +427,7 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre ObjectAddress address; ObjectAddress refAddr; Relation rel; + List *currexts; address = get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object, @@ -456,7 +457,11 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre if (refAddress) *refAddress = refAddr; - recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION); + /* Avoid duplicates */ + currexts = getAutoExtensionsOfObject(address.classId, + address.objectId); + if (!list_member_oid(currexts, refAddr.objectId)) + recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION); return address; } diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 184215a367..ff06c9aa77 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -252,6 +252,7 @@ extern long changeDependencyFor(Oid classId, Oid objectId, Oid newRefObjectId); extern Oid getExtensionOfObject(Oid classId, Oid objectId); +extern List *getAutoExtensionsOfObject(Oid classId, Oid objectId); extern bool sequenceIsOwned(Oid seqId, char deptype, Oid *tableId, int32 *colId); extern List *getOwnedSequences(Oid relid, AttrNumber attnum); diff --git a/src/test/modules/test_extensions/expected/test_extdepend.out b/src/test/modules/test_extensions/expected/test_extdepend.out index 11e441ddd3..40533e90de 100644 --- a/src/test/modules/test_extensions/expected/test_extdepend.out +++ b/src/test/modules/test_extensions/expected/test_extdepend.out @@ -47,6 +47,8 @@ SELECT * FROM test_extdep_commands \gexec CREATE INDEX e ON a (a1) ALTER INDEX e DEPENDS ON EXTENSION test_ext5 RESET search_path +-- A dependent object made dependent again has no effect +ALTER FUNCTION test_ext.b() DEPENDS ON EXTENSION test_ext5; -- make sure we have the right dependencies on the extension SELECT deptype, p.* FROM pg_depend, pg_identify_object(classid, objid, objsubid) AS p diff --git a/src/test/modules/test_extensions/sql/test_extdepend.sql b/src/test/modules/test_extensions/sql/test_extdepend.sql index cf44145dcb..cc170ab709 100644 --- a/src/test/modules/test_extensions/sql/test_extdepend.sql +++ b/src/test/modules/test_extensions/sql/test_extdepend.sql @@ -27,6 +27,8 @@ COPY test_extdep_commands FROM stdin; SELECT * FROM test_extdep_commands; -- First, test that dependent objects go away when the extension is dropped. SELECT * FROM test_extdep_commands \gexec +-- A dependent object made dependent again has no effect +ALTER FUNCTION test_ext.b() DEPENDS ON EXTENSION test_ext5; -- make sure we have the right dependencies on the extension SELECT deptype, p.* FROM pg_depend, pg_identify_object(classid, objid, objsubid) AS p