/*-------------------------------------------------------------------------
 *
 * pg_shdepend.c
 *	  routines to support manipulation of the pg_shdepend relation
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/catalog/pg_shdepend.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/gp_storage_server.h"
#include "catalog/gp_storage_user_mapping.h"
#include "catalog/indexing.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_auth_members.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
#include "catalog/pg_default_acl.h"
#include "catalog/pg_event_trigger.h"
#include "catalog/pg_extension.h"
#include "catalog/pg_foreign_data_wrapper.h"
#include "catalog/pg_foreign_server.h"
#include "catalog/pg_language.h"
#include "catalog/pg_largeobject.h"
#include "catalog/pg_largeobject_metadata.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_profile.h"
#include "catalog/pg_shdepend.h"
#include "catalog/pg_statistic_ext.h"
#include "catalog/pg_subscription.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_tag.h"
#include "catalog/pg_ts_config.h"
#include "catalog/pg_ts_dict.h"
#include "catalog/pg_type.h"
#include "catalog/pg_user_mapping.h"
#include "commands/alter.h"
#include "commands/collationcmds.h"
#include "commands/conversioncmds.h"
#include "commands/dbcommands.h"
#include "commands/defrem.h"
#include "commands/event_trigger.h"
#include "commands/extension.h"
#include "commands/policy.h"
#include "commands/proclang.h"
#include "commands/publicationcmds.h"
#include "commands/schemacmds.h"
#include "commands/subscriptioncmds.h"
#include "commands/tablecmds.h"
#include "commands/tablespace.h"
#include "commands/typecmds.h"
#include "miscadmin.h"
#include "storage/lmgr.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/memutils.h"
#include "utils/syscache.h"

typedef enum
{
	LOCAL_OBJECT,
	SHARED_OBJECT,
	REMOTE_OBJECT
} SharedDependencyObjectType;

typedef struct
{
	ObjectAddress object;
	char		deptype;
	SharedDependencyObjectType objtype;
} ShDependObjectInfo;

static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2);
static Oid	classIdGetDbId(Oid classId);
static void shdepChangeDep(Relation sdepRel,
						   Oid classid, Oid objid, int32 objsubid,
						   Oid refclassid, Oid refobjid,
						   SharedDependencyType deptype);
static void shdepAddDependency(Relation sdepRel,
							   Oid classId, Oid objectId, int32 objsubId,
							   Oid refclassId, Oid refobjId,
							   SharedDependencyType deptype);
static void shdepDropDependency(Relation sdepRel,
								Oid classId, Oid objectId, int32 objsubId,
								bool drop_subobjects,
								Oid refclassId, Oid refobjId,
								SharedDependencyType deptype);
static void storeObjectDescription(StringInfo descs,
								   SharedDependencyObjectType type,
								   ObjectAddress *object,
								   SharedDependencyType deptype,
								   int count);


/*
 * recordSharedDependencyOn
 *
 * Record a dependency between 2 objects via their respective ObjectAddresses.
 * The first argument is the dependent object, the second the one it
 * references (which must be a shared object).
 *
 * This locks the referenced object and makes sure it still exists.
 * Then it creates an entry in pg_shdepend.  The lock is kept until
 * the end of the transaction.
 *
 * Dependencies on pinned objects are not recorded.
 */
void
recordSharedDependencyOn(ObjectAddress *depender,
						 ObjectAddress *referenced,
						 SharedDependencyType deptype)
{
	Relation	sdepRel;

	/*
	 * Objects in pg_shdepend can't have SubIds.
	 */
	Assert(depender->objectSubId == 0);
	Assert(referenced->objectSubId == 0);

	/*
	 * During bootstrap, do nothing since pg_shdepend may not exist yet.
	 * initdb will fill in appropriate pg_shdepend entries after bootstrap.
	 */
	if (IsBootstrapProcessingMode())
		return;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	/* If the referenced object is pinned, do nothing. */
	if (!IsPinnedObject(referenced->classId, referenced->objectId))
	{
		shdepAddDependency(sdepRel, depender->classId, depender->objectId,
						   depender->objectSubId,
						   referenced->classId, referenced->objectId,
						   deptype);
	}

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * recordDependencyOnOwner
 *
 * A convenient wrapper of recordSharedDependencyOn -- register the specified
 * user as owner of the given object.
 *
 * Note: it's the caller's responsibility to ensure that there isn't an owner
 * entry for the object already.
 */
void
recordDependencyOnOwner(Oid classId, Oid objectId, Oid owner)
{
	ObjectAddress myself,
				referenced;

	myself.classId = classId;
	myself.objectId = objectId;
	myself.objectSubId = 0;

	referenced.classId = AuthIdRelationId;
	referenced.objectId = owner;
	referenced.objectSubId = 0;

	recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_OWNER);
}

/*
 * shdepChangeDep
 *
 * Update shared dependency records to account for an updated referenced
 * object.  This is an internal workhorse for operations such as changing
 * an object's owner.
 *
 * There must be no more than one existing entry for the given dependent
 * object and dependency type!	So in practice this can only be used for
 * updating SHARED_DEPENDENCY_OWNER and SHARED_DEPENDENCY_TABLESPACE
 * entries, which should have that property.
 *
 * If there is no previous entry, we assume it was referencing a PINned
 * object, so we create a new entry.  If the new referenced object is
 * PINned, we don't create an entry (and drop the old one, if any).
 * (For tablespaces, we don't record dependencies in certain cases, so
 * there are other possible reasons for entries to be missing.)
 *
 * sdepRel must be the pg_shdepend relation, already opened and suitably
 * locked.
 */
