PostgreSQL Source Code  git master
dependency.h File Reference
Include dependency graph for dependency.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define LAST_OCLASS   OCLASS_TRANSFORM
 
#define PERFORM_DELETION_INTERNAL   0x0001 /* internal action */
 
#define PERFORM_DELETION_CONCURRENTLY   0x0002 /* concurrent drop */
 
#define PERFORM_DELETION_QUIETLY   0x0004 /* suppress notices */
 
#define PERFORM_DELETION_SKIP_ORIGINAL   0x0008 /* keep original obj */
 
#define PERFORM_DELETION_SKIP_EXTENSIONS   0x0010 /* keep extensions */
 

Typedefs

typedef enum DependencyType DependencyType
 
typedef enum SharedDependencyType SharedDependencyType
 
typedef struct ObjectAddresses ObjectAddresses
 
typedef enum ObjectClass ObjectClass
 

Enumerations

enum  DependencyType {
  DEPENDENCY_NORMAL = 'n', DEPENDENCY_AUTO = 'a', DEPENDENCY_INTERNAL = 'i', DEPENDENCY_INTERNAL_AUTO = 'I',
  DEPENDENCY_EXTENSION = 'e', DEPENDENCY_AUTO_EXTENSION = 'x', DEPENDENCY_PIN = 'p'
}
 
enum  SharedDependencyType {
  SHARED_DEPENDENCY_PIN = 'p', SHARED_DEPENDENCY_OWNER = 'o', SHARED_DEPENDENCY_ACL = 'a', SHARED_DEPENDENCY_POLICY = 'r',
  SHARED_DEPENDENCY_INVALID = 0
}
 
enum  ObjectClass {
  OCLASS_CLASS, OCLASS_PROC, OCLASS_TYPE, OCLASS_CAST,
  OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DEFAULT,
  OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPERATOR, OCLASS_OPCLASS,
  OCLASS_OPFAMILY, OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC,
  OCLASS_REWRITE, OCLASS_TRIGGER, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT,
  OCLASS_TSPARSER, OCLASS_TSDICT, OCLASS_TSTEMPLATE, OCLASS_TSCONFIG,
  OCLASS_ROLE, OCLASS_DATABASE, OCLASS_TBLSPACE, OCLASS_FDW,
  OCLASS_FOREIGN_SERVER, OCLASS_USER_MAPPING, OCLASS_DEFACL, OCLASS_EXTENSION,
  OCLASS_EVENT_TRIGGER, OCLASS_POLICY, OCLASS_PUBLICATION, OCLASS_PUBLICATION_REL,
  OCLASS_SUBSCRIPTION, OCLASS_TRANSFORM
}
 

Functions

void performDeletion (const ObjectAddress *object, DropBehavior behavior, int flags)
 
void performMultipleDeletions (const ObjectAddresses *objects, DropBehavior behavior, int flags)
 
void recordDependencyOnExpr (const ObjectAddress *depender, Node *expr, List *rtable, DependencyType behavior)
 
void recordDependencyOnSingleRelExpr (const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool ignore_self)
 
ObjectClass getObjectClass (const ObjectAddress *object)
 
ObjectAddressesnew_object_addresses (void)
 
void add_exact_object_address (const ObjectAddress *object, ObjectAddresses *addrs)
 
bool object_address_present (const ObjectAddress *object, const ObjectAddresses *addrs)
 
