1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Avoid duplicates in ALTER ... DEPENDS ON EXTENSION

If the command is attempted for an extension that the object already
depends on, silently do nothing.

In particular, this means that if a database containing multiple such
entries is dumped, the restore will silently do the right thing and
record just the first one.  (At least, in a world where pg_dump does
dump such entries -- which it doesn't currently, but it will.)

Backpatch to 9.6, where this kind of dependency was introduced.

Reviewed-by: Ibrar Ahmed, Tom Lane (offlist)
Discussion: https://postgr.es/m/20200217225333.GA30974@alvherre.pgsql
This commit is contained in:
Alvaro Herrera
2020-03-11 11:04:59 -03:00
parent fab5456356
commit 73b31e784d
5 changed files with 55 additions and 1 deletions

View File

@ -488,6 +488,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
*

View File

@ -403,6 +403,7 @@ ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddre
ObjectAddress address;
ObjectAddress refAddr;
Relation rel;
List *currexts;
address =
get_object_address_rv(stmt->objectType, stmt->relation, stmt->objname,
@ -434,7 +435,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;
}