static void
shdepChangeDep(Relation sdepRel,
			   Oid classid, Oid objid, int32 objsubid,
			   Oid refclassid, Oid refobjid,
			   SharedDependencyType deptype)
{
	Oid			dbid = classIdGetDbId(classid);
	HeapTuple	oldtup = NULL;
	HeapTuple	scantup;
	ScanKeyData key[4];
	SysScanDesc scan;

	/*
	 * Make sure the new referenced object doesn't go away while we record the
	 * dependency.
	 */
	shdepLockAndCheckObject(refclassid, refobjid);

	/*
	 * Look for a previous entry
	 */
	ScanKeyInit(&key[0],
				Anum_pg_shdepend_dbid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(dbid));
	ScanKeyInit(&key[1],
				Anum_pg_shdepend_classid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(classid));
	ScanKeyInit(&key[2],
				Anum_pg_shdepend_objid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(objid));
	ScanKeyInit(&key[3],
				Anum_pg_shdepend_objsubid,
				BTEqualStrategyNumber, F_INT4EQ,
				Int32GetDatum(objsubid));

	scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
							  NULL, 4, key);

	while ((scantup = systable_getnext(scan)) != NULL)
	{
		/* Ignore if not of the target dependency type */
		if (((Form_pg_shdepend) GETSTRUCT(scantup))->deptype != deptype)
			continue;
		/* Caller screwed up if multiple matches */
		if (oldtup)
			elog(ERROR,
				 "multiple pg_shdepend entries for object %u/%u/%d deptype %c",
				 classid, objid, objsubid, deptype);
		oldtup = heap_copytuple(scantup);
	}

	systable_endscan(scan);

	if (IsPinnedObject(refclassid, refobjid))
	{
		/* No new entry needed, so just delete existing entry if any */
		if (oldtup)
			CatalogTupleDelete(sdepRel, &oldtup->t_self);
	}
	else if (oldtup)
	{
		/* Need to update existing entry */
		Form_pg_shdepend shForm = (Form_pg_shdepend) GETSTRUCT(oldtup);

		/* Since oldtup is a copy, we can just modify it in-memory */
		shForm->refclassid = refclassid;
		shForm->refobjid = refobjid;

		CatalogTupleUpdate(sdepRel, &oldtup->t_self, oldtup);
	}
	else
	{
		/* Need to insert new entry */
		Datum		values[Natts_pg_shdepend];
		bool		nulls[Natts_pg_shdepend];

		memset(nulls, false, sizeof(nulls));

		values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(dbid);
		values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classid);
		values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objid);
		values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubid);

		values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassid);
		values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjid);
		values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);

		/*
		 * we are reusing oldtup just to avoid declaring a new variable, but
		 * it's certainly a new tuple
		 */
		oldtup = heap_form_tuple(RelationGetDescr(sdepRel), values, nulls);
		CatalogTupleInsert(sdepRel, oldtup);
	}

	if (oldtup)
		heap_freetuple(oldtup);
}

/*
 * changeDependencyOnOwner
 *
 * Update the shared dependencies to account for the new owner.
 *
 * Note: we don't need an objsubid argument because only whole objects
 * have owners.
 */