void record_object_address_dependencies (const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
 
void free_object_addresses (ObjectAddresses *addrs)
 
void recordDependencyOn (const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
 
void recordMultipleDependencies (const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
 
void recordDependencyOnCurrentExtension (const ObjectAddress *object, bool isReplace)
 
long deleteDependencyRecordsFor (Oid classId, Oid objectId, bool skipExtensionDeps)
 
long deleteDependencyRecordsForClass (Oid classId, Oid objectId, Oid refclassId, char deptype)
 
long changeDependencyFor (Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
Oid getExtensionOfObject (Oid classId, Oid objectId)
 
bool sequenceIsOwned (Oid seqId, char deptype, Oid *tableId, int32 *colId)
 
ListgetOwnedSequences (Oid relid, AttrNumber attnum)
 
Oid getOwnedSequence (Oid relid, AttrNumber attnum)
 
Oid get_constraint_index (Oid constraintId)
 
Oid get_index_constraint (Oid indexId)
 
void recordSharedDependencyOn (ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
 
void deleteSharedDependencyRecordsFor (Oid classId, Oid objectId, int32 objectSubId)
 
void recordDependencyOnOwner (Oid classId, Oid objectId, Oid owner)
 
void changeDependencyOnOwner (Oid classId, Oid objectId, Oid newOwnerId)
 
void updateAclDependencies (Oid classId, Oid objectId, int32 objectSubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
 
bool checkSharedDependencies (Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
 
void shdepLockAndCheckObject (Oid classId, Oid objectId)
 
void copyTemplateDependencies (Oid templateDbId, Oid newDbId)
 
void dropDatabaseDependencies (Oid databaseId)
 
void shdepDropOwned (List *relids, DropBehavior behavior)
 
void shdepReassignOwned (List *relids, Oid newrole)
 

Macro Definition Documentation

◆ LAST_OCLASS

#define LAST_OCLASS   OCLASS_TRANSFORM

Definition at line 186 of file dependency.h.

Referenced by add_object_address().

◆ PERFORM_DELETION_CONCURRENTLY

#define PERFORM_DELETION_CONCURRENTLY   0x0002 /* concurrent drop */

Definition at line 190 of file dependency.h.

Referenced by AcquireDeletionLock(), deleteOneObject(), doDeletion(), and RemoveRelations().

◆ PERFORM_DELETION_INTERNAL

◆ PERFORM_DELETION_QUIETLY

#define PERFORM_DELETION_QUIETLY   0x0004 /* suppress notices */

Definition at line 191 of file dependency.h.

Referenced by do_autovacuum(), RemoveTempRelations(), and reportDependentObjects().

◆ PERFORM_DELETION_SKIP_EXTENSIONS

#define PERFORM_DELETION_SKIP_EXTENSIONS   0x0010 /* keep extensions */

Definition at line 193 of file dependency.h.

Referenced by do_autovacuum(), findDependentObjects(), and RemoveTempRelations().

◆ PERFORM_DELETION_SKIP_ORIGINAL

#define PERFORM_DELETION_SKIP_ORIGINAL   0x0008 /* keep original obj */

Definition at line 192 of file dependency.h.

Referenced by deleteObjectsInList(), and RemoveTempRelations().

Typedef Documentation

◆ DependencyType

◆ ObjectAddresses

Definition at line 138 of file dependency.h.

◆ ObjectClass

◆ SharedDependencyType

Enumeration Type Documentation

◆ DependencyType

Enumerator
DEPENDENCY_NORMAL 
DEPENDENCY_AUTO 
DEPENDENCY_INTERNAL 
DEPENDENCY_INTERNAL_AUTO 
DEPENDENCY_EXTENSION 
DEPENDENCY_AUTO_EXTENSION 
DEPENDENCY_PIN 

Definition at line 87 of file dependency.h.

◆ ObjectClass

Enumerator
OCLASS_CLASS 
OCLASS_PROC 
OCLASS_TYPE 
OCLASS_CAST 
OCLASS_COLLATION 
OCLASS_CONSTRAINT 
OCLASS_CONVERSION 
OCLASS_DEFAULT 
OCLASS_LANGUAGE 
OCLASS_LARGEOBJECT 
OCLASS_OPERATOR 
OCLASS_OPCLASS 
OCLASS_OPFAMILY 
OCLASS_AM 
OCLASS_AMOP 
OCLASS_AMPROC 
OCLASS_REWRITE 
OCLASS_TRIGGER 
OCLASS_SCHEMA 
OCLASS_STATISTIC_EXT 
OCLASS_TSPARSER 
OCLASS_TSDICT 
OCLASS_TSTEMPLATE 
OCLASS_TSCONFIG 
OCLASS_ROLE 
OCLASS_DATABASE 
OCLASS_TBLSPACE 
OCLASS_FDW 
OCLASS_FOREIGN_SERVER 
OCLASS_USER_MAPPING 
OCLASS_DEFACL 
OCLASS_EXTENSION 
OCLASS_EVENT_TRIGGER 
OCLASS_POLICY 
OCLASS_PUBLICATION 
OCLASS_PUBLICATION_REL 
OCLASS_SUBSCRIPTION 
OCLASS_TRANSFORM 

Definition at line 144 of file dependency.h.

145 {
146  OCLASS_CLASS, /* pg_class */
147  OCLASS_PROC, /* pg_proc */
148  OCLASS_TYPE, /* pg_type */
149  OCLASS_CAST, /* pg_cast */
150  OCLASS_COLLATION, /* pg_collation */
151  OCLASS_CONSTRAINT, /* pg_constraint */
152  OCLASS_CONVERSION, /* pg_conversion */
153  OCLASS_DEFAULT, /* pg_attrdef */
154  OCLASS_LANGUAGE, /* pg_language */
155  OCLASS_LARGEOBJECT, /* pg_largeobject */
156  OCLASS_OPERATOR, /* pg_operator */
157  OCLASS_OPCLASS, /* pg_opclass */
158  OCLASS_OPFAMILY, /* pg_opfamily */
159  OCLASS_AM, /* pg_am */
160  OCLASS_AMOP, /* pg_amop */
161  OCLASS_AMPROC, /* pg_amproc */
162  OCLASS_REWRITE, /* pg_rewrite */
163  OCLASS_TRIGGER, /* pg_trigger */
164  OCLASS_SCHEMA, /* pg_namespace */
165  OCLASS_STATISTIC_EXT, /* pg_statistic_ext */
166  OCLASS_TSPARSER, /* pg_ts_parser */
167  OCLASS_TSDICT, /* pg_ts_dict */
168  OCLASS_TSTEMPLATE, /* pg_ts_template */
169  OCLASS_TSCONFIG, /* pg_ts_config */
170  OCLASS_ROLE, /* pg_authid */
171  OCLASS_DATABASE, /* pg_database */
172  OCLASS_TBLSPACE, /* pg_tablespace */
173  OCLASS_FDW, /* pg_foreign_data_wrapper */
174  OCLASS_FOREIGN_SERVER, /* pg_foreign_server */
175  OCLASS_USER_MAPPING, /* pg_user_mapping */
176  OCLASS_DEFACL, /* pg_default_acl */
177  OCLASS_EXTENSION, /* pg_extension */
178  OCLASS_EVENT_TRIGGER, /* pg_event_trigger */
179  OCLASS_POLICY, /* pg_policy */
180  OCLASS_PUBLICATION, /* pg_publication */
181  OCLASS_PUBLICATION_REL, /* pg_publication_rel */
182  OCLASS_SUBSCRIPTION, /* pg_subscription */
183  OCLASS_TRANSFORM /* pg_transform */
184 } ObjectClass;
ObjectClass
Definition: dependency.h:144

◆ SharedDependencyType

Enumerator
SHARED_DEPENDENCY_PIN 
SHARED_DEPENDENCY_OWNER 
SHARED_DEPENDENCY_ACL 
SHARED_DEPENDENCY_POLICY 
SHARED_DEPENDENCY_INVALID 

Definition at line 128 of file dependency.h.

Function Documentation

◆ add_exact_object_address()

void add_exact_object_address ( const ObjectAddress object,
ObjectAddresses addrs 
)

Definition at line 2185 of file dependency.c.

References Assert, ObjectAddresses::extras, ObjectAddresses::maxrefs, ObjectAddresses::numrefs, ObjectAddressStack::object, ObjectAddresses::refs, and repalloc().

Referenced by AlterConstraintNamespaces(), AlterIndexNamespaces(), AlterRelationNamespaceInternal(), AlterTypeNamespaceInternal(), makeConfigurationDependencies(), recordDependencyOnSingleRelExpr(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

2187 {
2188  ObjectAddress *item;
2189 
2190  /* enlarge array if needed */
2191  if (addrs->numrefs >= addrs->maxrefs)
2192  {
2193  addrs->maxrefs *= 2;
2194  addrs->refs = (ObjectAddress *)
2195  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2196  Assert(!addrs->extras);
2197  }
2198  /* record this item */
2199  item = addrs->refs + addrs->numrefs;
2200  *item = *object;
2201  addrs->numrefs++;
2202 }
ObjectAddress * refs
Definition: dependency.c:108
#define Assert(condition)
Definition: c.h:699
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1044
ObjectAddressExtra * extras
Definition: dependency.c:109

◆ changeDependencyFor()

long changeDependencyFor ( Oid  classId,
Oid  objectId,
Oid  refClassId,
Oid  oldRefObjectId,
Oid  newRefObjectId 
)

Definition at line 295 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, DependDependerIndexId, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, heap_close, heap_copytuple(), heap_freetuple(), heap_open(), HeapTupleIsValid, isObjectPinned(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by AlterExtensionNamespace(), AlterObjectNamespace_internal(), AlterRelationNamespaceInternal(), and AlterTypeNamespaceInternal().

298 {
299  long count = 0;
300  Relation depRel;
301  ScanKeyData key[2];
302  SysScanDesc scan;
303  HeapTuple tup;
304  ObjectAddress objAddr;
305  bool newIsPinned;
306 
307  depRel = heap_open(DependRelationId, RowExclusiveLock);
308 
309  /*
310  * If oldRefObjectId is pinned, there won't be any dependency entries on
311  * it --- we can't cope in that case. (This isn't really worth expending
312  * code to fix, in current usage; it just means you can't rename stuff out
313  * of pg_catalog, which would likely be a bad move anyway.)
314  */
315  objAddr.classId = refClassId;
316  objAddr.objectId = oldRefObjectId;
317  objAddr.objectSubId = 0;
318 
319  if (isObjectPinned(&objAddr, depRel))
320  ereport(ERROR,
321  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
322  errmsg("cannot remove dependency on %s because it is a system object",
323  getObjectDescription(&objAddr))));
324 
325  /*
326  * We can handle adding a dependency on something pinned, though, since
327  * that just means deleting the dependency entry.
328  */
329  objAddr.objectId = newRefObjectId;
330 
331  newIsPinned = isObjectPinned(&objAddr, depRel);
332 
333  /* Now search for dependency records */
334  ScanKeyInit(&key[0],
335  Anum_pg_depend_classid,
336  BTEqualStrategyNumber, F_OIDEQ,
337  ObjectIdGetDatum(classId));
338  ScanKeyInit(&key[1],
339  Anum_pg_depend_objid,
340  BTEqualStrategyNumber, F_OIDEQ,
341  ObjectIdGetDatum(objectId));
342 
343  scan = systable_beginscan(depRel, DependDependerIndexId, true,
344  NULL, 2, key);
345 
346  while (HeapTupleIsValid((tup = systable_getnext(scan))))
347  {
348  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
349 
350  if (depform->refclassid == refClassId &&
351  depform->refobjid == oldRefObjectId)
352  {
353  if (newIsPinned)
354  CatalogTupleDelete(depRel, &tup->t_self);
355  else
356  {
357  /* make a modifiable copy */
358  tup = heap_copytuple(tup);
359  depform = (Form_pg_depend) GETSTRUCT(tup);
360 
361  depform->refobjid = newRefObjectId;
362 
363  CatalogTupleUpdate(depRel, &tup->t_self, tup);
364 
365  heap_freetuple(tup);
366  }
367 
368  count++;
369  }
370  }
371 
372  systable_endscan(scan);
373 
374  heap_close(depRel, RowExclusiveLock);
375 
376  return count;
377 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:722
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define DependDependerIndexId
Definition: indexing.h:146
int errcode(int sqlerrcode)
Definition: elog.c:575
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:389
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependencyOnOwner()

void changeDependencyOnOwner ( Oid  classId,
Oid  objectId,
Oid  newOwnerId 
)

Definition at line 304 of file pg_shdepend.c.

References heap_close, heap_open(), RowExclusiveLock, SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_OWNER, shdepChangeDep(), and shdepDropDependency().

Referenced by AlterDatabaseOwner(), AlterEventTriggerOwner_internal(), AlterForeignDataWrapperOwner_internal(), AlterForeignServerOwner_internal(), AlterObjectOwner_internal(), AlterPublicationOwner_internal(), AlterSchemaOwner_internal(), AlterSubscriptionOwner_internal(), AlterTypeOwner_oid(), and ATExecChangeOwner().

305 {
306  Relation sdepRel;
307 
308  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
309 
310  /* Adjust the SHARED_DEPENDENCY_OWNER entry */
311  shdepChangeDep(sdepRel,
312  classId, objectId, 0,
313  AuthIdRelationId, newOwnerId,
315 
316  /*----------
317  * There should never be a SHARED_DEPENDENCY_ACL entry for the owner,
318  * so get rid of it if there is one. This can happen if the new owner
319  * was previously granted some rights to the object.
320  *
321  * This step is analogous to aclnewowner's removal of duplicate entries
322  * in the ACL. We have to do it to handle this scenario:
323  * A grants some rights on an object to B
324  * ALTER OWNER changes the object's owner to B
325  * ALTER OWNER changes the object's owner to C
326  * The third step would remove all mention of B from the object's ACL,
327  * but we'd still have a SHARED_DEPENDENCY_ACL for B if we did not do
328  * things this way.
329  *
330  * The rule against having a SHARED_DEPENDENCY_ACL entry for the owner
331  * allows us to fix things up in just this one place, without having
332  * to make the various ALTER OWNER routines each know about it.
333  *----------
334  */
335  shdepDropDependency(sdepRel, classId, objectId, 0, true,
336  AuthIdRelationId, newOwnerId,
338 
339  heap_close(sdepRel, RowExclusiveLock);
340 }
static void shdepChangeDep(Relation sdepRel, Oid classid, Oid objid, int32 objsubid, Oid refclassid, Oid refobjid, SharedDependencyType deptype)
Definition: pg_shdepend.c:194
#define heap_close(r, l)
Definition: heapam.h:97
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900

◆ checkSharedDependencies()

bool checkSharedDependencies ( Oid  classId,
Oid  objectId,
char **  detail_msg,
char **  detail_log_msg 
)

Definition at line 522 of file pg_shdepend.c.

References AccessShareLock, appendStringInfo(), BTEqualStrategyNumber, remoteDep::count, StringInfoData::data, remoteDep::dbOid, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), InvalidOid, lappend(), StringInfoData::len, lfirst, list_free_deep(), LOCAL_OBJECT, MAX_REPORTED_DEPS, MyDatabaseId, ngettext, NIL, ObjectIdGetDatum, palloc(), pfree(), REMOTE_OBJECT, ScanKeyInit(), SHARED_DEPENDENCY_INVALID, SHARED_DEPENDENCY_PIN, SHARED_OBJECT, SharedDependReferenceIndexId, storeObjectDescription(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by DropRole().

524 {
525  Relation sdepRel;
526  ScanKeyData key[2];
527  SysScanDesc scan;
528  HeapTuple tup;
529  int numReportedDeps = 0;
530  int numNotReportedDeps = 0;
531  int numNotReportedDbs = 0;
532  List *remDeps = NIL;
533  ListCell *cell;
534  ObjectAddress object;
535  StringInfoData descs;
536  StringInfoData alldescs;
537 
538  /*
539  * We limit the number of dependencies reported to the client to
540  * MAX_REPORTED_DEPS, since client software may not deal well with
541  * enormous error strings. The server log always gets a full report.
542  */
543 #define MAX_REPORTED_DEPS 100
544 
545  initStringInfo(&descs);
546  initStringInfo(&alldescs);
547 
548  sdepRel = heap_open(SharedDependRelationId, AccessShareLock);
549 
550  ScanKeyInit(&key[0],
551  Anum_pg_shdepend_refclassid,
552  BTEqualStrategyNumber, F_OIDEQ,
553  ObjectIdGetDatum(classId));
554  ScanKeyInit(&key[1],
555  Anum_pg_shdepend_refobjid,
556  BTEqualStrategyNumber, F_OIDEQ,
557  ObjectIdGetDatum(objectId));
558 
559  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
560  NULL, 2, key);
561 
562  while (HeapTupleIsValid(tup = systable_getnext(scan)))
563  {
564  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
565 
566  /* This case can be dispatched quickly */
567  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
568  {
569  object.classId = classId;
570  object.objectId = objectId;
571  object.objectSubId = 0;
572  ereport(ERROR,
573  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
574  errmsg("cannot drop %s because it is required by the database system",
575  getObjectDescription(&object))));
576  }
577 
578  object.classId = sdepForm->classid;
579  object.objectId = sdepForm->objid;
580  object.objectSubId = sdepForm->objsubid;
581 
582  /*
583  * If it's a dependency local to this database or it's a shared
584  * object, describe it.
585  *
586  * If it's a remote dependency, keep track of it so we can report the
587  * number of them later.
588  */
589  if (sdepForm->dbid == MyDatabaseId)
590  {
591  if (numReportedDeps < MAX_REPORTED_DEPS)
592  {
593  numReportedDeps++;
594  storeObjectDescription(&descs, LOCAL_OBJECT, &object,
595  sdepForm->deptype, 0);
596  }
597  else
598  numNotReportedDeps++;
599  storeObjectDescription(&alldescs, LOCAL_OBJECT, &object,
600  sdepForm->deptype, 0);
601  }
602  else if (sdepForm->dbid == InvalidOid)
603  {
604  if (numReportedDeps < MAX_REPORTED_DEPS)
605  {
606  numReportedDeps++;
607  storeObjectDescription(&descs, SHARED_OBJECT, &object,
608  sdepForm->deptype, 0);
609  }
610  else
611  numNotReportedDeps++;
612  storeObjectDescription(&alldescs, SHARED_OBJECT, &object,
613  sdepForm->deptype, 0);
614  }
615  else
616  {
617  /* It's not local nor shared, so it must be remote. */
618  remoteDep *dep;
619  bool stored = false;
620 
621  /*
622  * XXX this info is kept on a simple List. Maybe it's not good
623  * for performance, but using a hash table seems needlessly
624  * complex. The expected number of databases is not high anyway,
625  * I suppose.
626  */
627  foreach(cell, remDeps)
628  {
629  dep = lfirst(cell);
630  if (dep->dbOid == sdepForm->dbid)
631  {
632  dep->count++;
633  stored = true;
634  break;
635  }
636  }
637  if (!stored)
638  {
639  dep = (remoteDep *) palloc(sizeof(remoteDep));
640  dep->dbOid = sdepForm->dbid;
641  dep->count = 1;
642  remDeps = lappend(remDeps, dep);
643  }
644  }
645  }
646 
647  systable_endscan(scan);
648 
649  heap_close(sdepRel, AccessShareLock);
650 
651  /*
652  * Summarize dependencies in remote databases.
653  */
654  foreach(cell, remDeps)
655  {
656  remoteDep *dep = lfirst(cell);
657 
658  object.classId = DatabaseRelationId;
659  object.objectId = dep->dbOid;
660  object.objectSubId = 0;
661 
662  if (numReportedDeps < MAX_REPORTED_DEPS)
663  {
664  numReportedDeps++;
665  storeObjectDescription(&descs, REMOTE_OBJECT, &object,
667  }
668  else
669  numNotReportedDbs++;
670  storeObjectDescription(&alldescs, REMOTE_OBJECT, &object,
672  }
673 
674  list_free_deep(remDeps);
675 
676  if (descs.len == 0)
677  {
678  pfree(descs.data);
679  pfree(alldescs.data);
680  *detail_msg = *detail_log_msg = NULL;
681  return false;
682  }
683 
684  if (numNotReportedDeps > 0)
685  appendStringInfo(&descs, ngettext("\nand %d other object "
686  "(see server log for list)",
687  "\nand %d other objects "
688  "(see server log for list)",
689  numNotReportedDeps),
690  numNotReportedDeps);
691  if (numNotReportedDbs > 0)
692  appendStringInfo(&descs, ngettext("\nand objects in %d other database "
693  "(see server log for list)",
694  "\nand objects in %d other databases "
695  "(see server log for list)",
696  numNotReportedDbs),
697  numNotReportedDbs);
698 
699  *detail_msg = descs.data;
700  *detail_log_msg = alldescs.data;
701  return true;
702 }
#define NIL
Definition: pg_list.h:69
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
#define AccessShareLock
Definition: lockdefs.h:36
#define MAX_REPORTED_DEPS
static void storeObjectDescription(StringInfo descs, SharedDependencyObjectType type, ObjectAddress *object, SharedDependencyType deptype, int count)
Definition: pg_shdepend.c:1060
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
void list_free_deep(List *list)
Definition: list.c:1147
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define ngettext(s, p, n)
Definition: c.h:1022
Oid MyDatabaseId
Definition: globals.c:86
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:106
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define SharedDependReferenceIndexId
Definition: indexing.h:232
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ copyTemplateDependencies()

void copyTemplateDependencies ( Oid  templateDbId,
Oid  newDbId 
)

Definition at line 711 of file pg_shdepend.c.

References BTEqualStrategyNumber, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTupleInsertWithInfo(), heap_close, heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SharedDependDependerIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), and values.

Referenced by createdb().

712 {
713  Relation sdepRel;
714  TupleDesc sdepDesc;
715  ScanKeyData key[1];
716  SysScanDesc scan;
717  HeapTuple tup;
718  CatalogIndexState indstate;
719  Datum values[Natts_pg_shdepend];
720  bool nulls[Natts_pg_shdepend];
721  bool replace[Natts_pg_shdepend];
722 
723  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
724  sdepDesc = RelationGetDescr(sdepRel);
725 
726  indstate = CatalogOpenIndexes(sdepRel);
727 
728  /* Scan all entries with dbid = templateDbId */
729  ScanKeyInit(&key[0],
730  Anum_pg_shdepend_dbid,
731  BTEqualStrategyNumber, F_OIDEQ,
732  ObjectIdGetDatum(templateDbId));
733 
734  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
735  NULL, 1, key);
736 
737  /* Set up to copy the tuples except for inserting newDbId */
738  memset(values, 0, sizeof(values));
739  memset(nulls, false, sizeof(nulls));
740  memset(replace, false, sizeof(replace));
741 
742  replace[Anum_pg_shdepend_dbid - 1] = true;
743  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
744 
745  /*
746  * Copy the entries of the original database, changing the database Id to
747  * that of the new database. Note that because we are not copying rows
748  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
749  * copy the ownership dependency of the template database itself; this is
750  * what we want.
751  */
752  while (HeapTupleIsValid(tup = systable_getnext(scan)))
753  {
754  HeapTuple newtup;
755 
756  newtup = heap_modify_tuple(tup, sdepDesc, values, nulls, replace);
757  CatalogTupleInsertWithInfo(sdepRel, newtup, indstate);
758 
759  heap_freetuple(newtup);
760  }
761 
762  systable_endscan(scan);
763 
764  CatalogCloseIndexes(indstate);
765  heap_close(sdepRel, RowExclusiveLock);
766 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define SharedDependDependerIndexId
Definition: indexing.h:230
#define RelationGetDescr(relation)
Definition: rel.h:433
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:365
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
static Datum values[MAXATTR]
Definition: bootstrap.c:164
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:187
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1173
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteDependencyRecordsFor()

long deleteDependencyRecordsFor ( Oid  classId,
Oid  objectId,
bool  skipExtensionDeps 
)

Definition at line 191 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, DEPENDENCY_EXTENSION, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by AlterPolicy(), create_proc_lang(), CreateTransform(), DefineQueryRewrite(), GenerateTypeDependencies(), InsertRule(), makeConfigurationDependencies(), makeOperatorDependencies(), ProcedureCreate(), RemoveRoleFromObjectPolicy(), and swap_relation_files().

193 {
194  long count = 0;
195  Relation depRel;
196  ScanKeyData key[2];
197  SysScanDesc scan;
198  HeapTuple tup;
199 
200  depRel = heap_open(DependRelationId, RowExclusiveLock);
201 
202  ScanKeyInit(&key[0],
203  Anum_pg_depend_classid,
204  BTEqualStrategyNumber, F_OIDEQ,
205  ObjectIdGetDatum(classId));
206  ScanKeyInit(&key[1],
207  Anum_pg_depend_objid,
208  BTEqualStrategyNumber, F_OIDEQ,
209  ObjectIdGetDatum(objectId));
210 
211  scan = systable_beginscan(depRel, DependDependerIndexId, true,
212  NULL, 2, key);
213 
214  while (HeapTupleIsValid(tup = systable_getnext(scan)))
215  {
216  if (skipExtensionDeps &&
217  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
218  continue;
219 
220  CatalogTupleDelete(depRel, &tup->t_self);
221  count++;
222  }
223 
224  systable_endscan(scan);
225 
226  heap_close(depRel, RowExclusiveLock);
227 
228  return count;
229 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define DependDependerIndexId
Definition: indexing.h:146
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteDependencyRecordsForClass()

long deleteDependencyRecordsForClass ( Oid  classId,
Oid  objectId,
Oid  refclassId,
char  deptype 
)

Definition at line 241 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by AlterForeignDataWrapper(), ApplyExtensionUpdates(), ATExecDropIdentity(), ExecAlterExtensionContentsStmt(), index_constraint_create(), IndexSetParentIndex(), and process_owned_by().

243 {
244  long count = 0;
245  Relation depRel;
246  ScanKeyData key[2];
247  SysScanDesc scan;
248  HeapTuple tup;
249 
250  depRel = heap_open(DependRelationId, RowExclusiveLock);
251 
252  ScanKeyInit(&key[0],
253  Anum_pg_depend_classid,
254  BTEqualStrategyNumber, F_OIDEQ,
255  ObjectIdGetDatum(classId));
256  ScanKeyInit(&key[1],
257  Anum_pg_depend_objid,
258  BTEqualStrategyNumber, F_OIDEQ,
259  ObjectIdGetDatum(objectId));
260 
261  scan = systable_beginscan(depRel, DependDependerIndexId, true,
262  NULL, 2, key);
263 
264  while (HeapTupleIsValid(tup = systable_getnext(scan)))
265  {
266  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
267 
268  if (depform->refclassid == refclassId && depform->deptype == deptype)
269  {
270  CatalogTupleDelete(depRel, &tup->t_self);
271  count++;
272  }
273  }
274 
275  systable_endscan(scan);
276 
277  heap_close(depRel, RowExclusiveLock);
278 
279  return count;
280 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define DependDependerIndexId
Definition: indexing.h:146
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteSharedDependencyRecordsFor()

void deleteSharedDependencyRecordsFor ( Oid  classId,
Oid  objectId,
int32  objectSubId 
)

Definition at line 823 of file pg_shdepend.c.

References heap_close, heap_open(), InvalidOid, RowExclusiveLock, SHARED_DEPENDENCY_INVALID, and shdepDropDependency().

Referenced by AlterPolicy(), deleteOneObject(), DropSubscription(), DropTableSpace(), GenerateTypeDependencies(), makeConfigurationDependencies(), makeOperatorDependencies(), and RemoveRoleFromObjectPolicy().

824 {
825  Relation sdepRel;
826 
827  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
828 
829  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
830  (objectSubId == 0),
833 
834  heap_close(sdepRel, RowExclusiveLock);
835 }
#define heap_close(r, l)
Definition: heapam.h:97
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

Definition at line 775 of file pg_shdepend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), heap_close, heap_open(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_INVALID, SharedDependDependerIndexId, shdepDropDependency(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by dropdb().

776 {
777  Relation sdepRel;
778  ScanKeyData key[1];
779  SysScanDesc scan;
780  HeapTuple tup;
781 
782  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
783 
784  /*
785  * First, delete all the entries that have the database Oid in the dbid
786  * field.
787  */
788  ScanKeyInit(&key[0],
789  Anum_pg_shdepend_dbid,
790  BTEqualStrategyNumber, F_OIDEQ,
791  ObjectIdGetDatum(databaseId));
792  /* We leave the other index fields unspecified */
793 
794  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
795  NULL, 1, key);
796 
797  while (HeapTupleIsValid(tup = systable_getnext(scan)))
798  {
799  CatalogTupleDelete(sdepRel, &tup->t_self);
800  }
801 
802  systable_endscan(scan);
803 
804  /* Now delete all entries corresponding to the database itself */
805  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
808 
809  heap_close(sdepRel, RowExclusiveLock);
810 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define SharedDependDependerIndexId
Definition: indexing.h:230
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ free_object_addresses()

void free_object_addresses ( ObjectAddresses addrs)

Definition at line 2401 of file dependency.c.

References ObjectAddresses::extras, pfree(), and ObjectAddresses::refs.

Referenced by AlterTableNamespace(), AlterTypeNamespace(), makeConfigurationDependencies(), performDeletion(), performMultipleDeletions(), recordDependencyOnExpr(), recordDependencyOnSingleRelExpr(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

2402 {
2403  pfree(addrs->refs);
2404  if (addrs->extras)
2405  pfree(addrs->extras);
2406  pfree(addrs);
2407 }
void pfree(void *pointer)
Definition: mcxt.c:1031
ObjectAddress * refs
Definition: dependency.c:108
ObjectAddressExtra * extras
Definition: dependency.c:109

◆ get_constraint_index()

Oid get_constraint_index ( Oid  constraintId)

Definition at line 626 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_INTERNAL, DependReferenceIndexId, get_rel_relkind(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, InvalidOid, ObjectIdGetDatum, relkind, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ATPostAlterTypeParse(), infer_arbiter_indexes(), and pg_get_constraintdef_worker().

627 {
628  Oid indexId = InvalidOid;
629  Relation depRel;
630  ScanKeyData key[3];
631  SysScanDesc scan;
632  HeapTuple tup;
633 
634  /* Search the dependency table for the dependent index */
635  depRel = heap_open(DependRelationId, AccessShareLock);
636 
637  ScanKeyInit(&key[0],
638  Anum_pg_depend_refclassid,
639  BTEqualStrategyNumber, F_OIDEQ,
640  ObjectIdGetDatum(ConstraintRelationId));
641  ScanKeyInit(&key[1],
642  Anum_pg_depend_refobjid,
643  BTEqualStrategyNumber, F_OIDEQ,
644  ObjectIdGetDatum(constraintId));
645  ScanKeyInit(&key[2],
646  Anum_pg_depend_refobjsubid,
647  BTEqualStrategyNumber, F_INT4EQ,
648  Int32GetDatum(0));
649 
650  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
651  NULL, 3, key);
652 
653  while (HeapTupleIsValid(tup = systable_getnext(scan)))
654  {
655  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
656 
657  /*
658  * We assume any internal dependency of an index on the constraint
659  * must be what we are looking for.
660  */
661  if (deprec->classid == RelationRelationId &&
662  deprec->objsubid == 0 &&
663  deprec->deptype == DEPENDENCY_INTERNAL)
664  {
665  char relkind = get_rel_relkind(deprec->objid);
666 
667  /* This is pure paranoia; there shouldn't be any such */
668  if (relkind != RELKIND_INDEX &&
669  relkind != RELKIND_PARTITIONED_INDEX)
670  break;
671 
672  indexId = deprec->objid;
673  break;
674  }
675  }
676 
677  systable_endscan(scan);
678  heap_close(depRel, AccessShareLock);
679 
680  return indexId;
681 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
#define DependReferenceIndexId
Definition: indexing.h:148
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char relkind
Definition: pg_class.h:51
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:462
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 689 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_INTERNAL, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, InvalidOid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by generateClonedIndexStmt(), RenameRelationInternal(), and transformIndexConstraint().

690 {
691  Oid constraintId = InvalidOid;
692  Relation depRel;
693  ScanKeyData key[3];
694  SysScanDesc scan;
695  HeapTuple tup;
696 
697  /* Search the dependency table for the index */
698  depRel = heap_open(DependRelationId, AccessShareLock);
699 
700  ScanKeyInit(&key[0],
701  Anum_pg_depend_classid,
702  BTEqualStrategyNumber, F_OIDEQ,
703  ObjectIdGetDatum(RelationRelationId));
704  ScanKeyInit(&key[1],
705  Anum_pg_depend_objid,
706  BTEqualStrategyNumber, F_OIDEQ,
707  ObjectIdGetDatum(indexId));
708  ScanKeyInit(&key[2],
709  Anum_pg_depend_objsubid,
710  BTEqualStrategyNumber, F_INT4EQ,
711  Int32GetDatum(0));
712 
713  scan = systable_beginscan(depRel, DependDependerIndexId, true,
714  NULL, 3, key);
715 
716  while (HeapTupleIsValid(tup = systable_getnext(scan)))
717  {
718  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
719 
720  /*
721  * We assume any internal dependency on a constraint must be what we
722  * are looking for.
723  */
724  if (deprec->refclassid == ConstraintRelationId &&
725  deprec->refobjsubid == 0 &&
726  deprec->deptype == DEPENDENCY_INTERNAL)
727  {
728  constraintId = deprec->refobjid;
729  break;
730  }
731  }
732 
733  systable_endscan(scan);
734  heap_close(depRel, AccessShareLock);
735 
736  return constraintId;
737 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define DependDependerIndexId
Definition: indexing.h:146
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:462
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getExtensionOfObject()

Oid getExtensionOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 447 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_EXTENSION, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by AlterExtensionNamespace(), ExecAlterExtensionContentsStmt(), lookup_shippable(), pg_extension_config_dump(), and recordDependencyOnCurrentExtension().

448 {
449  Oid result = InvalidOid;
450  Relation depRel;
451  ScanKeyData key[2];
452  SysScanDesc scan;
453  HeapTuple tup;
454 
455  depRel = heap_open(DependRelationId, AccessShareLock);
456 
457  ScanKeyInit(&key[0],
458  Anum_pg_depend_classid,
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(classId));
461  ScanKeyInit(&key[1],
462  Anum_pg_depend_objid,
463  BTEqualStrategyNumber, F_OIDEQ,
464  ObjectIdGetDatum(objectId));
465 
466  scan = systable_beginscan(depRel, DependDependerIndexId, true,
467  NULL, 2, key);
468 
469  while (HeapTupleIsValid((tup = systable_getnext(scan))))
470  {
471  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
472 
473  if (depform->refclassid == ExtensionRelationId &&
474  depform->deptype == DEPENDENCY_EXTENSION)
475  {
476  result = depform->refobjid;
477  break; /* no need to keep scanning */
478  }
479  }
480 
481  systable_endscan(scan);
482 
483  heap_close(depRel, AccessShareLock);
484 
485  return result;
486 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define DependDependerIndexId
Definition: indexing.h:146
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

Definition at line 2416 of file dependency.c.

References ObjectAddress::classId, elog, ERROR, ObjectAddress::objectSubId, OCLASS_AM, OCLASS_AMOP, OCLASS_AMPROC, OCLASS_CAST, OCLASS_CLASS, OCLASS_COLLATION, OCLASS_CONSTRAINT, OCLASS_CONVERSION, OCLASS_DATABASE, OCLASS_DEFACL, OCLASS_DEFAULT, OCLASS_EVENT_TRIGGER, OCLASS_EXTENSION, OCLASS_FDW, OCLASS_FOREIGN_SERVER, OCLASS_LANGUAGE, OCLASS_LARGEOBJECT, OCLASS_OPCLASS, OCLASS_OPERATOR, OCLASS_OPFAMILY, OCLASS_POLICY, OCLASS_PROC, OCLASS_PUBLICATION, OCLASS_PUBLICATION_REL, OCLASS_REWRITE, OCLASS_ROLE, OCLASS_SCHEMA, OCLASS_STATISTIC_EXT, OCLASS_SUBSCRIPTION, OCLASS_TBLSPACE, OCLASS_TRANSFORM, OCLASS_TRIGGER, OCLASS_TSCONFIG, OCLASS_TSDICT, OCLASS_TSPARSER, OCLASS_TSTEMPLATE, OCLASS_TYPE, and OCLASS_USER_MAPPING.

Referenced by AlterObjectNamespace_oid(), ATExecAlterColumnType(), deleteObjectsInList(), doDeletion(), EventTriggerSQLDropAddObject(), getObjectDescription(), getObjectIdentityParts(), and getObjectTypeDescription().

2417 {
2418  /* only pg_class entries can have nonzero objectSubId */
2419  if (object->classId != RelationRelationId &&
2420  object->objectSubId != 0)
2421  elog(ERROR, "invalid non-zero objectSubId for object class %u",
2422  object->classId);
2423 
2424  switch (object->classId)
2425  {
2426  case RelationRelationId:
2427  /* caller must check objectSubId */
2428  return OCLASS_CLASS;
2429 
2430  case ProcedureRelationId:
2431  return OCLASS_PROC;
2432 
2433  case TypeRelationId:
2434  return OCLASS_TYPE;
2435 
2436  case CastRelationId:
2437  return OCLASS_CAST;
2438 
2439  case CollationRelationId:
2440  return OCLASS_COLLATION;
2441 
2442  case ConstraintRelationId:
2443  return OCLASS_CONSTRAINT;
2444 
2445  case ConversionRelationId:
2446  return OCLASS_CONVERSION;
2447 
2448  case AttrDefaultRelationId:
2449  return OCLASS_DEFAULT;
2450 
2451  case LanguageRelationId:
2452  return OCLASS_LANGUAGE;
2453 
2454  case LargeObjectRelationId:
2455  return OCLASS_LARGEOBJECT;
2456 
2457  case OperatorRelationId:
2458  return OCLASS_OPERATOR;
2459 
2460  case OperatorClassRelationId:
2461  return OCLASS_OPCLASS;
2462 
2463  case OperatorFamilyRelationId:
2464  return OCLASS_OPFAMILY;
2465 
2466  case AccessMethodRelationId:
2467  return OCLASS_AM;
2468 
2469  case AccessMethodOperatorRelationId:
2470  return OCLASS_AMOP;
2471 
2472  case AccessMethodProcedureRelationId:
2473  return OCLASS_AMPROC;
2474 
2475  case RewriteRelationId:
2476  return OCLASS_REWRITE;
2477 
2478  case TriggerRelationId:
2479  return OCLASS_TRIGGER;
2480 
2481  case NamespaceRelationId:
2482  return OCLASS_SCHEMA;
2483 
2484  case StatisticExtRelationId:
2485  return OCLASS_STATISTIC_EXT;
2486 
2487  case TSParserRelationId:
2488  return OCLASS_TSPARSER;
2489 
2490  case TSDictionaryRelationId:
2491  return OCLASS_TSDICT;
2492 
2493  case TSTemplateRelationId:
2494  return OCLASS_TSTEMPLATE;
2495 
2496  case TSConfigRelationId:
2497  return OCLASS_TSCONFIG;
2498 
2499  case AuthIdRelationId:
2500  return OCLASS_ROLE;
2501 
2502  case DatabaseRelationId:
2503  return OCLASS_DATABASE;
2504 
2505  case TableSpaceRelationId:
2506  return OCLASS_TBLSPACE;
2507 
2508  case ForeignDataWrapperRelationId:
2509  return OCLASS_FDW;
2510 
2511  case ForeignServerRelationId:
2512  return OCLASS_FOREIGN_SERVER;
2513 
2514  case UserMappingRelationId:
2515  return OCLASS_USER_MAPPING;
2516 
2517  case DefaultAclRelationId:
2518  return OCLASS_DEFACL;
2519 
2520  case ExtensionRelationId:
2521  return OCLASS_EXTENSION;
2522 
2523  case EventTriggerRelationId:
2524  return OCLASS_EVENT_TRIGGER;
2525 
2526  case PolicyRelationId:
2527  return OCLASS_POLICY;
2528 
2529  case PublicationRelationId:
2530  return OCLASS_PUBLICATION;
2531 
2532  case PublicationRelRelationId:
2533  return OCLASS_PUBLICATION_REL;
2534 
2535  case SubscriptionRelationId:
2536  return OCLASS_SUBSCRIPTION;
2537 
2538  case TransformRelationId:
2539  return OCLASS_TRANSFORM;
2540  }
2541 
2542  /* shouldn't get here */
2543  elog(ERROR, "unrecognized object class: %u", object->classId);
2544  return OCLASS_CLASS; /* keep compiler quiet */
2545 }
#define ERROR
Definition: elog.h:43
#define elog
Definition: elog.h:219

◆ getOwnedSequence()

Oid getOwnedSequence ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 605 of file pg_depend.c.

References elog, ERROR, getOwnedSequences(), linitial_oid, and list_length().

Referenced by ATExecDropIdentity(), build_column_default(), transformAlterTableStmt(), and transformTableLikeClause().

606 {
607  List *seqlist = getOwnedSequences(relid, attnum);
608 
609  if (list_length(seqlist) > 1)
610  elog(ERROR, "more than one owned sequence found");
611  else if (list_length(seqlist) < 1)
612  elog(ERROR, "no owned sequence found");
613 
614  return linitial_oid(seqlist);
615 }
#define ERROR
Definition: elog.h:43
List * getOwnedSequences(Oid relid, AttrNumber attnum)
Definition: pg_depend.c:548
int16 attnum
Definition: pg_attribute.h:79
#define linitial_oid(l)
Definition: pg_list.h:113
static int list_length(const List *l)
Definition: pg_list.h:89
#define elog
Definition: elog.h:219
Definition: pg_list.h:45

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 548 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_AUTO, DEPENDENCY_INTERNAL, DependReferenceIndexId, get_rel_relkind(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, lappend_oid(), NIL, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ExecuteTruncateGuts(), getOwnedSequence(), and transformAlterTableStmt().

549 {
550  List *result = NIL;
551  Relation depRel;
552  ScanKeyData key[3];
553  SysScanDesc scan;
554  HeapTuple tup;
555 
556  depRel = heap_open(DependRelationId, AccessShareLock);
557 
558  ScanKeyInit(&key[0],
559  Anum_pg_depend_refclassid,
560  BTEqualStrategyNumber, F_OIDEQ,
561  ObjectIdGetDatum(RelationRelationId));
562  ScanKeyInit(&key[1],
563  Anum_pg_depend_refobjid,
564  BTEqualStrategyNumber, F_OIDEQ,
565  ObjectIdGetDatum(relid));
566  if (attnum)
567  ScanKeyInit(&key[2],
568  Anum_pg_depend_refobjsubid,
569  BTEqualStrategyNumber, F_INT4EQ,
571 
572  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
573  NULL, attnum ? 3 : 2, key);
574 
575  while (HeapTupleIsValid(tup = systable_getnext(scan)))
576  {
577  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
578 
579  /*
580  * We assume any auto or internal dependency of a sequence on a column
581  * must be what we are looking for. (We need the relkind test because
582  * indexes can also have auto dependencies on columns.)
583  */
584  if (deprec->classid == RelationRelationId &&
585  deprec->objsubid == 0 &&
586  deprec->refobjsubid != 0 &&
587  (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
588  get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
589  {
590  result = lappend_oid(result, deprec->objid);
591  }
592  }
593 
594  systable_endscan(scan);
595 
596  heap_close(depRel, AccessShareLock);
597 
598  return result;
599 }
#define NIL
Definition: pg_list.h:69
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
#define DependReferenceIndexId
Definition: indexing.h:148
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
int16 attnum
Definition: pg_attribute.h:79
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:462
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ new_object_addresses()

ObjectAddresses* new_object_addresses ( void  )

Definition at line 2130 of file dependency.c.

References ObjectAddresses::extras, ObjectAddresses::maxrefs, ObjectAddresses::numrefs, palloc(), and ObjectAddresses::refs.

Referenced by AlterExtensionNamespace(), AlterTableNamespace(), AlterTypeNamespace(), makeConfigurationDependencies(), performDeletion(), performMultipleDeletions(), recordDependencyOnExpr(), recordDependencyOnSingleRelExpr(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

2131 {
2132  ObjectAddresses *addrs;
2133 
2134  addrs = palloc(sizeof(ObjectAddresses));
2135 
2136  addrs->numrefs = 0;
2137  addrs->maxrefs = 32;
2138  addrs->refs = (ObjectAddress *)
2139  palloc(addrs->maxrefs * sizeof(ObjectAddress));
2140  addrs->extras = NULL; /* until/unless needed */
2141 
2142  return addrs;
2143 }
ObjectAddress * refs
Definition: dependency.c:108
ObjectAddressExtra * extras
Definition: dependency.c:109
void * palloc(Size size)
Definition: mcxt.c:924

◆ object_address_present()

bool object_address_present ( const ObjectAddress object,
const ObjectAddresses addrs 
)

Definition at line 2245 of file dependency.c.

References ObjectAddress::classId, i, ObjectAddresses::numrefs, ObjectAddress::objectId, ObjectAddress::objectSubId, and ObjectAddresses::refs.

Referenced by AlterConstraintNamespaces(), AlterIndexNamespaces(), AlterRelationNamespaceInternal(), AlterTypeNamespaceInternal(), and findDependentObjects().

2247 {
2248  int i;
2249 
2250  for (i = addrs->numrefs - 1; i >= 0; i--)
2251  {
2252  const ObjectAddress *thisobj = addrs->refs + i;
2253 
2254  if (object->classId == thisobj->classId &&
2255  object->objectId == thisobj->objectId)
2256  {
2257  if (object->objectSubId == thisobj->objectSubId ||
2258  thisobj->objectSubId == 0)
2259  return true;
2260  }
2261  }
2262 
2263  return false;
2264 }
ObjectAddress * refs
Definition: dependency.c:108
int i

◆ performDeletion()

void performDeletion ( const ObjectAddress object,
DropBehavior  behavior,
int  flags 
)

Definition at line 300 of file dependency.c.

References AcquireDeletionLock(), deleteObjectsInList(), DEPFLAG_ORIGINAL, findDependentObjects(), free_object_addresses(), heap_close, heap_open(), new_object_addresses(), reportDependentObjects(), and RowExclusiveLock.

Referenced by AlterDomainDropConstraint(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropIdentity(), ATPostAlterTypeCleanup(), DefineQueryRewrite(), do_autovacuum(), dropOperators(), dropProcedures(), finish_heap_swap(), inv_drop(), PreCommit_on_commit_actions(), PublicationDropTables(), RemoveAttrDefault(), RemoveTempRelations(), RemoveUserMapping(), and SetDefaultACL().

302 {
303  Relation depRel;
304  ObjectAddresses *targetObjects;
305 
306  /*
307  * We save some cycles by opening pg_depend just once and passing the
308  * Relation pointer down to all the recursive deletion steps.
309  */
310  depRel = heap_open(DependRelationId, RowExclusiveLock);
311 
312  /*
313  * Acquire deletion lock on the target object. (Ideally the caller has
314  * done this already, but many places are sloppy about it.)
315  */
316  AcquireDeletionLock(object, 0);
317 
318  /*
319  * Construct a list of objects to delete (ie, the given object plus
320  * everything directly or indirectly dependent on it).
321  */
322  targetObjects = new_object_addresses();
323 
324  findDependentObjects(object,
326  flags,
327  NULL, /* empty stack */
328  targetObjects,
329  NULL, /* no pendingObjects */
330  &depRel);
331 
332  /*
333  * Check if deletion is allowed, and report about cascaded deletes.
334  */
335  reportDependentObjects(targetObjects,
336  behavior,
337  flags,
338  object);
339 
340  /* do the deed */
341  deleteObjectsInList(targetObjects, &depRel, flags);
342 
343  /* And clean up */
344  free_object_addresses(targetObjects);
345 
346  heap_close(depRel, RowExclusiveLock);
347 }
static void findDependentObjects(const ObjectAddress *object, int objflags, int flags, ObjectAddressStack *stack, ObjectAddresses *targetObjects, const ObjectAddresses *pendingObjects, Relation *depRel)
Definition: dependency.c:459
#define heap_close(r, l)
Definition: heapam.h:97
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2130
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2401
#define DEPFLAG_ORIGINAL
Definition: dependency.c:97
#define RowExclusiveLock
Definition: lockdefs.h:38
static void reportDependentObjects(const ObjectAddresses *targetObjects, DropBehavior behavior, int flags, const ObjectAddress *origObject)
Definition: dependency.c:836
static void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1308
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
static void deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel, int flags)
Definition: dependency.c:216

◆ performMultipleDeletions()

void performMultipleDeletions ( const ObjectAddresses objects,
DropBehavior  behavior,
int  flags 
)

Definition at line 359 of file dependency.c.

References AcquireDeletionLock(), deleteObjectsInList(), DEPFLAG_ORIGINAL, findDependentObjects(), free_object_addresses(), heap_close, heap_open(), i, new_object_addresses(), ObjectAddresses::numrefs, ObjectAddresses::refs, reportDependentObjects(), and RowExclusiveLock.

Referenced by RemoveObjects(), RemoveRelations(), and shdepDropOwned().

361 {
362  Relation depRel;
363  ObjectAddresses *targetObjects;
364  int i;
365 
366  /* No work if no objects... */
367  if (objects->numrefs <= 0)
368  return;
369 
370  /*
371  * We save some cycles by opening pg_depend just once and passing the
372  * Relation pointer down to all the recursive deletion steps.
373  */
374  depRel = heap_open(DependRelationId, RowExclusiveLock);
375 
376  /*
377  * Construct a list of objects to delete (ie, the given objects plus
378  * everything directly or indirectly dependent on them). Note that
379  * because we pass the whole objects list as pendingObjects context, we
380  * won't get a failure from trying to delete an object that is internally
381  * dependent on another one in the list; we'll just skip that object and
382  * delete it when we reach its owner.
383  */
384  targetObjects = new_object_addresses();
385 
386  for (i = 0; i < objects->numrefs; i++)
387  {
388  const ObjectAddress *thisobj = objects->refs + i;
389 
390  /*
391  * Acquire deletion lock on each target object. (Ideally the caller
392  * has done this already, but many places are sloppy about it.)
393  */
394  AcquireDeletionLock(thisobj, flags);
395 
396  findDependentObjects(thisobj,
398  flags,
399  NULL, /* empty stack */
400  targetObjects,
401  objects,
402  &depRel);
403  }
404 
405  /*
406  * Check if deletion is allowed, and report about cascaded deletes.
407  *
408  * If there's exactly one object being deleted, report it the same way as
409  * in performDeletion(), else we have to be vaguer.
410  */
411  reportDependentObjects(targetObjects,
412  behavior,
413  flags,
414  (objects->numrefs == 1 ? objects->refs : NULL));
415 
416  /* do the deed */
417  deleteObjectsInList(targetObjects, &depRel, flags);
418 
419  /* And clean up */
420  free_object_addresses(targetObjects);
421 
422  heap_close(depRel, RowExclusiveLock);
423 }
static void findDependentObjects(const ObjectAddress *object, int objflags, int flags, ObjectAddressStack *stack, ObjectAddresses *targetObjects, const ObjectAddresses *pendingObjects, Relation *depRel)
Definition: dependency.c:459
#define heap_close(r, l)
Definition: heapam.h:97
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2130
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2401
#define DEPFLAG_ORIGINAL
Definition: dependency.c:97
ObjectAddress * refs
Definition: dependency.c:108
#define RowExclusiveLock
Definition: lockdefs.h:38
static void reportDependentObjects(const ObjectAddresses *targetObjects, DropBehavior behavior, int flags, const ObjectAddress *origObject)
Definition: dependency.c:836
static void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1308
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
int i
static void deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel, int flags)
Definition: dependency.c:216

◆ record_object_address_dependencies()

void record_object_address_dependencies ( const ObjectAddress depender,
ObjectAddresses referenced,
DependencyType  behavior 
)

Definition at line 2387 of file dependency.c.

References eliminate_duplicate_dependencies(), ObjectAddresses::numrefs, recordMultipleDependencies(), and ObjectAddresses::refs.

Referenced by makeConfigurationDependencies().

2390 {
2392  recordMultipleDependencies(depender,
2393  referenced->refs, referenced->numrefs,
2394  behavior);
2395 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2039
ObjectAddress * refs
Definition: dependency.c:108
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:56

◆ recordDependencyOn()

void recordDependencyOn ( const ObjectAddress depender,
const ObjectAddress referenced,
DependencyType  behavior 
)

Definition at line 44 of file pg_depend.c.

References recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), AddNewAttributeTuples(), AggregateCreate(), AlterForeignDataWrapper(), AlterPolicy(), ApplyExtensionUpdates(), ATAddForeignKeyConstraint(), ATExecAddOf(), CloneForeignKeyConstraints(), CollationCreate(), ConstraintSetParentConstraint(), ConversionCreate(), create_proc_lang(), create_toast_table(), CreateAccessMethod(), CreateCast(), CreateConstraintEntry(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreateStatistics(), CreateTransform(), CreateTrigger(), CreateUserMapping(), DefineOpClass(), ExecAlterExtensionContentsStmt(), ExecAlterObjectDependsStmt(), GenerateTypeDependencies(), heap_create_with_catalog(), index_constraint_create(), index_create(), IndexSetParentIndex(), insert_event_trigger_tuple(), InsertExtensionTuple(), InsertRule(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeRangeConstructors(), makeTSTemplateDependencies(), ProcedureCreate(), process_owned_by(), publication_add_relation(), RangeCreate(), recordDependencyOnCurrentExtension(), RemoveRoleFromObjectPolicy(), SetDefaultACL(), SetFunctionArgType(), SetFunctionReturnType(), StoreAttrDefault(), StoreCatalogInheritance1(), storeOperators(), StorePartitionKey(), storeProcedures(), and swap_relation_files().

47 {
48  recordMultipleDependencies(depender, referenced, 1, behavior);
49 }
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:56

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

Definition at line 139 of file pg_depend.c.

References Assert, ObjectAddress::classId, creating_extension, CurrentExtensionObject, DEPENDENCY_EXTENSION, ereport, errcode(), errmsg(), ERROR, get_extension_name(), getExtensionOfObject(), getObjectDescription(), ObjectAddress::objectId, ObjectAddress::objectSubId, OidIsValid, and recordDependencyOn().

Referenced by CollationCreate(), ConversionCreate(), create_proc_lang(), CreateAccessMethod(), CreateCast(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreateTransform(), CreateUserMapping(), DefineOpClass(), GenerateTypeDependencies(), heap_create_with_catalog(), insert_event_trigger_tuple(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeTSTemplateDependencies(), NamespaceCreate(), and ProcedureCreate().

141 {
142  /* Only whole objects can be extension members */
143  Assert(object->objectSubId == 0);
144 
145  if (creating_extension)
146  {
147  ObjectAddress extension;
148 
149  /* Only need to check for existing membership if isReplace */
150  if (isReplace)
151  {
152  Oid oldext;
153 
154  oldext = getExtensionOfObject(object->classId, object->objectId);
155  if (OidIsValid(oldext))
156  {
157  /* If already a member of this extension, nothing to do */
158  if (oldext == CurrentExtensionObject)
159  return;
160  /* Already a member of some other extension, so reject */
161  ereport(ERROR,
162  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
163  errmsg("%s is already a member of extension \"%s\"",
164  getObjectDescription(object),
165  get_extension_name(oldext))));
166  }
167  }
168 
169  /* OK, record it as a member of CurrentExtensionObject */
170  extension.classId = ExtensionRelationId;
171  extension.objectId = CurrentExtensionObject;
172  extension.objectSubId = 0;
173 
174  recordDependencyOn(object, &extension, DEPENDENCY_EXTENSION);
175  }
176 }
Oid CurrentExtensionObject
Definition: extension.c:68
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:447
char * get_extension_name(Oid ext_oid)
Definition: extension.c:180
int errcode(int sqlerrcode)
Definition: elog.c:575
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
char * getObjectDescription(const ObjectAddress *object)
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
bool creating_extension
Definition: extension.c:67
#define Assert(condition)
Definition: c.h:699
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ recordDependencyOnExpr()

void recordDependencyOnExpr ( const ObjectAddress depender,
Node expr,
List rtable,
DependencyType  behavior 
)

Definition at line 1360 of file dependency.c.

References find_expr_references_context::addrs, eliminate_duplicate_dependencies(), find_expr_references_walker(), free_object_addresses(), list_make1, new_object_addresses(), ObjectAddresses::numrefs, recordMultipleDependencies(), ObjectAddresses::refs, and find_expr_references_context::rtables.

Referenced by AlterPolicy(), CreatePolicy(), CreateTrigger(), GenerateTypeDependencies(), InsertRule(), ProcedureCreate(), RemoveRoleFromObjectPolicy(), and StoreAttrDefault().

1363 {
1365 
1366  context.addrs = new_object_addresses();
1367 
1368  /* Set up interpretation for Vars at varlevelsup = 0 */
1369  context.rtables = list_make1(rtable);
1370 
1371  /* Scan the expression tree for referenceable objects */
1372  find_expr_references_walker(expr, &context);
1373 
1374  /* Remove any duplicates */
1376 
1377  /* And record 'em */
1378  recordMultipleDependencies(depender,
1379  context.addrs->refs, context.addrs->numrefs,
1380  behavior);
1381 
1382  free_object_addresses(context.addrs);
1383 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1496
ObjectAddresses * addrs
Definition: dependency.c:127
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2130
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2401
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2039
#define list_make1(x1)
Definition: pg_list.h:139
ObjectAddress * refs
Definition: dependency.c:108
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:56

◆ recordDependencyOnOwner()

void recordDependencyOnOwner ( Oid  classId,
Oid  objectId,
Oid  owner 
)

Definition at line 159 of file pg_shdepend.c.

References ObjectAddress::classId, ObjectAddress::objectId, ObjectAddress::objectSubId, recordSharedDependencyOn(), and SHARED_DEPENDENCY_OWNER.

Referenced by CollationCreate(), ConversionCreate(), create_proc_lang(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreatePublication(), CreateStatistics(), CreateSubscription(), CreateTableSpace(), CreateUserMapping(), DefineOpClass(), GenerateTypeDependencies(), heap_create_with_catalog(), insert_event_trigger_tuple(), InsertExtensionTuple(), inv_create(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), NamespaceCreate(), ProcedureCreate(), and SetDefaultACL().

160 {
161  ObjectAddress myself,
162  referenced;
163 
164  myself.classId = classId;
165  myself.objectId = objectId;
166  myself.objectSubId = 0;
167 
168  referenced.classId = AuthIdRelationId;
169  referenced.objectId = owner;
170  referenced.objectSubId = 0;
171 
172  recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_OWNER);
173 }
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:115

◆ recordDependencyOnSingleRelExpr()

void recordDependencyOnSingleRelExpr ( const ObjectAddress depender,
Node expr,
Oid  relId,
DependencyType  behavior,
DependencyType  self_behavior,
bool  ignore_self 
)

Definition at line 1401 of file dependency.c.

References add_exact_object_address(), find_expr_references_context::addrs, ObjectAddress::classId, eliminate_duplicate_dependencies(), find_expr_references_walker(), free_object_addresses(), list_make1, MemSet, new_object_addresses(), ObjectAddresses::numrefs, ObjectAddress::objectId, recordMultipleDependencies(), ObjectAddresses::refs, RangeTblEntry::relid, RangeTblEntry::relkind, find_expr_references_context::rtables, RTE_RELATION, RangeTblEntry::rtekind, T_RangeTblEntry, and RangeTblEntry::type.

Referenced by CreateConstraintEntry(), index_create(), and StorePartitionKey().

1406 {
1408  RangeTblEntry rte;
1409 
1410  context.addrs = new_object_addresses();
1411 
1412  /* We gin up a rather bogus rangetable list to handle Vars */
1413  MemSet(&rte, 0, sizeof(rte));
1414  rte.type = T_RangeTblEntry;
1415  rte.rtekind = RTE_RELATION;
1416  rte.relid = relId;
1417  rte.relkind = RELKIND_RELATION; /* no need for exactness here */
1418 
1419  context.rtables = list_make1(list_make1(&rte));
1420 
1421  /* Scan the expression tree for referenceable objects */
1422  find_expr_references_walker(expr, &context);
1423 
1424  /* Remove any duplicates */
1426 
1427  /* Separate self-dependencies if necessary */
1428  if (behavior != self_behavior && context.addrs->numrefs > 0)
1429  {
1430  ObjectAddresses *self_addrs;
1431  ObjectAddress *outobj;
1432  int oldref,
1433  outrefs;
1434 
1435  self_addrs = new_object_addresses();
1436 
1437  outobj = context.addrs->refs;
1438  outrefs = 0;
1439  for (oldref = 0; oldref < context.addrs->numrefs; oldref++)
1440  {
1441  ObjectAddress *thisobj = context.addrs->refs + oldref;
1442 
1443  if (thisobj->classId == RelationRelationId &&
1444  thisobj->objectId == relId)
1445  {
1446  /* Move this ref into self_addrs */
1447  add_exact_object_address(thisobj, self_addrs);
1448  }
1449  else
1450  {
1451  /* Keep it in context.addrs */
1452  *outobj = *thisobj;
1453  outobj++;
1454  outrefs++;
1455  }
1456  }
1457  context.addrs->numrefs = outrefs;
1458 
1459  /* Record the self-dependencies */
1460  if (!ignore_self)
1461  recordMultipleDependencies(depender,
1462  self_addrs->refs, self_addrs->numrefs,
1463  self_behavior);
1464 
1465  free_object_addresses(self_addrs);
1466  }
1467 
1468  /* Record the external dependencies */
1469  recordMultipleDependencies(depender,
1470  context.addrs->refs, context.addrs->numrefs,
1471  behavior);
1472 
1473  free_object_addresses(context.addrs);
1474 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1496
ObjectAddresses * addrs
Definition: dependency.c:127
#define MemSet(start, val, len)
Definition: c.h:908
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2185
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2130
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2401
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2039
#define list_make1(x1)
Definition: pg_list.h:139
ObjectAddress * refs
Definition: dependency.c:108
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:56
RTEKind rtekind
Definition: parsenodes.h:962
NodeTag type
Definition: parsenodes.h:960

◆ recordMultipleDependencies()

void recordMultipleDependencies ( const ObjectAddress depender,
const ObjectAddress referenced,
int  nreferenced,
DependencyType  behavior 
)

Definition at line 56 of file pg_depend.c.

References CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTupleInsertWithInfo(), CharGetDatum, ObjectAddress::classId, heap_close, heap_form_tuple(), heap_freetuple(), heap_open(), i, Int32GetDatum, IsBootstrapProcessingMode, isObjectPinned(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RelationData::rd_att, RowExclusiveLock, and values.

Referenced by record_object_address_dependencies(), recordDependencyOn(), recordDependencyOnExpr(), and recordDependencyOnSingleRelExpr().

60 {
61  Relation dependDesc;
62  CatalogIndexState indstate;
63  HeapTuple tup;
64  int i;
65  bool nulls[Natts_pg_depend];
66  Datum values[Natts_pg_depend];
67 
68  if (nreferenced <= 0)
69  return; /* nothing to do */
70 
71  /*
72  * During bootstrap, do nothing since pg_depend may not exist yet. initdb
73  * will fill in appropriate pg_depend entries after bootstrap.
74  */
76  return;
77 
78  dependDesc = heap_open(DependRelationId, RowExclusiveLock);
79 
80  /* Don't open indexes unless we need to make an update */
81  indstate = NULL;
82 
83  memset(nulls, false, sizeof(nulls));
84 
85  for (i = 0; i < nreferenced; i++, referenced++)
86  {
87  /*
88  * If the referenced object is pinned by the system, there's no real
89  * need to record dependencies on it. This saves lots of space in
90  * pg_depend, so it's worth the time taken to check.
91  */
92  if (!isObjectPinned(referenced, dependDesc))
93  {
94  /*
95  * Record the Dependency. Note we don't bother to check for
96  * duplicate dependencies; there's no harm in them.
97  */
98  values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
99  values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
100  values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
101 
102  values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
103  values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
104  values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
105 
106  values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
107 
108  tup = heap_form_tuple(dependDesc->rd_att, values, nulls);
109 
110  /* fetch index info only when we know we need it */
111  if (indstate == NULL)
112  indstate = CatalogOpenIndexes(dependDesc);
113 
114  CatalogTupleInsertWithInfo(dependDesc, tup, indstate);
115 
116  heap_freetuple(tup);
117  }
118  }
119 
120  if (indstate != NULL)
121  CatalogCloseIndexes(indstate);
122 
123  heap_close(dependDesc, RowExclusiveLock);
124 }
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1074
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:389
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:365
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
TupleDesc rd_att
Definition: rel.h:85
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:40
#define CharGetDatum(X)
Definition: postgres.h:399
static Datum values[MAXATTR]
Definition: bootstrap.c:164
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372
#define Int32GetDatum(X)
Definition: postgres.h:462
int i
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:58
Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:187

◆ recordSharedDependencyOn()

void recordSharedDependencyOn ( ObjectAddress depender,
ObjectAddress referenced,
SharedDependencyType  deptype 
)

Definition at line 115 of file pg_shdepend.c.

References Assert, ObjectAddress::classId, heap_close, heap_open(), IsBootstrapProcessingMode, isSharedObjectPinned(), ObjectAddress::objectId, ObjectAddress::objectSubId, RowExclusiveLock, and shdepAddDependency().

Referenced by AlterPolicy(), CreatePolicy(), recordDependencyOnOwner(), and RemoveRoleFromObjectPolicy().

118 {
119  Relation sdepRel;
120 
121  /*
122  * Objects in pg_shdepend can't have SubIds.
123  */
124  Assert(depender->objectSubId == 0);
125  Assert(referenced->objectSubId == 0);
126 
127  /*
128  * During bootstrap, do nothing since pg_shdepend may not exist yet.
129  * initdb will fill in appropriate pg_shdepend entries after bootstrap.
130  */
132  return;
133 
134  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
135 
136  /* If the referenced object is pinned, do nothing. */
137  if (!isSharedObjectPinned(referenced->classId, referenced->objectId,
138  sdepRel))
139  {
140  shdepAddDependency(sdepRel, depender->classId, depender->objectId,
141  depender->objectSubId,
142  referenced->classId, referenced->objectId,
143  deptype);
144  }
145 
146  heap_close(sdepRel, RowExclusiveLock);
147 }
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:845
#define heap_close(r, l)
Definition: heapam.h:97
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define Assert(condition)
Definition: c.h:699
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:372

◆ sequenceIsOwned()

bool sequenceIsOwned ( Oid  seqId,
char  deptype,
Oid tableId,
int32 colId 
)

Definition at line 500 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by AlterTableNamespace(), ATExecChangeOwner(), and process_owned_by().

501 {
502  bool ret = false;
503  Relation depRel;
504  ScanKeyData key[2];
505  SysScanDesc scan;
506  HeapTuple tup;
507 
508  depRel = heap_open(DependRelationId, AccessShareLock);
509 
510  ScanKeyInit(&key[0],
511  Anum_pg_depend_classid,
512  BTEqualStrategyNumber, F_OIDEQ,
513  ObjectIdGetDatum(RelationRelationId));
514  ScanKeyInit(&key[1],
515  Anum_pg_depend_objid,
516  BTEqualStrategyNumber, F_OIDEQ,
517  ObjectIdGetDatum(seqId));
518 
519  scan = systable_beginscan(depRel, DependDependerIndexId, true,
520  NULL, 2, key);
521 
522  while (HeapTupleIsValid((tup = systable_getnext(scan))))
523  {
524  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
525 
526  if (depform->refclassid == RelationRelationId &&
527  depform->deptype == deptype)
528  {
529  *tableId = depform->refobjid;
530  *colId = depform->refobjsubid;
531  ret = true;
532  break; /* no need to keep scanning */
533  }
534  }
535 
536  systable_endscan(scan);
537 
538  heap_close(depRel, AccessShareLock);
539 
540  return ret;
541 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define DependDependerIndexId
Definition: indexing.h:146
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ shdepDropOwned()

void shdepDropOwned ( List relids,
DropBehavior  behavior 
)

Definition at line 1163 of file pg_shdepend.c.

References add_exact_object_address(), BTEqualStrategyNumber, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, free_object_addresses(), getObjectDescription(), GETSTRUCT, heap_close, heap_open(), InvalidOid, isSharedObjectPinned(), lfirst_oid, MyDatabaseId, new_object_addresses(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, performMultipleDeletions(), RemoveRoleFromObjectACL(), RemoveRoleFromObjectPolicy(), RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_INVALID, SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_PIN, SHARED_DEPENDENCY_POLICY, SharedDependReferenceIndexId, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by DropOwnedObjects().

1164 {
1165  Relation sdepRel;
1166  ListCell *cell;
1167  ObjectAddresses *deleteobjs;
1168 
1169  deleteobjs = new_object_addresses();
1170 
1171  /*
1172  * We don't need this strong a lock here, but we'll call routines that
1173  * acquire RowExclusiveLock. Better get that right now to avoid potential
1174  * deadlock failures.
1175  */
1176  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
1177 
1178  /*
1179  * For each role, find the dependent objects and drop them using the
1180  * regular (non-shared) dependency management.
1181  */
1182  foreach(cell, roleids)
1183  {
1184  Oid roleid = lfirst_oid(cell);
1185  ScanKeyData key[2];
1186  SysScanDesc scan;
1187  HeapTuple tuple;
1188 
1189  /* Doesn't work for pinned objects */
1190  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1191  {
1192  ObjectAddress obj;
1193 
1194  obj.classId = AuthIdRelationId;
1195  obj.objectId = roleid;
1196  obj.objectSubId = 0;
1197 
1198  ereport(ERROR,
1199  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1200  errmsg("cannot drop objects owned by %s because they are "
1201  "required by the database system",
1202  getObjectDescription(&obj))));
1203  }
1204 
1205  ScanKeyInit(&key[0],
1206  Anum_pg_shdepend_refclassid,
1207  BTEqualStrategyNumber, F_OIDEQ,
1208  ObjectIdGetDatum(AuthIdRelationId));
1209  ScanKeyInit(&key[1],
1210  Anum_pg_shdepend_refobjid,
1211  BTEqualStrategyNumber, F_OIDEQ,
1212  ObjectIdGetDatum(roleid));
1213 
1214  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1215  NULL, 2, key);
1216 
1217  while ((tuple = systable_getnext(scan)) != NULL)
1218  {
1219  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1220  ObjectAddress obj;
1221 
1222  /*
1223  * We only operate on shared objects and objects in the current
1224  * database
1225  */
1226  if (sdepForm->dbid != MyDatabaseId &&
1227  sdepForm->dbid != InvalidOid)
1228  continue;
1229 
1230  switch (sdepForm->deptype)
1231  {
1232  /* Shouldn't happen */
1233  case SHARED_DEPENDENCY_PIN:
1235  elog(ERROR, "unexpected dependency type");
1236  break;
1237  case SHARED_DEPENDENCY_ACL:
1238  RemoveRoleFromObjectACL(roleid,
1239  sdepForm->classid,
1240  sdepForm->objid);
1241  break;
1243  /* If unable to remove role from policy, remove policy. */
1244  if (!RemoveRoleFromObjectPolicy(roleid,
1245  sdepForm->classid,
1246  sdepForm->objid))
1247  {
1248  obj.classId = sdepForm->classid;
1249  obj.objectId = sdepForm->objid;
1250  obj.objectSubId = sdepForm->objsubid;
1251  add_exact_object_address(&obj, deleteobjs);
1252  }
1253  break;
1255  /* If a local object, save it for deletion below */
1256  if (sdepForm->dbid == MyDatabaseId)
1257  {
1258  obj.classId = sdepForm->classid;
1259  obj.objectId = sdepForm->objid;
1260  obj.objectSubId = sdepForm->objsubid;
1261  add_exact_object_address(&obj, deleteobjs);
1262  }
1263  break;
1264  }
1265  }
1266 
1267  systable_endscan(scan);
1268  }
1269 
1270  /* the dependency mechanism does the actual work */
1271  performMultipleDeletions(deleteobjs, behavior, 0);
1272 
1273  heap_close(sdepRel, RowExclusiveLock);
1274 
1275  free_object_addresses(deleteobjs);
1276 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
int errcode(int sqlerrcode)
Definition: elog.c:575
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2185
#define heap_close(r, l)
Definition: heapam.h:97
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition: aclchk.c:1395
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2130
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2401
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * getObjectDescription(const ObjectAddress *object)
bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
Definition: policy.c:438
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
Oid MyDatabaseId
Definition: globals.c:86
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void performMultipleDeletions(const ObjectAddresses *objects, DropBehavior behavior, int flags)
Definition: dependency.c:359
#define elog
Definition: elog.h:219
#define SharedDependReferenceIndexId
Definition: indexing.h:232
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ shdepLockAndCheckObject()

void shdepLockAndCheckObject ( Oid  classId,
Oid  objectId 
)

Definition at line 987 of file pg_shdepend.c.

References AccessShareLock, AUTHOID, elog, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_tablespace_name(), LockSharedObject(), ObjectIdGetDatum, pfree(), SearchSysCacheExists1, and tablespace.

Referenced by AlterDatabaseSet(), AlterRoleSet(), shdepAddDependency(), and shdepChangeDep().

988 {
989  /* AccessShareLock should be OK, since we are not modifying the object */
990  LockSharedObject(classId, objectId, 0, AccessShareLock);
991 
992  switch (classId)
993  {
994  case AuthIdRelationId:
996  ereport(ERROR,
997  (errcode(ERRCODE_UNDEFINED_OBJECT),
998  errmsg("role %u was concurrently dropped",
999  objectId)));
1000  break;
1001 
1002  /*
1003  * Currently, this routine need not support any other shared
1004  * object types besides roles. If we wanted to record explicit
1005  * dependencies on databases or tablespaces, we'd need code along
1006  * these lines:
1007  */
1008 #ifdef NOT_USED
1009  case TableSpaceRelationId:
1010  {
1011  /* For lack of a syscache on pg_tablespace, do this: */
1012  char *tablespace = get_tablespace_name(objectId);
1013 
1014  if (tablespace == NULL)
1015  ereport(ERROR,
1016  (errcode(ERRCODE_UNDEFINED_OBJECT),
1017  errmsg("tablespace %u was concurrently dropped",
1018  objectId)));
1019  pfree(tablespace);
1020  break;
1021  }
1022 #endif
1023 
1024  case DatabaseRelationId:
1025  {
1026  /* For lack of a syscache on pg_database, do this: */
1027  char *database = get_database_name(objectId);
1028 
1029  if (database == NULL)
1030  ereport(ERROR,
1031  (errcode(ERRCODE_UNDEFINED_OBJECT),
1032  errmsg("database %u was concurrently dropped",
1033  objectId)));
1034  pfree(database);
1035  break;
1036  }
1037 
1038 
1039  default:
1040  elog(ERROR, "unrecognized shared classId: %u", classId);
1041  }
1042 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
char * tablespace
Definition: pgbench.c:155
#define ereport(elevel, rest)
Definition: elog.h:122
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:897
int errmsg(const char *fmt,...)
Definition: elog.c:797
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1428
#define elog
Definition: elog.h:219

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

Definition at line 1285 of file pg_shdepend.c.

References AccessExclusiveLock, AlterEventTriggerOwner_oid(), AlterForeignDataWrapperOwner_oid(), AlterForeignServerOwner_oid(), AlterObjectOwner_internal(), AlterPublicationOwner_oid(), AlterSchemaOwner_oid(), AlterSubscriptionOwner_oid(), AlterTypeOwner_oid(), ATExecChangeOwner(), BTEqualStrategyNumber, ObjectAddress::classId, CommandCounterIncrement(), elog, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, heap_close, heap_open(), InvalidOid, isSharedObjectPinned(), lfirst_oid, MyDatabaseId, NoLock, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_PIN, SharedDependReferenceIndexId, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ReassignOwnedObjects().

1286 {
1287  Relation sdepRel;
1288  ListCell *cell;
1289 
1290  /*
1291  * We don't need this strong a lock here, but we'll call routines that
1292  * acquire RowExclusiveLock. Better get that right now to avoid potential
1293  * deadlock problems.
1294  */
1295  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
1296 
1297  foreach(cell, roleids)
1298  {
1299  SysScanDesc scan;
1300  ScanKeyData key[2];
1301  HeapTuple tuple;
1302  Oid roleid = lfirst_oid(cell);
1303 
1304  /* Refuse to work on pinned roles */
1305  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1306  {
1307  ObjectAddress obj;
1308 
1309  obj.classId = AuthIdRelationId;
1310  obj.objectId = roleid;
1311  obj.objectSubId = 0;
1312 
1313  ereport(ERROR,
1314  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1315  errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
1316  getObjectDescription(&obj))));
1317 
1318  /*
1319  * There's no need to tell the whole truth, which is that we
1320  * didn't track these dependencies at all ...
1321  */
1322  }
1323 
1324  ScanKeyInit(&key[0],
1325  Anum_pg_shdepend_refclassid,
1326  BTEqualStrategyNumber, F_OIDEQ,
1327  ObjectIdGetDatum(AuthIdRelationId));
1328  ScanKeyInit(&key[1],
1329  Anum_pg_shdepend_refobjid,
1330  BTEqualStrategyNumber, F_OIDEQ,
1331  ObjectIdGetDatum(roleid));
1332 
1333  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1334  NULL, 2, key);
1335 
1336  while ((tuple = systable_getnext(scan)) != NULL)
1337  {
1338  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1339 
1340  /*
1341  * We only operate on shared objects and objects in the current
1342  * database
1343  */
1344  if (sdepForm->dbid != MyDatabaseId &&
1345  sdepForm->dbid != InvalidOid)
1346  continue;
1347 
1348  /* Unexpected because we checked for pins above */
1349  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
1350  elog(ERROR, "unexpected shared pin");
1351 
1352  /* We leave non-owner dependencies alone */
1353  if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
1354  continue;
1355 
1356  /* Issue the appropriate ALTER OWNER call */
1357  switch (sdepForm->classid)
1358  {
1359  case TypeRelationId:
1360  AlterTypeOwner_oid(sdepForm->objid, newrole, true);
1361  break;
1362 
1363  case NamespaceRelationId:
1364  AlterSchemaOwner_oid(sdepForm->objid, newrole);
1365  break;
1366 
1367  case RelationRelationId:
1368 
1369  /*
1370  * Pass recursing = true so that we don't fail on indexes,
1371  * owned sequences, etc when we happen to visit them
1372  * before their parent table.
1373  */
1374  ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
1375  break;
1376 
1377  case DefaultAclRelationId:
1378 
1379  /*
1380  * Ignore default ACLs; they should be handled by DROP
1381  * OWNED, not REASSIGN OWNED.
1382  */
1383  break;
1384 
1385  case UserMappingRelationId:
1386  /* ditto */
1387  break;
1388 
1389  case ForeignServerRelationId:
1390  AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1391  break;
1392 
1393  case ForeignDataWrapperRelationId:
1394  AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1395  break;
1396 
1397  case EventTriggerRelationId:
1398  AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
1399  break;
1400 
1401  case PublicationRelationId:
1402  AlterPublicationOwner_oid(sdepForm->objid, newrole);
1403  break;
1404 
1405  case SubscriptionRelationId:
1406  AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
1407  break;
1408 
1409  /* Generic alter owner cases */
1410  case CollationRelationId:
1411  case ConversionRelationId:
1412  case OperatorRelationId:
1413  case ProcedureRelationId:
1414  case LanguageRelationId:
1415  case LargeObjectRelationId:
1416  case OperatorFamilyRelationId:
1417  case OperatorClassRelationId:
1418  case ExtensionRelationId:
1419  case StatisticExtRelationId:
1420  case TableSpaceRelationId:
1421  case DatabaseRelationId:
1422  case TSConfigRelationId:
1423  case TSDictionaryRelationId:
1424  {
1425  Oid classId = sdepForm->classid;
1426  Relation catalog;
1427 
1428  if (classId == LargeObjectRelationId)
1429  classId = LargeObjectMetadataRelationId;
1430 
1431  catalog = heap_open(classId, RowExclusiveLock);
1432 
1433  AlterObjectOwner_internal(catalog, sdepForm->objid,
1434  newrole);
1435 
1436  heap_close(catalog, NoLock);
1437  }
1438  break;
1439 
1440  default:
1441  elog(ERROR, "unexpected classid %u", sdepForm->classid);
1442  break;
1443  }
1444  /* Make sure the next iteration will see my changes */
1446  }
1447 
1448  systable_endscan(scan);
1449  }
1450 
1451  heap_close(sdepRel, RowExclusiveLock);
1452 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
Definition: foreigncmds.c:312
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
void AlterSchemaOwner_oid(Oid oid, Oid newOwnerId)
Definition: schemacmds.c:298
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
void AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
Definition: foreigncmds.c:447
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
Definition: typecmds.c:3408
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:903
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:122
void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode)
Definition: tablecmds.c:10242
void CommandCounterIncrement(void)
Definition: xact.c:914
Oid MyDatabaseId
Definition: globals.c:86
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
void AlterEventTriggerOwner_oid(Oid trigOid, Oid newOwnerId)
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:797
void AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void AlterPublicationOwner_oid(Oid subid, Oid newOwnerId)
#define elog
Definition: elog.h:219
#define SharedDependReferenceIndexId
Definition: indexing.h:232
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:108

◆ updateAclDependencies()

void updateAclDependencies ( Oid  classId,
Oid  objectId,
int32  objectSubId,
Oid  ownerId,
int  noldmembers,
Oid oldmembers,
int  nnewmembers,
Oid newmembers 
)

Definition at line 421 of file pg_shdepend.c.

References getOidListDiff(), heap_close, heap_open(), i, isSharedObjectPinned(), pfree(), RowExclusiveLock, SHARED_DEPENDENCY_ACL, shdepAddDependency(), and shdepDropDependency().

Referenced by ExecGrant_Attribute(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), heap_create_with_catalog(), ProcedureCreate(), and SetDefaultACL().

425 {
426  Relation sdepRel;
427  int i;
428 
429  /*
430  * Remove entries that are common to both lists; those represent existing
431  * dependencies we don't need to change.
432  *
433  * OK to overwrite the inputs since we'll pfree them anyway.
434  */
435  getOidListDiff(oldmembers, &noldmembers, newmembers, &nnewmembers);
436 
437  if (noldmembers > 0 || nnewmembers > 0)
438  {
439  sdepRel = heap_open(SharedDependRelationId, RowExclusiveLock);
440 
441  /* Add new dependencies that weren't already present */
442  for (i = 0; i < nnewmembers; i++)
443  {
444  Oid roleid = newmembers[i];
445 
446  /*
447  * Skip the owner: he has an OWNER shdep entry instead. (This is
448  * not just a space optimization; it makes ALTER OWNER easier. See
449  * notes in changeDependencyOnOwner.)
450  */
451  if (roleid == ownerId)
452  continue;
453 
454  /* Skip pinned roles; they don't need dependency entries */
455  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
456  continue;
457 
458  shdepAddDependency(sdepRel, classId, objectId, objsubId,
459  AuthIdRelationId, roleid,
461  }
462 
463  /* Drop no-longer-used old dependencies */
464  for (i = 0; i < noldmembers; i++)
465  {
466  Oid roleid = oldmembers[i];
467 
468  /* Skip the owner, same as above */
469  if (roleid == ownerId)
470  continue;
471 
472  /* Skip pinned roles */
473  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
474  continue;
475 
476  shdepDropDependency(sdepRel, classId, objectId, objsubId,
477  false, /* exact match on objsubId */
478  AuthIdRelationId, roleid,
480  }
481 
482  heap_close(sdepRel, RowExclusiveLock);
483  }
484 
485  if (oldmembers)
486  pfree(oldmembers);
487  if (newmembers)
488  pfree(newmembers);
489 }
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1111
static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2)
Definition: pg_shdepend.c:351
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:845
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:1031
#define RowExclusiveLock
Definition: lockdefs.h:38
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:900
int i