void
changeDependencyOnOwner(Oid classId, Oid objectId, Oid newOwnerId)
{
	Relation	sdepRel;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	/* Adjust the SHARED_DEPENDENCY_OWNER entry */
	shdepChangeDep(sdepRel,
				   classId, objectId, 0,
				   AuthIdRelationId, newOwnerId,
				   SHARED_DEPENDENCY_OWNER);

	/*----------
	 * There should never be a SHARED_DEPENDENCY_ACL entry for the owner,
	 * so get rid of it if there is one.  This can happen if the new owner
	 * was previously granted some rights to the object.
	 *
	 * This step is analogous to aclnewowner's removal of duplicate entries
	 * in the ACL.  We have to do it to handle this scenario:
	 *		A grants some rights on an object to B
	 *		ALTER OWNER changes the object's owner to B
	 *		ALTER OWNER changes the object's owner to C
	 * The third step would remove all mention of B from the object's ACL,
	 * but we'd still have a SHARED_DEPENDENCY_ACL for B if we did not do
	 * things this way.
	 *
	 * The rule against having a SHARED_DEPENDENCY_ACL entry for the owner
	 * allows us to fix things up in just this one place, without having
	 * to make the various ALTER OWNER routines each know about it.
	 *----------
	 */
	shdepDropDependency(sdepRel, classId, objectId, 0, true,
						AuthIdRelationId, newOwnerId,
						SHARED_DEPENDENCY_ACL);

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * recordDependencyOnTablespace
 *
 * A convenient wrapper of recordSharedDependencyOn -- register the specified
 * tablespace as default for the given object.
 *
 * Note: it's the caller's responsibility to ensure that there isn't a
 * tablespace entry for the object already.
 */
void
recordDependencyOnTablespace(Oid classId, Oid objectId, Oid tablespace)
{
	ObjectAddress myself,
				referenced;

	ObjectAddressSet(myself, classId, objectId);
	ObjectAddressSet(referenced, TableSpaceRelationId, tablespace);

	recordSharedDependencyOn(&myself, &referenced,
							 SHARED_DEPENDENCY_TABLESPACE);
}

/*
 * changeDependencyOnTablespace
 *
 * Update the shared dependencies to account for the new tablespace.
 *
 * Note: we don't need an objsubid argument because only whole objects
 * have tablespaces.
 */
void
changeDependencyOnTablespace(Oid classId, Oid objectId, Oid newTablespaceId)
{
	Relation	sdepRel;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	if (newTablespaceId != DEFAULTTABLESPACE_OID &&
		newTablespaceId != InvalidOid)
		shdepChangeDep(sdepRel,
					   classId, objectId, 0,
					   TableSpaceRelationId, newTablespaceId,
					   SHARED_DEPENDENCY_TABLESPACE);
	else
		shdepDropDependency(sdepRel,
							classId, objectId, 0, true,
							InvalidOid, InvalidOid,
							SHARED_DEPENDENCY_INVALID);

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * getOidListDiff
 *		Helper for updateAclDependencies.
 *
 * Takes two Oid arrays and removes elements that are common to both arrays,
 * leaving just those that are in one input but not the other.
 * We assume both arrays have been sorted and de-duped.
 */
static void
getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2)
{
	int			in1,
				in2,
				out1,
				out2;

	in1 = in2 = out1 = out2 = 0;
	while (in1 < *nlist1 && in2 < *nlist2)
	{
		if (list1[in1] == list2[in2])
		{
			/* skip over duplicates */
			in1++;
			in2++;
		}
		else if (list1[in1] < list2[in2])
		{
			/* list1[in1] is not in list2 */
			list1[out1++] = list1[in1++];
		}
		else
		{
			/* list2[in2] is not in list1 */
			list2[out2++] = list2[in2++];
		}
	}

	/* any remaining list1 entries are not in list2 */
	while (in1 < *nlist1)
	{
		list1[out1++] = list1[in1++];
	}

	/* any remaining list2 entries are not in list1 */
	while (in2 < *nlist2)
	{
		list2[out2++] = list2[in2++];
	}

	*nlist1 = out1;
	*nlist2 = out2;
}

/*
 * updateAclDependencies
 *		Update the pg_shdepend info for an object's ACL during GRANT/REVOKE.
 *
 * classId, objectId, objsubId: identify the object whose ACL this is
 * ownerId: role owning the object
 * noldmembers, oldmembers: array of roleids appearing in old ACL
 * nnewmembers, newmembers: array of roleids appearing in new ACL
 *
 * We calculate the differences between the new and old lists of roles,
 * and then insert or delete from pg_shdepend as appropriate.
 *
 * Note that we can't just insert all referenced roles blindly during GRANT,
 * because we would end up with duplicate registered dependencies.  We could
 * check for existence of the tuples before inserting, but that seems to be
 * more expensive than what we are doing here.  Likewise we can't just delete
 * blindly during REVOKE, because the user may still have other privileges.
 * It is also possible that REVOKE actually adds dependencies, due to
 * instantiation of a formerly implicit default ACL (although at present,
 * all such dependencies should be for the owning role, which we ignore here).
 *
 * NOTE: Both input arrays must be sorted and de-duped.  (Typically they
 * are extracted from an ACL array by aclmembers(), which takes care of
 * both requirements.)	The arrays are pfreed before return.
 */
void
updateAclDependencies(Oid classId, Oid objectId, int32 objsubId,
					  Oid ownerId,
					  int noldmembers, Oid *oldmembers,
					  int nnewmembers, Oid *newmembers)
{
	Relation	sdepRel;
	int			i;

	/*
	 * Remove entries that are common to both lists; those represent existing
	 * dependencies we don't need to change.
	 *
	 * OK to overwrite the inputs since we'll pfree them anyway.
	 */
	getOidListDiff(oldmembers, &noldmembers, newmembers, &nnewmembers);

	if (noldmembers > 0 || nnewmembers > 0)
	{
		sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

		/* Add new dependencies that weren't already present */
		for (i = 0; i < nnewmembers; i++)
		{
			Oid			roleid = newmembers[i];

			/*
			 * Skip the owner: he has an OWNER shdep entry instead. (This is
			 * not just a space optimization; it makes ALTER OWNER easier. See
			 * notes in changeDependencyOnOwner.)
			 */
			if (roleid == ownerId)
				continue;

			/* Skip pinned roles; they don't need dependency entries */
			if (IsPinnedObject(AuthIdRelationId, roleid))
				continue;

			shdepAddDependency(sdepRel, classId, objectId, objsubId,
							   AuthIdRelationId, roleid,
							   SHARED_DEPENDENCY_ACL);
		}

		/* Drop no-longer-used old dependencies */
		for (i = 0; i < noldmembers; i++)
		{
			Oid			roleid = oldmembers[i];

			/* Skip the owner, same as above */
			if (roleid == ownerId)
				continue;

			/* Skip pinned roles */
			if (IsPinnedObject(AuthIdRelationId, roleid))
				continue;

			shdepDropDependency(sdepRel, classId, objectId, objsubId,
								false,	/* exact match on objsubId */
								AuthIdRelationId, roleid,
								SHARED_DEPENDENCY_ACL);
		}

		table_close(sdepRel, RowExclusiveLock);
	}

	if (oldmembers)
		pfree(oldmembers);
	if (newmembers)
		pfree(newmembers);
}

/*
 * A struct to keep track of dependencies found in other databases.
 */
typedef struct
{
	Oid			dbOid;
	int			count;
} remoteDep;

/*
 * qsort comparator for ShDependObjectInfo items
 */
static int
shared_dependency_comparator(const void *a, const void *b)
{
	const ShDependObjectInfo *obja = (const ShDependObjectInfo *) a;
	const ShDependObjectInfo *objb = (const ShDependObjectInfo *) b;

	/*
	 * Primary sort key is OID ascending.
	 */
	if (obja->object.objectId < objb->object.objectId)
		return -1;
	if (obja->object.objectId > objb->object.objectId)
		return 1;

	/*
	 * Next sort on catalog ID, in case identical OIDs appear in different
	 * catalogs.  Sort direction is pretty arbitrary here.
	 */
	if (obja->object.classId < objb->object.classId)
		return -1;
	if (obja->object.classId > objb->object.classId)
		return 1;

	/*
	 * Sort on object subId.
	 *
	 * We sort the subId as an unsigned int so that 0 (the whole object) will
	 * come first.
	 */
	if ((unsigned int) obja->object.objectSubId < (unsigned int) objb->object.objectSubId)
		return -1;
	if ((unsigned int) obja->object.objectSubId > (unsigned int) objb->object.objectSubId)
		return 1;

	/*
	 * Last, sort on deptype, in case the same object has multiple dependency
	 * types.  (Note that there's no need to consider objtype, as that's
	 * determined by the catalog OID.)
	 */
	if (obja->deptype < objb->deptype)
		return -1;
	if (obja->deptype > objb->deptype)
		return 1;

	return 0;
}

/*
 * checkSharedDependencies
 *
 * Check whether there are shared dependency entries for a given shared
 * object; return true if so.
 *
 * In addition, return a string containing a newline-separated list of object
 * descriptions that depend on the shared object, or NULL if none is found.
 * We actually return two such strings; the "detail" result is suitable for
 * returning to the client as an errdetail() string, and is limited in size.
 * The "detail_log" string is potentially much longer, and should be emitted
 * to the server log only.
 *
 * We can find three different kinds of dependencies: dependencies on objects
 * of the current database; dependencies on shared objects; and dependencies
 * on objects local to other databases.  We can (and do) provide descriptions
 * of the two former kinds of objects, but we can't do that for "remote"
 * objects, so we just provide a count of them.
 */
bool
checkSharedDependencies(Oid classId, Oid objectId,
						char **detail_msg, char **detail_log_msg)
{
	Relation	sdepRel;
	ScanKeyData key[2];
	SysScanDesc scan;
	HeapTuple	tup;
	int			numReportedDeps = 0;
	int			numNotReportedDeps = 0;
	int			numNotReportedDbs = 0;
	List	   *remDeps = NIL;
	ListCell   *cell;
	ObjectAddress object;
	ShDependObjectInfo *objects;
	int			numobjects;
	int			allocedobjects;
	StringInfoData descs;
	StringInfoData alldescs;

	/* This case can be dispatched quickly */
	if (IsPinnedObject(classId, objectId))
	{
		object.classId = classId;
		object.objectId = objectId;
		object.objectSubId = 0;
		ereport(ERROR,
				(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
				 errmsg("cannot drop %s because it is required by the database system",
						getObjectDescription(&object, false))));
	}

	/*
	 * We limit the number of dependencies reported to the client to
	 * MAX_REPORTED_DEPS, since client software may not deal well with
	 * enormous error strings.  The server log always gets a full report.
	 *
	 * For stability of regression test results, we sort local and shared
	 * objects by OID before reporting them.  We don't worry about the order
	 * in which other databases are reported, though.
	 */
#define MAX_REPORTED_DEPS 100

	allocedobjects = 128;		/* arbitrary initial array size */
	objects = (ShDependObjectInfo *)
		palloc(allocedobjects * sizeof(ShDependObjectInfo));
	numobjects = 0;
	initStringInfo(&descs);
	initStringInfo(&alldescs);

	sdepRel = table_open(SharedDependRelationId, AccessShareLock);

	ScanKeyInit(&key[0],
				Anum_pg_shdepend_refclassid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(classId));
	ScanKeyInit(&key[1],
				Anum_pg_shdepend_refobjid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(objectId));

	scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
							  NULL, 2, key);

	while (HeapTupleIsValid(tup = systable_getnext(scan)))
	{
		Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tup);

		object.classId = sdepForm->classid;
		object.objectId = sdepForm->objid;
		object.objectSubId = sdepForm->objsubid;

		/*
		 * If it's a dependency local to this database or it's a shared
		 * object, add it to the objects array.
		 *
		 * If it's a remote dependency, keep track of it so we can report the
		 * number of them later.
		 */
		if (sdepForm->dbid == MyDatabaseId ||
			sdepForm->dbid == InvalidOid)
		{
			if (numobjects >= allocedobjects)
			{
				allocedobjects *= 2;
				objects = (ShDependObjectInfo *)
					repalloc(objects,
							 allocedobjects * sizeof(ShDependObjectInfo));
			}
			objects[numobjects].object = object;
			objects[numobjects].deptype = sdepForm->deptype;
			objects[numobjects].objtype = (sdepForm->dbid == MyDatabaseId) ?
				LOCAL_OBJECT : SHARED_OBJECT;
			numobjects++;
		}
		else
		{
			/* It's not local nor shared, so it must be remote. */
			remoteDep  *dep;
			bool		stored = false;

			/*
			 * XXX this info is kept on a simple List.  Maybe it's not good
			 * for performance, but using a hash table seems needlessly
			 * complex.  The expected number of databases is not high anyway,
			 * I suppose.
			 */
			foreach(cell, remDeps)
			{
				dep = lfirst(cell);
				if (dep->dbOid == sdepForm->dbid)
				{
					dep->count++;
					stored = true;
					break;
				}
			}
			if (!stored)
			{
				dep = (remoteDep *) palloc(sizeof(remoteDep));
				dep->dbOid = sdepForm->dbid;
				dep->count = 1;
				remDeps = lappend(remDeps, dep);
			}
		}
	}

	systable_endscan(scan);

	table_close(sdepRel, AccessShareLock);

	/*
	 * Sort and report local and shared objects.
	 */
	if (numobjects > 1)
		qsort(objects, numobjects,
			  sizeof(ShDependObjectInfo), shared_dependency_comparator);

	for (int i = 0; i < numobjects; i++)
	{
		if (numReportedDeps < MAX_REPORTED_DEPS)
		{
			numReportedDeps++;
			storeObjectDescription(&descs,
								   objects[i].objtype,
								   &objects[i].object,
								   objects[i].deptype,
								   0);
		}
		else
			numNotReportedDeps++;
		storeObjectDescription(&alldescs,
							   objects[i].objtype,
							   &objects[i].object,
							   objects[i].deptype,
							   0);
	}

	/*
	 * Summarize dependencies in remote databases.
	 */
	foreach(cell, remDeps)
	{
		remoteDep  *dep = lfirst(cell);

		object.classId = DatabaseRelationId;
		object.objectId = dep->dbOid;
		object.objectSubId = 0;

		if (numReportedDeps < MAX_REPORTED_DEPS)
		{
			numReportedDeps++;
			storeObjectDescription(&descs, REMOTE_OBJECT, &object,
								   SHARED_DEPENDENCY_INVALID, dep->count);
		}
		else
			numNotReportedDbs++;
		storeObjectDescription(&alldescs, REMOTE_OBJECT, &object,
							   SHARED_DEPENDENCY_INVALID, dep->count);
	}

	pfree(objects);
	list_free_deep(remDeps);

	if (descs.len == 0)
	{
		pfree(descs.data);
		pfree(alldescs.data);
		*detail_msg = *detail_log_msg = NULL;
		return false;
	}

	if (numNotReportedDeps > 0)
		appendStringInfo(&descs, ngettext("\nand %d other object "
										  "(see server log for list)",
										  "\nand %d other objects "
										  "(see server log for list)",
										  numNotReportedDeps),
						 numNotReportedDeps);
	if (numNotReportedDbs > 0)
		appendStringInfo(&descs, ngettext("\nand objects in %d other database "
										  "(see server log for list)",
										  "\nand objects in %d other databases "
										  "(see server log for list)",
										  numNotReportedDbs),
						 numNotReportedDbs);

	*detail_msg = descs.data;
	*detail_log_msg = alldescs.data;
	return true;
}


/*
 * copyTemplateDependencies
 *
 * Routine to create the initial shared dependencies of a new database.
 * We simply copy the dependencies from the template database.
 */
void
copyTemplateDependencies(Oid templateDbId, Oid newDbId)
{
	Relation	sdepRel;
	TupleDesc	sdepDesc;
	ScanKeyData key[1];
	SysScanDesc scan;
	HeapTuple	tup;
	CatalogIndexState indstate;
	TupleTableSlot **slot;
	int			max_slots,
				slot_init_count,
				slot_stored_count;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
	sdepDesc = RelationGetDescr(sdepRel);

	/*
	 * Allocate the slots to use, but delay costly initialization until we
	 * know that they will be used.
	 */
	max_slots = MAX_CATALOG_MULTI_INSERT_BYTES / sizeof(FormData_pg_shdepend);
	slot = palloc(sizeof(TupleTableSlot *) * max_slots);

	indstate = CatalogOpenIndexes(sdepRel);

	/* Scan all entries with dbid = templateDbId */
	ScanKeyInit(&key[0],
				Anum_pg_shdepend_dbid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(templateDbId));

	scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
							  NULL, 1, key);

	/* number of slots currently storing tuples */
	slot_stored_count = 0;
	/* number of slots currently initialized */
	slot_init_count = 0;

	/*
	 * Copy the entries of the original database, changing the database Id to
	 * that of the new database.  Note that because we are not copying rows
	 * with dbId == 0 (ie, rows describing dependent shared objects) we won't
	 * copy the ownership dependency of the template database itself; this is
	 * what we want.
	 */
	while (HeapTupleIsValid(tup = systable_getnext(scan)))
	{
		Form_pg_shdepend shdep;

		if (slot_init_count < max_slots)
		{
			slot[slot_stored_count] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple);
			slot_init_count++;
		}

		ExecClearTuple(slot[slot_stored_count]);

		memset(slot[slot_stored_count]->tts_isnull, false,
			   slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));

		shdep = (Form_pg_shdepend) GETSTRUCT(tup);

		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_classid - 1] = shdep->classid;
		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objid - 1] = shdep->objid;
		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objsubid - 1] = shdep->objsubid;
		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refclassid - 1] = shdep->refclassid;
		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refobjid - 1] = shdep->refobjid;
		slot[slot_stored_count]->tts_values[Anum_pg_shdepend_deptype - 1] = shdep->deptype;

		ExecStoreVirtualTuple(slot[slot_stored_count]);
		slot_stored_count++;

		/* If slots are full, insert a batch of tuples */
		if (slot_stored_count == max_slots)
		{
			CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
			slot_stored_count = 0;
		}
	}

	/* Insert any tuples left in the buffer */
	if (slot_stored_count > 0)
		CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);

	systable_endscan(scan);

	CatalogCloseIndexes(indstate);
	table_close(sdepRel, RowExclusiveLock);

	/* Drop only the number of slots used */
	for (int i = 0; i < slot_init_count; i++)
		ExecDropSingleTupleTableSlot(slot[i]);
	pfree(slot);
}

/*
 * dropDatabaseDependencies
 *
 * Delete pg_shdepend entries corresponding to a database that's being
 * dropped.
 */
void
dropDatabaseDependencies(Oid databaseId)
{
	Relation	sdepRel;
	ScanKeyData key[1];
	SysScanDesc scan;
	HeapTuple	tup;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	/*
	 * First, delete all the entries that have the database Oid in the dbid
	 * field.
	 */
	ScanKeyInit(&key[0],
				Anum_pg_shdepend_dbid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(databaseId));
	/* We leave the other index fields unspecified */

	scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
							  NULL, 1, key);

	while (HeapTupleIsValid(tup = systable_getnext(scan)))
	{
		CatalogTupleDelete(sdepRel, &tup->t_self);
	}

	systable_endscan(scan);

	/* Now delete all entries corresponding to the database itself */
	shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
						InvalidOid, InvalidOid,
						SHARED_DEPENDENCY_INVALID);

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * deleteSharedDependencyRecordsFor
 *
 * Delete all pg_shdepend entries corresponding to an object that's being
 * dropped or modified.  The object is assumed to be either a shared object
 * or local to the current database (the classId tells us which).
 *
 * If objectSubId is zero, we are deleting a whole object, so get rid of
 * pg_shdepend entries for subobjects as well.
 */
void
deleteSharedDependencyRecordsFor(Oid classId, Oid objectId, int32 objectSubId)
{
	Relation	sdepRel;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	shdepDropDependency(sdepRel, classId, objectId, objectSubId,
						(objectSubId == 0),
						InvalidOid, InvalidOid,
						SHARED_DEPENDENCY_INVALID);

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * shdepAddDependency
 *		Internal workhorse for inserting into pg_shdepend
 *
 * sdepRel must be the pg_shdepend relation, already opened and suitably
 * locked.
 */
static void
shdepAddDependency(Relation sdepRel,
				   Oid classId, Oid objectId, int32 objsubId,
				   Oid refclassId, Oid refobjId,
				   SharedDependencyType deptype)
{
	HeapTuple	tup;
	Datum		values[Natts_pg_shdepend];
	bool		nulls[Natts_pg_shdepend];

	/*
	 * Make sure the object doesn't go away while we record the dependency on
	 * it.  DROP routines should lock the object exclusively before they check
	 * shared dependencies.
	 */
	shdepLockAndCheckObject(refclassId, refobjId);

	memset(nulls, false, sizeof(nulls));

	/*
	 * Form the new tuple and record the dependency.
	 */
	values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(classIdGetDbId(classId));
	values[Anum_pg_shdepend_classid - 1] = ObjectIdGetDatum(classId);
	values[Anum_pg_shdepend_objid - 1] = ObjectIdGetDatum(objectId);
	values[Anum_pg_shdepend_objsubid - 1] = Int32GetDatum(objsubId);

	values[Anum_pg_shdepend_refclassid - 1] = ObjectIdGetDatum(refclassId);
	values[Anum_pg_shdepend_refobjid - 1] = ObjectIdGetDatum(refobjId);
	values[Anum_pg_shdepend_deptype - 1] = CharGetDatum(deptype);

	tup = heap_form_tuple(sdepRel->rd_att, values, nulls);

	CatalogTupleInsert(sdepRel, tup);

	/* clean up */
	heap_freetuple(tup);
}

/*
 * shdepDropDependency
 *		Internal workhorse for deleting entries from pg_shdepend.
 *
 * We drop entries having the following properties:
 *	dependent object is the one identified by classId/objectId/objsubId
 *	if refclassId isn't InvalidOid, it must match the entry's refclassid
 *	if refobjId isn't InvalidOid, it must match the entry's refobjid
 *	if deptype isn't SHARED_DEPENDENCY_INVALID, it must match entry's deptype
 *
 * If drop_subobjects is true, we ignore objsubId and consider all entries
 * matching classId/objectId.
 *
 * sdepRel must be the pg_shdepend relation, already opened and suitably
 * locked.
 */
static void
shdepDropDependency(Relation sdepRel,
					Oid classId, Oid objectId, int32 objsubId,
					bool drop_subobjects,
					Oid refclassId, Oid refobjId,
					SharedDependencyType deptype)
{
	ScanKeyData key[4];
	int			nkeys;
	SysScanDesc scan;
	HeapTuple	tup;

	/* Scan for entries matching the dependent object */
	ScanKeyInit(&key[0],
				Anum_pg_shdepend_dbid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(classIdGetDbId(classId)));
	ScanKeyInit(&key[1],
				Anum_pg_shdepend_classid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(classId));
	ScanKeyInit(&key[2],
				Anum_pg_shdepend_objid,
				BTEqualStrategyNumber, F_OIDEQ,
				ObjectIdGetDatum(objectId));
	if (drop_subobjects)
		nkeys = 3;
	else
	{
		ScanKeyInit(&key[3],
					Anum_pg_shdepend_objsubid,
					BTEqualStrategyNumber, F_INT4EQ,
					Int32GetDatum(objsubId));
		nkeys = 4;
	}

	scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
							  NULL, nkeys, key);

	while (HeapTupleIsValid(tup = systable_getnext(scan)))
	{
		Form_pg_shdepend shdepForm = (Form_pg_shdepend) GETSTRUCT(tup);

		/* Filter entries according to additional parameters */
		if (OidIsValid(refclassId) && shdepForm->refclassid != refclassId)
			continue;
		if (OidIsValid(refobjId) && shdepForm->refobjid != refobjId)
			continue;
		if (deptype != SHARED_DEPENDENCY_INVALID &&
			shdepForm->deptype != deptype)
			continue;

		/* OK, delete it */
		CatalogTupleDelete(sdepRel, &tup->t_self);
	}

	systable_endscan(scan);
}

/*
 * classIdGetDbId
 *
 * Get the database Id that should be used in pg_shdepend, given the OID
 * of the catalog containing the object.  For shared objects, it's 0
 * (InvalidOid); for all other objects, it's the current database Id.
 */
static Oid
classIdGetDbId(Oid classId)
{
	Oid			dbId;

	if (IsSharedRelation(classId))
		dbId = InvalidOid;
	else
		dbId = MyDatabaseId;

	return dbId;
}

/*
 * shdepLockAndCheckObject
 *
 * Lock the object that we are about to record a dependency on.
 * After it's locked, verify that it hasn't been dropped while we
 * weren't looking.  If the object has been dropped, this function
 * does not return!
 */
void
shdepLockAndCheckObject(Oid classId, Oid objectId)
{
	/* AccessShareLock should be OK, since we are not modifying the object */
	LockSharedObject(classId, objectId, 0, AccessShareLock);

	switch (classId)
	{
		case AuthIdRelationId:
			if (!SearchSysCacheExists1(AUTHOID, ObjectIdGetDatum(objectId)))
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("role %u was concurrently dropped",
								objectId)));
			break;

		case TableSpaceRelationId:
			{
				/* For lack of a syscache on pg_tablespace, do this: */
				char	   *tablespace = get_tablespace_name(objectId);

				if (tablespace == NULL)
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("tablespace %u was concurrently dropped",
									objectId)));
				pfree(tablespace);
				break;
			}

		case DatabaseRelationId:
			{
				/* For lack of a syscache on pg_database, do this: */
				char	   *database = get_database_name(objectId);

				if (database == NULL)
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("database %u was concurrently dropped",
									objectId)));
				pfree(database);
				break;
			}

		case ProfileRelationId:
			{
				if (!SearchSysCacheExists1(PROFILEID, ObjectIdGetDatum(objectId)))
					ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_OBJECT),
						 errmsg("profile %u was concurrently dropped",
							       objectId)));
				break;
			}

		case StorageServerRelationId:
			{
				if (!SearchSysCacheExists1(STORAGESERVEROID, ObjectIdGetDatum(objectId)))
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("storage server %u was concurrently dropped",
			   						objectId)));
				break;
			}

		case StorageUserMappingRelationId:
			{
				if (!SearchSysCacheExists1(STORAGEUSERMAPPINGUSERSERVER, ObjectIdGetDatum(objectId)))
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("storage user mapping %u was concurrently dropped",
			   						objectId)));
				break;
			}

		case TagRelationId:
			{
				if (!SearchSysCacheExists1(TAGOID, ObjectIdGetDatum(objectId)))
					ereport(ERROR,
							(errcode(ERRCODE_UNDEFINED_OBJECT),
							 errmsg("tag %u was concurrently dropped",
									objectId)));
				break;
			}

		default:
			elog(ERROR, "unrecognized shared classId: %u", classId);
	}
}


/*
 * storeObjectDescription
 *		Append the description of a dependent object to "descs"
 *
 * While searching for dependencies of a shared object, we stash the
 * descriptions of dependent objects we find in a single string, which we
 * later pass to ereport() in the DETAIL field when somebody attempts to
 * drop a referenced shared object.
 *
 * When type is LOCAL_OBJECT or SHARED_OBJECT, we expect object to be the
 * dependent object, deptype is the dependency type, and count is not used.
 * When type is REMOTE_OBJECT, we expect object to be the database object,
 * and count to be nonzero; deptype is not used in this case.
 */
static void
storeObjectDescription(StringInfo descs,
					   SharedDependencyObjectType type,
					   ObjectAddress *object,
					   SharedDependencyType deptype,
					   int count)
{
	char	   *objdesc = getObjectDescription(object, false);

	/*
	 * An object being dropped concurrently doesn't need to be reported.
	 */
	if (objdesc == NULL)
		return;

	/* separate entries with a newline */
	if (descs->len != 0)
		appendStringInfoChar(descs, '\n');

	switch (type)
	{
		case LOCAL_OBJECT:
		case SHARED_OBJECT:
			if (deptype == SHARED_DEPENDENCY_OWNER)
				appendStringInfo(descs, _("owner of %s"), objdesc);
			else if (deptype == SHARED_DEPENDENCY_ACL)
				appendStringInfo(descs, _("privileges for %s"), objdesc);
			else if (deptype == SHARED_DEPENDENCY_POLICY)
				appendStringInfo(descs, _("target of %s"), objdesc);
			else if (deptype == SHARED_DEPENDENCY_TABLESPACE)
				appendStringInfo(descs, _("tablespace for %s"), objdesc);
			else if (deptype == SHARED_DEPENDENCY_PROFILE)
				appendStringInfo(descs, _("profile of %s"), objdesc);
			else if (deptype == SHARED_DEPENDENCY_STORAGE_SERVER)
				appendStringInfo(descs, _("storage server of %s"), objdesc);
			else if (deptype == SHARED_DEPENDENCY_TAG)
				appendStringInfo(descs, _("tag of %s"), objdesc);
			else
				elog(ERROR, "unrecognized dependency type: %d",
					 (int) deptype);
			break;

		case REMOTE_OBJECT:
			/* translator: %s will always be "database %s" */
			appendStringInfo(descs, ngettext("%d object in %s",
											 "%d objects in %s",
											 count),
							 count, objdesc);
			break;

		default:
			elog(ERROR, "unrecognized object type: %d", type);
	}

	pfree(objdesc);
}


/*
 * shdepDropOwned
 *
 * Drop the objects owned by any one of the given RoleIds.  If a role has
 * access to an object, the grant will be removed as well (but the object
 * will not, of course).
 *
 * We can revoke grants immediately while doing the scan, but drops are
 * saved up and done all at once with performMultipleDeletions.  This
 * is necessary so that we don't get failures from trying to delete
 * interdependent objects in the wrong order.
 */
void
shdepDropOwned(List *roleids, DropBehavior behavior)
{
	Relation	sdepRel;
	ListCell   *cell;
	ObjectAddresses *deleteobjs;

	deleteobjs = new_object_addresses();

	/*
	 * We don't need this strong a lock here, but we'll call routines that
	 * acquire RowExclusiveLock.  Better get that right now to avoid potential
	 * deadlock failures.
	 */
	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	/*
	 * For each role, find the dependent objects and drop them using the
	 * regular (non-shared) dependency management.
	 */
	foreach(cell, roleids)
	{
		Oid			roleid = lfirst_oid(cell);
		ScanKeyData key[2];
		SysScanDesc scan;
		HeapTuple	tuple;

		/* Doesn't work for pinned objects */
		if (IsPinnedObject(AuthIdRelationId, roleid))
		{
			ObjectAddress obj;

			obj.classId = AuthIdRelationId;
			obj.objectId = roleid;
			obj.objectSubId = 0;

			ereport(ERROR,
					(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
					 errmsg("cannot drop objects owned by %s because they are "
							"required by the database system",
							getObjectDescription(&obj, false))));
		}

		ScanKeyInit(&key[0],
					Anum_pg_shdepend_refclassid,
					BTEqualStrategyNumber, F_OIDEQ,
					ObjectIdGetDatum(AuthIdRelationId));
		ScanKeyInit(&key[1],
					Anum_pg_shdepend_refobjid,
					BTEqualStrategyNumber, F_OIDEQ,
					ObjectIdGetDatum(roleid));

		scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
								  NULL, 2, key);

		while ((tuple = systable_getnext(scan)) != NULL)
		{
			Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
			ObjectAddress obj;

			/*
			 * We only operate on shared objects and objects in the current
			 * database
			 */
			if (sdepForm->dbid != MyDatabaseId &&
				sdepForm->dbid != InvalidOid)
				continue;

			switch (sdepForm->deptype)
			{
					/* Shouldn't happen */
				case SHARED_DEPENDENCY_INVALID:
					elog(ERROR, "unexpected dependency type");
					break;
				case SHARED_DEPENDENCY_POLICY:

					/*
					 * Try to remove role from policy; if unable to, remove
					 * policy.
					 */
					if (!RemoveRoleFromObjectPolicy(roleid,
													sdepForm->classid,
													sdepForm->objid))
					{
						obj.classId = sdepForm->classid;
						obj.objectId = sdepForm->objid;
						obj.objectSubId = sdepForm->objsubid;

						/*
						 * Acquire lock on object, then verify this dependency
						 * is still relevant.  If not, the object might have
						 * been dropped or the policy modified.  Ignore the
						 * object in that case.
						 */
						AcquireDeletionLock(&obj, 0);
						if (!systable_recheck_tuple(scan, tuple))
						{
							ReleaseDeletionLock(&obj);
							break;
						}
						add_exact_object_address(&obj, deleteobjs);
					}
					break;
				case SHARED_DEPENDENCY_ACL:

					/*
					 * Dependencies on role grants are recorded using
					 * SHARED_DEPENDENCY_ACL, but unlike a regular ACL list
					 * which stores all permissions for a particular object in
					 * a single ACL array, there's a separate catalog row for
					 * each grant - so removing the grant just means removing
					 * the entire row.
					 */
					if (sdepForm->classid != AuthMemRelationId)
					{
						RemoveRoleFromObjectACL(roleid,
												sdepForm->classid,
												sdepForm->objid);
						break;
					}
					/* FALLTHROUGH */

				case SHARED_DEPENDENCY_OWNER:

					/*
					 * Save it for deletion below, if it's a local object or a
					 * role grant. Other shared objects, such as databases,
					 * should not be removed here.
					 */
					if (sdepForm->dbid == MyDatabaseId ||
						sdepForm->classid == AuthMemRelationId)
					{
						obj.classId = sdepForm->classid;
						obj.objectId = sdepForm->objid;
						obj.objectSubId = sdepForm->objsubid;
						/* as above */
						AcquireDeletionLock(&obj, 0);
						if (!systable_recheck_tuple(scan, tuple))
						{
							ReleaseDeletionLock(&obj);
							break;
						}
						add_exact_object_address(&obj, deleteobjs);
					}
					break;
			}
		}

		systable_endscan(scan);
	}

	/*
	 * For stability of deletion-report ordering, sort the objects into
	 * approximate reverse creation order before deletion.  (This might also
	 * make the deletion go a bit faster, since there's less chance of having
	 * to rearrange the objects due to dependencies.)
	 */
	sort_object_addresses(deleteobjs);

	/* the dependency mechanism does the actual work */
	performMultipleDeletions(deleteobjs, behavior, 0);

	table_close(sdepRel, RowExclusiveLock);

	free_object_addresses(deleteobjs);
}

/*
 * shdepReassignOwned
 *
 * Change the owner of objects owned by any of the roles in roleids to
 * newrole.  Grants are not touched.
 */
void
shdepReassignOwned(List *roleids, Oid newrole)
{
	Relation	sdepRel;
	ListCell   *cell;

	/*
	 * We don't need this strong a lock here, but we'll call routines that
	 * acquire RowExclusiveLock.  Better get that right now to avoid potential
	 * deadlock problems.
	 */
	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	foreach(cell, roleids)
	{
		SysScanDesc scan;
		ScanKeyData key[2];
		HeapTuple	tuple;
		Oid			roleid = lfirst_oid(cell);

		/* Refuse to work on pinned roles */
		if (IsPinnedObject(AuthIdRelationId, roleid))
		{
			ObjectAddress obj;

			obj.classId = AuthIdRelationId;
			obj.objectId = roleid;
			obj.objectSubId = 0;

			ereport(ERROR,
					(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
					 errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
							getObjectDescription(&obj, false))));

			/*
			 * There's no need to tell the whole truth, which is that we
			 * didn't track these dependencies at all ...
			 */
		}

		ScanKeyInit(&key[0],
					Anum_pg_shdepend_refclassid,
					BTEqualStrategyNumber, F_OIDEQ,
					ObjectIdGetDatum(AuthIdRelationId));
		ScanKeyInit(&key[1],
					Anum_pg_shdepend_refobjid,
					BTEqualStrategyNumber, F_OIDEQ,
					ObjectIdGetDatum(roleid));

		scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
								  NULL, 2, key);

		while ((tuple = systable_getnext(scan)) != NULL)
		{
			Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
			MemoryContext cxt,
						oldcxt;

			/*
			 * We only operate on shared objects and objects in the current
			 * database
			 */
			if (sdepForm->dbid != MyDatabaseId &&
				sdepForm->dbid != InvalidOid)
				continue;

			/* We leave non-owner dependencies alone */
			if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
				continue;

			/*
			 * The various ALTER OWNER routines tend to leak memory in
			 * CurrentMemoryContext.  That's not a problem when they're only
			 * called once per command; but in this usage where we might be
			 * touching many objects, it can amount to a serious memory leak.
			 * Fix that by running each call in a short-lived context.
			 */
			cxt = AllocSetContextCreate(CurrentMemoryContext,
										"shdepReassignOwned",
										ALLOCSET_DEFAULT_SIZES);
			oldcxt = MemoryContextSwitchTo(cxt);

			/* Issue the appropriate ALTER OWNER call */
			switch (sdepForm->classid)
			{
				case TypeRelationId:
					AlterTypeOwner_oid(sdepForm->objid, newrole, true);
					break;

				case NamespaceRelationId:
					AlterSchemaOwner_oid(sdepForm->objid, newrole);
					break;

				case RelationRelationId:

					/*
					 * Pass recursing = true so that we don't fail on indexes,
					 * owned sequences, etc when we happen to visit them
					 * before their parent table.
					 */
					ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
					break;

				case DefaultAclRelationId:

					/*
					 * Ignore default ACLs; they should be handled by DROP
					 * OWNED, not REASSIGN OWNED.
					 */
					break;

				case UserMappingRelationId:
					/* ditto */
					break;

				case ForeignServerRelationId:
					AlterForeignServerOwner_oid(sdepForm->objid, newrole);
					break;

				case ForeignDataWrapperRelationId:
					AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
					break;

				case EventTriggerRelationId:
					AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
					break;

				case PublicationRelationId:
					AlterPublicationOwner_oid(sdepForm->objid, newrole);
					break;

				case SubscriptionRelationId:
					AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
					break;

					/* Generic alter owner cases */
				case CollationRelationId:
				case ConversionRelationId:
				case OperatorRelationId:
				case ProcedureRelationId:
				case LanguageRelationId:
				case LargeObjectRelationId:
				case OperatorFamilyRelationId:
				case OperatorClassRelationId:
				case ExtensionRelationId:
				case StatisticExtRelationId:
				case TableSpaceRelationId:
				case DatabaseRelationId:
				case TSConfigRelationId:
				case TSDictionaryRelationId:
					{
						Oid			classId = sdepForm->classid;
						Relation	catalog;

						/*
						 * For large objects, the catalog to modify is
						 * pg_largeobject_metadata
						 */
						if (classId == LargeObjectRelationId)
							classId = LargeObjectMetadataRelationId;

						catalog = table_open(classId, RowExclusiveLock);

						AlterObjectOwner_internal(catalog, sdepForm->objid,
												  newrole);

						table_close(catalog, NoLock);
					}
					break;

				default:
					elog(ERROR, "unexpected classid %u", sdepForm->classid);
					break;
			}

			/* Clean up */
			MemoryContextSwitchTo(oldcxt);
			MemoryContextDelete(cxt);

			/* Make sure the next iteration will see my changes */
			CommandCounterIncrement();
		}

		systable_endscan(scan);
	}

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * recordProfileDependency
 *
 * A convenient wrapper of recordSharedDependencyOn -- register the specified
 * roles of attached to profile.
 */
void
recordProfileDependency(Oid roleId, Oid profileId)
{
	ObjectAddress myself,
				referenced;

	myself.classId = AuthIdRelationId;
	myself.objectId = roleId;
	myself.objectSubId = 0;

	referenced.classId = ProfileRelationId;
	referenced.objectId = profileId;
	referenced.objectSubId = 0;

	recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_PROFILE);
}

/*
 * changeProfileDependency
 *
 * Update the shared dependencies to account for the new profile.
 *
 * Note: we don't need an objsubid argument because only whole objects
 * have owners.
 */
void
changeProfileDependency(Oid roleId, Oid newprofileId)
{
	Relation	sdepRel;

	sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);

	/* Adjust the SHARED_DEPENDENCY_PROFILE entry */
	shdepChangeDep(sdepRel,
				AuthIdRelationId, roleId, 0,
		       		ProfileRelationId, newprofileId,
				SHARED_DEPENDENCY_PROFILE);

	table_close(sdepRel, RowExclusiveLock);
}

/*
 * recordStorageServerDependency
 *
 * A convenient wrapper of recordSharedDependencyOn -- register the specified
 * storage user mapping of attached to storage server.
 */
void
recordStorageServerDependency(Oid classId, Oid objectId, Oid srvId)
{
	ObjectAddress myself,
		referenced;

	ObjectAddressSet(myself, classId, objectId);
	ObjectAddressSet(referenced, StorageServerRelationId, srvId);

	recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_STORAGE_SERVER);
}

/*
 * recordTagDependency
 * 
 * A convenient wrapper of recoredSharedDependencyOn -- register the specified
 * tag description of attached to tag.
 */
void
recordTagDependency(Oid classId, Oid objectId, Oid tagId)
{
	ObjectAddress myself,
		referenced;
	
	ObjectAddressSet(myself, classId, objectId);
	ObjectAddressSet(referenced, TagRelationId, tagId);
	
	recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_TAG);
}