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 */
 
#define PERFORM_DELETION_CONCURRENT_LOCK
 

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_PARTITION_PRI = 'P',
  DEPENDENCY_PARTITION_SEC = 'S', 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 AcquireDeletionLock (const ObjectAddress *object, int flags)
 
void ReleaseDeletionLock (const ObjectAddress *object)
 
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 reverse_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 sort_object_addresses (ObjectAddresses *addrs)
 
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 deleteDependencyRecordsForSpecific (Oid classId, Oid objectId, char deptype, Oid refclassId, Oid refobjectId)
 
long changeDependencyFor (Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
long changeDependenciesOf (Oid classId, Oid oldObjectId, Oid newObjectId)
 
long changeDependenciesOn (Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
Oid getExtensionOfObject (Oid classId, Oid objectId)
 
ListgetAutoExtensionsOfObject (Oid classId, Oid objectId)
 
bool sequenceIsOwned (Oid seqId, char deptype, Oid *tableId, int32 *colId)
 
ListgetOwnedSequences (Oid relid)
 
Oid getIdentitySequence (Oid relid, AttrNumber attnum, bool missing_ok)
 
Oid get_constraint_index (Oid constraintId)
 
Oid get_index_constraint (Oid indexId)
 
Listget_index_ref_constraints (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 131 of file dependency.h.

Referenced by add_object_address().

◆ PERFORM_DELETION_CONCURRENT_LOCK

#define PERFORM_DELETION_CONCURRENT_LOCK
Value:
0x0020 /* normal drop with
* concurrent lock mode */

Definition at line 139 of file dependency.h.

Referenced by doDeletion(), and ReindexRelationConcurrently().

◆ PERFORM_DELETION_CONCURRENTLY

#define PERFORM_DELETION_CONCURRENTLY   0x0002 /* concurrent drop */

Definition at line 135 of file dependency.h.

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

◆ PERFORM_DELETION_INTERNAL

◆ PERFORM_DELETION_QUIETLY

#define PERFORM_DELETION_QUIETLY   0x0004 /* suppress notices */

◆ PERFORM_DELETION_SKIP_EXTENSIONS

#define PERFORM_DELETION_SKIP_EXTENSIONS   0x0010 /* keep extensions */

Definition at line 138 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 137 of file dependency.h.

Referenced by deleteObjectsInList(), and RemoveTempRelations().

Typedef Documentation

◆ DependencyType

◆ ObjectAddresses

Definition at line 83 of file dependency.h.

◆ ObjectClass

typedef enum ObjectClass ObjectClass

◆ SharedDependencyType

Enumeration Type Documentation

◆ DependencyType

Enumerator
DEPENDENCY_NORMAL 
DEPENDENCY_AUTO 
DEPENDENCY_INTERNAL 
DEPENDENCY_PARTITION_PRI 
DEPENDENCY_PARTITION_SEC 
DEPENDENCY_EXTENSION 
DEPENDENCY_AUTO_EXTENSION 
DEPENDENCY_PIN 

Definition at line 31 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 89 of file dependency.h.

90 {
91  OCLASS_CLASS, /* pg_class */
92  OCLASS_PROC, /* pg_proc */
93  OCLASS_TYPE, /* pg_type */
94  OCLASS_CAST, /* pg_cast */
95  OCLASS_COLLATION, /* pg_collation */
96  OCLASS_CONSTRAINT, /* pg_constraint */
97  OCLASS_CONVERSION, /* pg_conversion */
98  OCLASS_DEFAULT, /* pg_attrdef */
99  OCLASS_LANGUAGE, /* pg_language */
100  OCLASS_LARGEOBJECT, /* pg_largeobject */
101  OCLASS_OPERATOR, /* pg_operator */
102  OCLASS_OPCLASS, /* pg_opclass */
103  OCLASS_OPFAMILY, /* pg_opfamily */
104  OCLASS_AM, /* pg_am */
105  OCLASS_AMOP, /* pg_amop */
106  OCLASS_AMPROC, /* pg_amproc */
107  OCLASS_REWRITE, /* pg_rewrite */
108  OCLASS_TRIGGER, /* pg_trigger */
109  OCLASS_SCHEMA, /* pg_namespace */
110  OCLASS_STATISTIC_EXT, /* pg_statistic_ext */
111  OCLASS_TSPARSER, /* pg_ts_parser */
112  OCLASS_TSDICT, /* pg_ts_dict */
113  OCLASS_TSTEMPLATE, /* pg_ts_template */
114  OCLASS_TSCONFIG, /* pg_ts_config */
115  OCLASS_ROLE, /* pg_authid */
116  OCLASS_DATABASE, /* pg_database */
117  OCLASS_TBLSPACE, /* pg_tablespace */
118  OCLASS_FDW, /* pg_foreign_data_wrapper */
119  OCLASS_FOREIGN_SERVER, /* pg_foreign_server */
120  OCLASS_USER_MAPPING, /* pg_user_mapping */
121  OCLASS_DEFACL, /* pg_default_acl */
122  OCLASS_EXTENSION, /* pg_extension */
123  OCLASS_EVENT_TRIGGER, /* pg_event_trigger */
124  OCLASS_POLICY, /* pg_policy */
125  OCLASS_PUBLICATION, /* pg_publication */
126  OCLASS_PUBLICATION_REL, /* pg_publication_rel */
127  OCLASS_SUBSCRIPTION, /* pg_subscription */
128  OCLASS_TRANSFORM /* pg_transform */
129 } ObjectClass;
ObjectClass
Definition: dependency.h:89

◆ SharedDependencyType

Enumerator
SHARED_DEPENDENCY_PIN 
SHARED_DEPENDENCY_OWNER 
SHARED_DEPENDENCY_ACL 
SHARED_DEPENDENCY_POLICY 
SHARED_DEPENDENCY_INVALID 

Definition at line 73 of file dependency.h.

Function Documentation

◆ AcquireDeletionLock()

void AcquireDeletionLock ( const ObjectAddress object,
int  flags 
)

Definition at line 1528 of file dependency.c.

References AccessExclusiveLock, ObjectAddress::classId, LockDatabaseObject(), LockRelationOid(), ObjectAddress::objectId, PERFORM_DELETION_CONCURRENTLY, and ShareUpdateExclusiveLock.

Referenced by findDependentObjects(), performDeletion(), performMultipleDeletions(), and shdepDropOwned().

1529 {
1530  if (object->classId == RelationRelationId)
1531  {
1532  /*
1533  * In DROP INDEX CONCURRENTLY, take only ShareUpdateExclusiveLock on
1534  * the index for the moment. index_drop() will promote the lock once
1535  * it's safe to do so. In all other cases we need full exclusive
1536  * lock.
1537  */
1538  if (flags & PERFORM_DELETION_CONCURRENTLY)
1540  else
1542  }
1543  else
1544  {
1545  /* assume we should lock the whole object not a sub-object */
1546  LockDatabaseObject(object->classId, object->objectId, 0,
1548  }
1549 }
#define PERFORM_DELETION_CONCURRENTLY
Definition: dependency.h:135
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:961
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define AccessExclusiveLock
Definition: lockdefs.h:45
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:108

◆ add_exact_object_address()

void add_exact_object_address ( const ObjectAddress object,
ObjectAddresses addrs 
)

Definition at line 2465 of file dependency.c.

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

Referenced by AlterConstraintNamespaces(), AlterIndexNamespaces(), AlterRelationNamespaceInternal(), AlterTypeNamespaceInternal(), ATExecDropColumn(), ATPostAlterTypeCleanup(), DropClonedTriggersFromPartition(), InsertExtensionTuple(), makeConfigurationDependencies(), PreCommit_on_commit_actions(), recordDependencyOnSingleRelExpr(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

2467 {
2468  ObjectAddress *item;
2469 
2470  /* enlarge array if needed */
2471  if (addrs->numrefs >= addrs->maxrefs)
2472  {
2473  addrs->maxrefs *= 2;
2474  addrs->refs = (ObjectAddress *)
2475  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2476  Assert(!addrs->extras);
2477  }
2478  /* record this item */
2479  item = addrs->refs + addrs->numrefs;
2480  *item = *object;
2481  addrs->numrefs++;
2482 }
ObjectAddress * refs
Definition: dependency.c:111
#define Assert(condition)
Definition: c.h:738
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
ObjectAddressExtra * extras
Definition: dependency.c:112

◆ changeDependenciesOf()

long changeDependenciesOf ( Oid  classId,
Oid  oldObjectId,
Oid  newObjectId 
)

Definition at line 456 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleUpdate(), DependDependerIndexId, GETSTRUCT, heap_copytuple(), heap_freetuple(), HeapTupleIsValid, sort-test::key, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by index_concurrently_swap().

458 {
459  long count = 0;
460  Relation depRel;
461  ScanKeyData key[2];
462  SysScanDesc scan;
463  HeapTuple tup;
464 
465  depRel = table_open(DependRelationId, RowExclusiveLock);
466 
467  ScanKeyInit(&key[0],
468  Anum_pg_depend_classid,
469  BTEqualStrategyNumber, F_OIDEQ,
470  ObjectIdGetDatum(classId));
471  ScanKeyInit(&key[1],
472  Anum_pg_depend_objid,
473  BTEqualStrategyNumber, F_OIDEQ,
474  ObjectIdGetDatum(oldObjectId));
475 
476  scan = systable_beginscan(depRel, DependDependerIndexId, true,
477  NULL, 2, key);
478 
479  while (HeapTupleIsValid((tup = systable_getnext(scan))))
480  {
481  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
482 
483  /* make a modifiable copy */
484  tup = heap_copytuple(tup);
485  depform = (Form_pg_depend) GETSTRUCT(tup);
486 
487  depform->objid = newObjectId;
488 
489  CatalogTupleUpdate(depRel, &tup->t_self, tup);
490 
491  heap_freetuple(tup);
492 
493  count++;
494  }
495 
496  systable_endscan(scan);
497 
498  table_close(depRel, RowExclusiveLock);
499 
500  return count;
501 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
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 HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependenciesOn()

long changeDependenciesOn ( Oid  refClassId,
Oid  oldRefObjectId,
Oid  newRefObjectId 
)

Definition at line 512 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, DependReferenceIndexId, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, heap_copytuple(), heap_freetuple(), HeapTupleIsValid, isObjectPinned(), sort-test::key, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by index_concurrently_swap().

514 {
515  long count = 0;
516  Relation depRel;
517  ScanKeyData key[2];
518  SysScanDesc scan;
519  HeapTuple tup;
520  ObjectAddress objAddr;
521  bool newIsPinned;
522 
523  depRel = table_open(DependRelationId, RowExclusiveLock);
524 
525  /*
526  * If oldRefObjectId is pinned, there won't be any dependency entries on
527  * it --- we can't cope in that case. (This isn't really worth expending
528  * code to fix, in current usage; it just means you can't rename stuff out
529  * of pg_catalog, which would likely be a bad move anyway.)
530  */
531  objAddr.classId = refClassId;
532  objAddr.objectId = oldRefObjectId;
533  objAddr.objectSubId = 0;
534 
535  if (isObjectPinned(&objAddr, depRel))
536  ereport(ERROR,
537  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
538  errmsg("cannot remove dependency on %s because it is a system object",
539  getObjectDescription(&objAddr))));
540 
541  /*
542  * We can handle adding a dependency on something pinned, though, since
543  * that just means deleting the dependency entry.
544  */
545  objAddr.objectId = newRefObjectId;
546 
547  newIsPinned = isObjectPinned(&objAddr, depRel);
548 
549  /* Now search for dependency records */
550  ScanKeyInit(&key[0],
551  Anum_pg_depend_refclassid,
552  BTEqualStrategyNumber, F_OIDEQ,
553  ObjectIdGetDatum(refClassId));
554  ScanKeyInit(&key[1],
555  Anum_pg_depend_refobjid,
556  BTEqualStrategyNumber, F_OIDEQ,
557  ObjectIdGetDatum(oldRefObjectId));
558 
559  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
560  NULL, 2, key);
561 
562  while (HeapTupleIsValid((tup = systable_getnext(scan))))
563  {
564  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
565 
566  if (newIsPinned)
567  CatalogTupleDelete(depRel, &tup->t_self);
568  else
569  {
570  /* make a modifiable copy */
571  tup = heap_copytuple(tup);
572  depform = (Form_pg_depend) GETSTRUCT(tup);
573 
574  depform->refobjid = newRefObjectId;
575 
576  CatalogTupleUpdate(depRel, &tup->t_self, tup);
577 
578  heap_freetuple(tup);
579  }
580 
581  count++;
582  }
583 
584  systable_endscan(scan);
585 
586  table_close(depRel, RowExclusiveLock);
587 
588  return count;
589 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependReferenceIndexId
Definition: indexing.h:151
int errcode(int sqlerrcode)
Definition: elog.c:610
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:601
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#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,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependencyFor()

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

Definition at line 346 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, DependDependerIndexId, DEPENDENCY_NORMAL, GETSTRUCT, heap_copytuple(), heap_freetuple(), HeapTupleIsValid, isObjectPinned(), sort-test::key, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, recordDependencyOn(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

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

349 {
350  long count = 0;
351  Relation depRel;
352  ScanKeyData key[2];
353  SysScanDesc scan;
354  HeapTuple tup;
355  ObjectAddress objAddr;
356  ObjectAddress depAddr;
357  bool oldIsPinned;
358  bool newIsPinned;
359 
360  depRel = table_open(DependRelationId, RowExclusiveLock);
361 
362  /*
363  * Check to see if either oldRefObjectId or newRefObjectId is pinned.
364  * Pinned objects should not have any dependency entries pointing to them,
365  * so in these cases we should add or remove a pg_depend entry, or do
366  * nothing at all, rather than update an entry as in the normal case.
367  */
368  objAddr.classId = refClassId;
369  objAddr.objectId = oldRefObjectId;
370  objAddr.objectSubId = 0;
371 
372  oldIsPinned = isObjectPinned(&objAddr, depRel);
373 
374  objAddr.objectId = newRefObjectId;
375 
376  newIsPinned = isObjectPinned(&objAddr, depRel);
377 
378  if (oldIsPinned)
379  {
380  table_close(depRel, RowExclusiveLock);
381 
382  /*
383  * If both are pinned, we need do nothing. However, return 1 not 0,
384  * else callers will think this is an error case.
385  */
386  if (newIsPinned)
387  return 1;
388 
389  /*
390  * There is no old dependency record, but we should insert a new one.
391  * Assume a normal dependency is wanted.
392  */
393  depAddr.classId = classId;
394  depAddr.objectId = objectId;
395  depAddr.objectSubId = 0;
396  recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL);
397 
398  return 1;
399  }
400 
401  /* There should be existing dependency record(s), so search. */
402  ScanKeyInit(&key[0],
403  Anum_pg_depend_classid,
404  BTEqualStrategyNumber, F_OIDEQ,
405  ObjectIdGetDatum(classId));
406  ScanKeyInit(&key[1],
407  Anum_pg_depend_objid,
408  BTEqualStrategyNumber, F_OIDEQ,
409  ObjectIdGetDatum(objectId));
410 
411  scan = systable_beginscan(depRel, DependDependerIndexId, true,
412  NULL, 2, key);
413 
414  while (HeapTupleIsValid((tup = systable_getnext(scan))))
415  {
416  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
417 
418  if (depform->refclassid == refClassId &&
419  depform->refobjid == oldRefObjectId)
420  {
421  if (newIsPinned)
422  CatalogTupleDelete(depRel, &tup->t_self);
423  else
424  {
425  /* make a modifiable copy */
426  tup = heap_copytuple(tup);
427  depform = (Form_pg_depend) GETSTRUCT(tup);
428 
429  depform->refobjid = newRefObjectId;
430 
431  CatalogTupleUpdate(depRel, &tup->t_self, tup);
432 
433  heap_freetuple(tup);
434  }
435 
436  count++;
437  }
438  }
439 
440  systable_endscan(scan);
441 
442  table_close(depRel, RowExclusiveLock);
443 
444  return count;
445 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:601
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
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 HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependencyOnOwner()

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

Definition at line 309 of file pg_shdepend.c.

References RowExclusiveLock, SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_OWNER, shdepChangeDep(), shdepDropDependency(), table_close(), and table_open().

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

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

◆ checkSharedDependencies()

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

Definition at line 577 of file pg_shdepend.c.

References AccessShareLock, appendStringInfo(), BTEqualStrategyNumber, remoteDep::count, StringInfoData::data, remoteDep::dbOid, ShDependObjectInfo::deptype, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, HeapTupleIsValid, i, initStringInfo(), InvalidOid, sort-test::key, lappend(), StringInfoData::len, lfirst, list_free_deep(), LOCAL_OBJECT, MAX_REPORTED_DEPS, MyDatabaseId, ngettext, NIL, ShDependObjectInfo::object, ObjectIdGetDatum, ShDependObjectInfo::objtype, palloc(), pfree(), qsort, REMOTE_OBJECT, repalloc(), ScanKeyInit(), shared_dependency_comparator(), SHARED_DEPENDENCY_INVALID, SHARED_DEPENDENCY_PIN, SHARED_OBJECT, SharedDependReferenceIndexId, storeObjectDescription(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by DropRole().

579 {
580  Relation sdepRel;
581  ScanKeyData key[2];
582  SysScanDesc scan;
583  HeapTuple tup;
584  int numReportedDeps = 0;
585  int numNotReportedDeps = 0;
586  int numNotReportedDbs = 0;
587  List *remDeps = NIL;
588  ListCell *cell;
589  ObjectAddress object;
590  ShDependObjectInfo *objects;
591  int numobjects;
592  int allocedobjects;
593  StringInfoData descs;
594  StringInfoData alldescs;
595 
596  /*
597  * We limit the number of dependencies reported to the client to
598  * MAX_REPORTED_DEPS, since client software may not deal well with
599  * enormous error strings. The server log always gets a full report.
600  *
601  * For stability of regression test results, we sort local and shared
602  * objects by OID before reporting them. We don't worry about the order
603  * in which other databases are reported, though.
604  */
605 #define MAX_REPORTED_DEPS 100
606 
607  allocedobjects = 128; /* arbitrary initial array size */
608  objects = (ShDependObjectInfo *)
609  palloc(allocedobjects * sizeof(ShDependObjectInfo));
610  numobjects = 0;
611  initStringInfo(&descs);
612  initStringInfo(&alldescs);
613 
614  sdepRel = table_open(SharedDependRelationId, AccessShareLock);
615 
616  ScanKeyInit(&key[0],
617  Anum_pg_shdepend_refclassid,
618  BTEqualStrategyNumber, F_OIDEQ,
619  ObjectIdGetDatum(classId));
620  ScanKeyInit(&key[1],
621  Anum_pg_shdepend_refobjid,
622  BTEqualStrategyNumber, F_OIDEQ,
623  ObjectIdGetDatum(objectId));
624 
625  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
626  NULL, 2, key);
627 
628  while (HeapTupleIsValid(tup = systable_getnext(scan)))
629  {
630  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
631 
632  /* This case can be dispatched quickly */
633  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
634  {
635  object.classId = classId;
636  object.objectId = objectId;
637  object.objectSubId = 0;
638  ereport(ERROR,
639  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
640  errmsg("cannot drop %s because it is required by the database system",
641  getObjectDescription(&object))));
642  }
643 
644  object.classId = sdepForm->classid;
645  object.objectId = sdepForm->objid;
646  object.objectSubId = sdepForm->objsubid;
647 
648  /*
649  * If it's a dependency local to this database or it's a shared
650  * object, add it to the objects array.
651  *
652  * If it's a remote dependency, keep track of it so we can report the
653  * number of them later.
654  */
655  if (sdepForm->dbid == MyDatabaseId ||
656  sdepForm->dbid == InvalidOid)
657  {
658  if (numobjects >= allocedobjects)
659  {
660  allocedobjects *= 2;
661  objects = (ShDependObjectInfo *)
662  repalloc(objects,
663  allocedobjects * sizeof(ShDependObjectInfo));
664  }
665  objects[numobjects].object = object;
666  objects[numobjects].deptype = sdepForm->deptype;
667  objects[numobjects].objtype = (sdepForm->dbid == MyDatabaseId) ?
669  numobjects++;
670  }
671  else
672  {
673  /* It's not local nor shared, so it must be remote. */
674  remoteDep *dep;
675  bool stored = false;
676 
677  /*
678  * XXX this info is kept on a simple List. Maybe it's not good
679  * for performance, but using a hash table seems needlessly
680  * complex. The expected number of databases is not high anyway,
681  * I suppose.
682  */
683  foreach(cell, remDeps)
684  {
685  dep = lfirst(cell);
686  if (dep->dbOid == sdepForm->dbid)
687  {
688  dep->count++;
689  stored = true;
690  break;
691  }
692  }
693  if (!stored)
694  {
695  dep = (remoteDep *) palloc(sizeof(remoteDep));
696  dep->dbOid = sdepForm->dbid;
697  dep->count = 1;
698  remDeps = lappend(remDeps, dep);
699  }
700  }
701  }
702 
703  systable_endscan(scan);
704 
705  table_close(sdepRel, AccessShareLock);
706 
707  /*
708  * Sort and report local and shared objects.
709  */
710  if (numobjects > 1)
711  qsort((void *) objects, numobjects,
713 
714  for (int i = 0; i < numobjects; i++)
715  {
716  if (numReportedDeps < MAX_REPORTED_DEPS)
717  {
718  numReportedDeps++;
719  storeObjectDescription(&descs,
720  objects[i].objtype,
721  &objects[i].object,
722  objects[i].deptype,
723  0);
724  }
725  else
726  numNotReportedDeps++;
727  storeObjectDescription(&alldescs,
728  objects[i].objtype,
729  &objects[i].object,
730  objects[i].deptype,
731  0);
732  }
733 
734  /*
735  * Summarize dependencies in remote databases.
736  */
737  foreach(cell, remDeps)
738  {
739  remoteDep *dep = lfirst(cell);
740 
741  object.classId = DatabaseRelationId;
742  object.objectId = dep->dbOid;
743  object.objectSubId = 0;
744 
745  if (numReportedDeps < MAX_REPORTED_DEPS)
746  {
747  numReportedDeps++;
748  storeObjectDescription(&descs, REMOTE_OBJECT, &object,
750  }
751  else
752  numNotReportedDbs++;
753  storeObjectDescription(&alldescs, REMOTE_OBJECT, &object,
755  }
756 
757  pfree(objects);
758  list_free_deep(remDeps);
759 
760  if (descs.len == 0)
761  {
762  pfree(descs.data);
763  pfree(alldescs.data);
764  *detail_msg = *detail_log_msg = NULL;
765  return false;
766  }
767 
768  if (numNotReportedDeps > 0)
769  appendStringInfo(&descs, ngettext("\nand %d other object "
770  "(see server log for list)",
771  "\nand %d other objects "
772  "(see server log for list)",
773  numNotReportedDeps),
774  numNotReportedDeps);
775  if (numNotReportedDbs > 0)
776  appendStringInfo(&descs, ngettext("\nand objects in %d other database "
777  "(see server log for list)",
778  "\nand objects in %d other databases "
779  "(see server log for list)",
780  numNotReportedDbs),
781  numNotReportedDbs);
782 
783  *detail_msg = descs.data;
784  *detail_log_msg = alldescs.data;
785  return true;
786 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
static int shared_dependency_comparator(const void *a, const void *b)
Definition: pg_shdepend.c:509
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
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:1144
int errcode(int sqlerrcode)
Definition: elog.c:610
void list_free_deep(List *list)
Definition: list.c:1390
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
SharedDependencyObjectType objtype
Definition: pg_shdepend.c:80
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
void pfree(void *pointer)
Definition: mcxt.c:1056
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
List * lappend(List *list, void *datum)
Definition: list.c:321
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define ngettext(s, p, n)
Definition: c.h:1145
Oid MyDatabaseId
Definition: globals.c:85
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1069
void * palloc(Size size)
Definition: mcxt.c:949
int errmsg(const char *fmt,...)
Definition: elog.c:824
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define SharedDependReferenceIndexId
Definition: indexing.h:225
#define qsort(a, b, c, d)
Definition: port.h:479
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define BTEqualStrategyNumber
Definition: stratnum.h:31
ObjectAddress object
Definition: pg_shdepend.c:78

◆ copyTemplateDependencies()

void copyTemplateDependencies ( Oid  templateDbId,
Oid  newDbId 
)

Definition at line 795 of file pg_shdepend.c.

References BTEqualStrategyNumber, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTupleInsertWithInfo(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, sort-test::key, ObjectIdGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SharedDependDependerIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and values.

Referenced by createdb().

796 {
797  Relation sdepRel;
798  TupleDesc sdepDesc;
799  ScanKeyData key[1];
800  SysScanDesc scan;
801  HeapTuple tup;
802  CatalogIndexState indstate;
803  Datum values[Natts_pg_shdepend];
804  bool nulls[Natts_pg_shdepend];
805  bool replace[Natts_pg_shdepend];
806 
807  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
808  sdepDesc = RelationGetDescr(sdepRel);
809 
810  indstate = CatalogOpenIndexes(sdepRel);
811 
812  /* Scan all entries with dbid = templateDbId */
813  ScanKeyInit(&key[0],
814  Anum_pg_shdepend_dbid,
815  BTEqualStrategyNumber, F_OIDEQ,
816  ObjectIdGetDatum(templateDbId));
817 
818  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
819  NULL, 1, key);
820 
821  /* Set up to copy the tuples except for inserting newDbId */
822  memset(values, 0, sizeof(values));
823  memset(nulls, false, sizeof(nulls));
824  memset(replace, false, sizeof(replace));
825 
826  replace[Anum_pg_shdepend_dbid - 1] = true;
827  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
828 
829  /*
830  * Copy the entries of the original database, changing the database Id to
831  * that of the new database. Note that because we are not copying rows
832  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
833  * copy the ownership dependency of the template database itself; this is
834  * what we want.
835  */
836  while (HeapTupleIsValid(tup = systable_getnext(scan)))
837  {
838  HeapTuple newtup;
839 
840  newtup = heap_modify_tuple(tup, sdepDesc, values, nulls, replace);
841  CatalogTupleInsertWithInfo(sdepRel, newtup, indstate);
842 
843  heap_freetuple(newtup);
844  }
845 
846  systable_endscan(scan);
847 
848  CatalogCloseIndexes(indstate);
849  table_close(sdepRel, RowExclusiveLock);
850 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define SharedDependDependerIndexId
Definition: indexing.h:223
#define RelationGetDescr(relation)
Definition: rel.h:482
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define RowExclusiveLock
Definition: lockdefs.h:38
uintptr_t Datum
Definition: postgres.h:367
void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup, CatalogIndexState indstate)
Definition: indexing.c:204
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:42
static Datum values[MAXATTR]
Definition: bootstrap.c:167
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:60
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:1113
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteDependencyRecordsFor()

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

Definition at line 190 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, DEPENDENCY_EXTENSION, GETSTRUCT, HeapTupleIsValid, sort-test::key, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

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

192 {
193  long count = 0;
194  Relation depRel;
195  ScanKeyData key[2];
196  SysScanDesc scan;
197  HeapTuple tup;
198 
199  depRel = table_open(DependRelationId, RowExclusiveLock);
200 
201  ScanKeyInit(&key[0],
202  Anum_pg_depend_classid,
203  BTEqualStrategyNumber, F_OIDEQ,
204  ObjectIdGetDatum(classId));
205  ScanKeyInit(&key[1],
206  Anum_pg_depend_objid,
207  BTEqualStrategyNumber, F_OIDEQ,
208  ObjectIdGetDatum(objectId));
209 
210  scan = systable_beginscan(depRel, DependDependerIndexId, true,
211  NULL, 2, key);
212 
213  while (HeapTupleIsValid(tup = systable_getnext(scan)))
214  {
215  if (skipExtensionDeps &&
216  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
217  continue;
218 
219  CatalogTupleDelete(depRel, &tup->t_self);
220  count++;
221  }
222 
223  systable_endscan(scan);
224 
225  table_close(depRel, RowExclusiveLock);
226 
227  return count;
228 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
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 HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteDependencyRecordsForClass()

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

Definition at line 240 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, GETSTRUCT, HeapTupleIsValid, sort-test::key, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

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

242 {
243  long count = 0;
244  Relation depRel;
245  ScanKeyData key[2];
246  SysScanDesc scan;
247  HeapTuple tup;
248 
249  depRel = table_open(DependRelationId, RowExclusiveLock);
250 
251  ScanKeyInit(&key[0],
252  Anum_pg_depend_classid,
253  BTEqualStrategyNumber, F_OIDEQ,
254  ObjectIdGetDatum(classId));
255  ScanKeyInit(&key[1],
256  Anum_pg_depend_objid,
257  BTEqualStrategyNumber, F_OIDEQ,
258  ObjectIdGetDatum(objectId));
259 
260  scan = systable_beginscan(depRel, DependDependerIndexId, true,
261  NULL, 2, key);
262 
263  while (HeapTupleIsValid(tup = systable_getnext(scan)))
264  {
265  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
266 
267  if (depform->refclassid == refclassId && depform->deptype == deptype)
268  {
269  CatalogTupleDelete(depRel, &tup->t_self);
270  count++;
271  }
272  }
273 
274  systable_endscan(scan);
275 
276  table_close(depRel, RowExclusiveLock);
277 
278  return count;
279 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
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 HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteDependencyRecordsForSpecific()

long deleteDependencyRecordsForSpecific ( Oid  classId,
Oid  objectId,
char  deptype,
Oid  refclassId,
Oid  refobjectId 
)

Definition at line 287 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, GETSTRUCT, HeapTupleIsValid, sort-test::key, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by ExecAlterObjectDependsStmt().

289 {
290  long count = 0;
291  Relation depRel;
292  ScanKeyData key[2];
293  SysScanDesc scan;
294  HeapTuple tup;
295 
296  depRel = table_open(DependRelationId, RowExclusiveLock);
297 
298  ScanKeyInit(&key[0],
299  Anum_pg_depend_classid,
300  BTEqualStrategyNumber, F_OIDEQ,
301  ObjectIdGetDatum(classId));
302  ScanKeyInit(&key[1],
303  Anum_pg_depend_objid,
304  BTEqualStrategyNumber, F_OIDEQ,
305  ObjectIdGetDatum(objectId));
306 
307  scan = systable_beginscan(depRel, DependDependerIndexId, true,
308  NULL, 2, key);
309 
310  while (HeapTupleIsValid(tup = systable_getnext(scan)))
311  {
312  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
313 
314  if (depform->refclassid == refclassId &&
315  depform->refobjid == refobjectId &&
316  depform->deptype == deptype)
317  {
318  CatalogTupleDelete(depRel, &tup->t_self);
319  count++;
320  }
321  }
322 
323  systable_endscan(scan);
324 
325  table_close(depRel, RowExclusiveLock);
326 
327  return count;
328 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
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 HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteSharedDependencyRecordsFor()

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

Definition at line 907 of file pg_shdepend.c.

References InvalidOid, RowExclusiveLock, SHARED_DEPENDENCY_INVALID, shdepDropDependency(), table_close(), and table_open().

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

908 {
909  Relation sdepRel;
910 
911  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
912 
913  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
914  (objectSubId == 0),
917 
918  table_close(sdepRel, RowExclusiveLock);
919 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define RowExclusiveLock
Definition: lockdefs.h:38
#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:984
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

Definition at line 859 of file pg_shdepend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), HeapTupleIsValid, InvalidOid, sort-test::key, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_INVALID, SharedDependDependerIndexId, shdepDropDependency(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by dropdb().

860 {
861  Relation sdepRel;
862  ScanKeyData key[1];
863  SysScanDesc scan;
864  HeapTuple tup;
865 
866  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
867 
868  /*
869  * First, delete all the entries that have the database Oid in the dbid
870  * field.
871  */
872  ScanKeyInit(&key[0],
873  Anum_pg_shdepend_dbid,
874  BTEqualStrategyNumber, F_OIDEQ,
875  ObjectIdGetDatum(databaseId));
876  /* We leave the other index fields unspecified */
877 
878  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
879  NULL, 1, key);
880 
881  while (HeapTupleIsValid(tup = systable_getnext(scan)))
882  {
883  CatalogTupleDelete(sdepRel, &tup->t_self);
884  }
885 
886  systable_endscan(scan);
887 
888  /* Now delete all entries corresponding to the database itself */
889  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
892 
893  table_close(sdepRel, RowExclusiveLock);
894 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define SharedDependDependerIndexId
Definition: indexing.h:223
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#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:984
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ free_object_addresses()

◆ get_constraint_index()

Oid get_constraint_index ( Oid  constraintId)

Definition at line 898 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_INTERNAL, DependReferenceIndexId, get_rel_relkind(), GETSTRUCT, HeapTupleIsValid, Int32GetDatum, InvalidOid, sort-test::key, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

899 {
900  Oid indexId = InvalidOid;
901  Relation depRel;
902  ScanKeyData key[3];
903  SysScanDesc scan;
904  HeapTuple tup;
905 
906  /* Search the dependency table for the dependent index */
907  depRel = table_open(DependRelationId, AccessShareLock);
908 
909  ScanKeyInit(&key[0],
910  Anum_pg_depend_refclassid,
911  BTEqualStrategyNumber, F_OIDEQ,
912  ObjectIdGetDatum(ConstraintRelationId));
913  ScanKeyInit(&key[1],
914  Anum_pg_depend_refobjid,
915  BTEqualStrategyNumber, F_OIDEQ,
916  ObjectIdGetDatum(constraintId));
917  ScanKeyInit(&key[2],
918  Anum_pg_depend_refobjsubid,
919  BTEqualStrategyNumber, F_INT4EQ,
920  Int32GetDatum(0));
921 
922  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
923  NULL, 3, key);
924 
925  while (HeapTupleIsValid(tup = systable_getnext(scan)))
926  {
927  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
928 
929  /*
930  * We assume any internal dependency of an index on the constraint
931  * must be what we are looking for.
932  */
933  if (deprec->classid == RelationRelationId &&
934  deprec->objsubid == 0 &&
935  deprec->deptype == DEPENDENCY_INTERNAL)
936  {
937  char relkind = get_rel_relkind(deprec->objid);
938 
939  /*
940  * This is pure paranoia; there shouldn't be any other relkinds
941  * dependent on a constraint.
942  */
943  if (relkind != RELKIND_INDEX &&
944  relkind != RELKIND_PARTITIONED_INDEX)
945  continue;
946 
947  indexId = deprec->objid;
948  break;
949  }
950  }
951 
952  systable_endscan(scan);
953  table_close(depRel, AccessShareLock);
954 
955  return indexId;
956 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1915
#define DependReferenceIndexId
Definition: indexing.h:151
#define AccessShareLock
Definition: lockdefs.h:36
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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 965 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_INTERNAL, GETSTRUCT, HeapTupleIsValid, Int32GetDatum, InvalidOid, sort-test::key, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

966 {
967  Oid constraintId = InvalidOid;
968  Relation depRel;
969  ScanKeyData key[3];
970  SysScanDesc scan;
971  HeapTuple tup;
972 
973  /* Search the dependency table for the index */
974  depRel = table_open(DependRelationId, AccessShareLock);
975 
976  ScanKeyInit(&key[0],
977  Anum_pg_depend_classid,
978  BTEqualStrategyNumber, F_OIDEQ,
979  ObjectIdGetDatum(RelationRelationId));
980  ScanKeyInit(&key[1],
981  Anum_pg_depend_objid,
982  BTEqualStrategyNumber, F_OIDEQ,
983  ObjectIdGetDatum(indexId));
984  ScanKeyInit(&key[2],
985  Anum_pg_depend_objsubid,
986  BTEqualStrategyNumber, F_INT4EQ,
987  Int32GetDatum(0));
988 
989  scan = systable_beginscan(depRel, DependDependerIndexId, true,
990  NULL, 3, key);
991 
992  while (HeapTupleIsValid(tup = systable_getnext(scan)))
993  {
994  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
995 
996  /*
997  * We assume any internal dependency on a constraint must be what we
998  * are looking for.
999  */
1000  if (deprec->refclassid == ConstraintRelationId &&
1001  deprec->refobjsubid == 0 &&
1002  deprec->deptype == DEPENDENCY_INTERNAL)
1003  {
1004  constraintId = deprec->refobjid;
1005  break;
1006  }
1007  }
1008 
1009  systable_endscan(scan);
1010  table_close(depRel, AccessShareLock);
1011 
1012  return constraintId;
1013 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_index_ref_constraints()

List* get_index_ref_constraints ( Oid  indexId)

Definition at line 1021 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_NORMAL, DependReferenceIndexId, GETSTRUCT, HeapTupleIsValid, Int32GetDatum, sort-test::key, lappend_oid(), NIL, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by index_concurrently_swap().

1022 {
1023  List *result = NIL;
1024  Relation depRel;
1025  ScanKeyData key[3];
1026  SysScanDesc scan;
1027  HeapTuple tup;
1028 
1029  /* Search the dependency table for the index */
1030  depRel = table_open(DependRelationId, AccessShareLock);
1031 
1032  ScanKeyInit(&key[0],
1033  Anum_pg_depend_refclassid,
1034  BTEqualStrategyNumber, F_OIDEQ,
1035  ObjectIdGetDatum(RelationRelationId));
1036  ScanKeyInit(&key[1],
1037  Anum_pg_depend_refobjid,
1038  BTEqualStrategyNumber, F_OIDEQ,
1039  ObjectIdGetDatum(indexId));
1040  ScanKeyInit(&key[2],
1041  Anum_pg_depend_refobjsubid,
1042  BTEqualStrategyNumber, F_INT4EQ,
1043  Int32GetDatum(0));
1044 
1045  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
1046  NULL, 3, key);
1047 
1048  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1049  {
1050  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1051 
1052  /*
1053  * We assume any normal dependency from a constraint must be what we
1054  * are looking for.
1055  */
1056  if (deprec->classid == ConstraintRelationId &&
1057  deprec->objsubid == 0 &&
1058  deprec->deptype == DEPENDENCY_NORMAL)
1059  {
1060  result = lappend_oid(result, deprec->objid);
1061  }
1062  }
1063 
1064  systable_endscan(scan);
1065  table_close(depRel, AccessShareLock);
1066 
1067  return result;
1068 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependReferenceIndexId
Definition: indexing.h:151
#define AccessShareLock
Definition: lockdefs.h:36
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getAutoExtensionsOfObject()

List* getAutoExtensionsOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 705 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_AUTO_EXTENSION, GETSTRUCT, HeapTupleIsValid, sort-test::key, lappend_oid(), NIL, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ExecAlterObjectDependsStmt().

706 {
707  List *result = NIL;
708  Relation depRel;
709  ScanKeyData key[2];
710  SysScanDesc scan;
711  HeapTuple tup;
712 
713  depRel = table_open(DependRelationId, AccessShareLock);
714 
715  ScanKeyInit(&key[0],
716  Anum_pg_depend_classid,
717  BTEqualStrategyNumber, F_OIDEQ,
718  ObjectIdGetDatum(classId));
719  ScanKeyInit(&key[1],
720  Anum_pg_depend_objid,
721  BTEqualStrategyNumber, F_OIDEQ,
722  ObjectIdGetDatum(objectId));
723 
724  scan = systable_beginscan(depRel, DependDependerIndexId, true,
725  NULL, 2, key);
726 
727  while (HeapTupleIsValid((tup = systable_getnext(scan))))
728  {
729  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
730 
731  if (depform->refclassid == ExtensionRelationId &&
732  depform->deptype == DEPENDENCY_AUTO_EXTENSION)
733  result = lappend_oid(result, depform->refobjid);
734  }
735 
736  systable_endscan(scan);
737 
738  table_close(depRel, AccessShareLock);
739 
740  return result;
741 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getExtensionOfObject()

Oid getExtensionOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 659 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_EXTENSION, GETSTRUCT, HeapTupleIsValid, InvalidOid, sort-test::key, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

660 {
661  Oid result = InvalidOid;
662  Relation depRel;
663  ScanKeyData key[2];
664  SysScanDesc scan;
665  HeapTuple tup;
666 
667  depRel = table_open(DependRelationId, AccessShareLock);
668 
669  ScanKeyInit(&key[0],
670  Anum_pg_depend_classid,
671  BTEqualStrategyNumber, F_OIDEQ,
672  ObjectIdGetDatum(classId));
673  ScanKeyInit(&key[1],
674  Anum_pg_depend_objid,
675  BTEqualStrategyNumber, F_OIDEQ,
676  ObjectIdGetDatum(objectId));
677 
678  scan = systable_beginscan(depRel, DependDependerIndexId, true,
679  NULL, 2, key);
680 
681  while (HeapTupleIsValid((tup = systable_getnext(scan))))
682  {
683  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
684 
685  if (depform->refclassid == ExtensionRelationId &&
686  depform->deptype == DEPENDENCY_EXTENSION)
687  {
688  result = depform->refobjid;
689  break; /* no need to keep scanning */
690  }
691  }
692 
693  systable_endscan(scan);
694 
695  table_close(depRel, AccessShareLock);
696 
697  return result;
698 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#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
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getIdentitySequence()

Oid getIdentitySequence ( Oid  relid,
AttrNumber  attnum,
bool  missing_ok 
)

Definition at line 872 of file pg_depend.c.

References DEPENDENCY_INTERNAL, elog, ERROR, getOwnedSequences_internal(), InvalidOid, linitial_oid, and list_length().

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

873 {
875 
876  if (list_length(seqlist) > 1)
877  elog(ERROR, "more than one owned sequence found");
878  else if (list_length(seqlist) < 1)
879  {
880  if (missing_ok)
881  return InvalidOid;
882  else
883  elog(ERROR, "no owned sequence found");
884  }
885 
886  return linitial_oid(seqlist);
887 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:804
#define ERROR
Definition: elog.h:43
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:79
#define linitial_oid(l)
Definition: pg_list.h:197
static int list_length(const List *l)
Definition: pg_list.h:169
#define elog(elevel,...)
Definition: elog.h:214
Definition: pg_list.h:50

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

Definition at line 2720 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().

2721 {
2722  /* only pg_class entries can have nonzero objectSubId */
2723  if (object->classId != RelationRelationId &&
2724  object->objectSubId != 0)
2725  elog(ERROR, "invalid non-zero objectSubId for object class %u",
2726  object->classId);
2727 
2728  switch (object->classId)
2729  {
2730  case RelationRelationId:
2731  /* caller must check objectSubId */
2732  return OCLASS_CLASS;
2733 
2734  case ProcedureRelationId:
2735  return OCLASS_PROC;
2736 
2737  case TypeRelationId:
2738  return OCLASS_TYPE;
2739 
2740  case CastRelationId:
2741  return OCLASS_CAST;
2742 
2743  case CollationRelationId:
2744  return OCLASS_COLLATION;
2745 
2746  case ConstraintRelationId:
2747  return OCLASS_CONSTRAINT;
2748 
2749  case ConversionRelationId:
2750  return OCLASS_CONVERSION;
2751 
2752  case AttrDefaultRelationId:
2753  return OCLASS_DEFAULT;
2754 
2755  case LanguageRelationId:
2756  return OCLASS_LANGUAGE;
2757 
2758  case LargeObjectRelationId:
2759  return OCLASS_LARGEOBJECT;
2760 
2761  case OperatorRelationId:
2762  return OCLASS_OPERATOR;
2763 
2764  case OperatorClassRelationId:
2765  return OCLASS_OPCLASS;
2766 
2767  case OperatorFamilyRelationId:
2768  return OCLASS_OPFAMILY;
2769 
2770  case AccessMethodRelationId:
2771  return OCLASS_AM;
2772 
2773  case AccessMethodOperatorRelationId:
2774  return OCLASS_AMOP;
2775 
2776  case AccessMethodProcedureRelationId:
2777  return OCLASS_AMPROC;
2778 
2779  case RewriteRelationId:
2780  return OCLASS_REWRITE;
2781 
2782  case TriggerRelationId:
2783  return OCLASS_TRIGGER;
2784 
2785  case NamespaceRelationId:
2786  return OCLASS_SCHEMA;
2787 
2788  case StatisticExtRelationId:
2789  return OCLASS_STATISTIC_EXT;
2790 
2791  case TSParserRelationId:
2792  return OCLASS_TSPARSER;
2793 
2794  case TSDictionaryRelationId:
2795  return OCLASS_TSDICT;
2796 
2797  case TSTemplateRelationId:
2798  return OCLASS_TSTEMPLATE;
2799 
2800  case TSConfigRelationId:
2801  return OCLASS_TSCONFIG;
2802 
2803  case AuthIdRelationId:
2804  return OCLASS_ROLE;
2805 
2806  case DatabaseRelationId:
2807  return OCLASS_DATABASE;
2808 
2809  case TableSpaceRelationId:
2810  return OCLASS_TBLSPACE;
2811 
2812  case ForeignDataWrapperRelationId:
2813  return OCLASS_FDW;
2814 
2815  case ForeignServerRelationId:
2816  return OCLASS_FOREIGN_SERVER;
2817 
2818  case UserMappingRelationId:
2819  return OCLASS_USER_MAPPING;
2820 
2821  case DefaultAclRelationId:
2822  return OCLASS_DEFACL;
2823 
2824  case ExtensionRelationId:
2825  return OCLASS_EXTENSION;
2826 
2827  case EventTriggerRelationId:
2828  return OCLASS_EVENT_TRIGGER;
2829 
2830  case PolicyRelationId:
2831  return OCLASS_POLICY;
2832 
2833  case PublicationRelationId:
2834  return OCLASS_PUBLICATION;
2835 
2836  case PublicationRelRelationId:
2837  return OCLASS_PUBLICATION_REL;
2838 
2839  case SubscriptionRelationId:
2840  return OCLASS_SUBSCRIPTION;
2841 
2842  case TransformRelationId:
2843  return OCLASS_TRANSFORM;
2844  }
2845 
2846  /* shouldn't get here */
2847  elog(ERROR, "unrecognized object class: %u", object->classId);
2848  return OCLASS_CLASS; /* keep compiler quiet */
2849 }
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:214

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 863 of file pg_depend.c.

References getOwnedSequences_internal().

Referenced by ExecuteTruncateGuts().

864 {
865  return getOwnedSequences_internal(relid, 0, 0);
866 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:804

◆ new_object_addresses()

◆ object_address_present()

bool object_address_present ( const ObjectAddress object,
const ObjectAddresses addrs 
)

Definition at line 2525 of file dependency.c.

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

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

2527 {
2528  int i;
2529 
2530  for (i = addrs->numrefs - 1; i >= 0; i--)
2531  {
2532  const ObjectAddress *thisobj = addrs->refs + i;
2533 
2534  if (object->classId == thisobj->classId &&
2535  object->objectId == thisobj->objectId)
2536  {
2537  if (object->objectSubId == thisobj->objectSubId ||
2538  thisobj->objectSubId == 0)
2539  return true;
2540  }
2541  }
2542 
2543  return false;
2544 }
ObjectAddress * refs
Definition: dependency.c:111
int i

◆ performDeletion()

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

Definition at line 312 of file dependency.c.

References AcquireDeletionLock(), deleteObjectsInList(), DEPFLAG_ORIGINAL, findDependentObjects(), free_object_addresses(), new_object_addresses(), reportDependentObjects(), RowExclusiveLock, table_close(), and table_open().

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

314 {
315  Relation depRel;
316  ObjectAddresses *targetObjects;
317 
318  /*
319  * We save some cycles by opening pg_depend just once and passing the
320  * Relation pointer down to all the recursive deletion steps.
321  */
322  depRel = table_open(DependRelationId, RowExclusiveLock);
323 
324  /*
325  * Acquire deletion lock on the target object. (Ideally the caller has
326  * done this already, but many places are sloppy about it.)
327  */
328  AcquireDeletionLock(object, 0);
329 
330  /*
331  * Construct a list of objects to delete (ie, the given object plus
332  * everything directly or indirectly dependent on it).
333  */
334  targetObjects = new_object_addresses();
335 
336  findDependentObjects(object,
338  flags,
339  NULL, /* empty stack */
340  targetObjects,
341  NULL, /* no pendingObjects */
342  &depRel);
343 
344  /*
345  * Check if deletion is allowed, and report about cascaded deletes.
346  */
347  reportDependentObjects(targetObjects,
348  behavior,
349  flags,
350  object);
351 
352  /* do the deed */
353  deleteObjectsInList(targetObjects, &depRel, flags);
354 
355  /* And clean up */
356  free_object_addresses(targetObjects);
357 
358  table_close(depRel, RowExclusiveLock);
359 }
static void findDependentObjects(const ObjectAddress *object, int objflags, int flags, ObjectAddressStack *stack, ObjectAddresses *targetObjects, const ObjectAddresses *pendingObjects, Relation *depRel)
Definition: dependency.c:471
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2410
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2705
#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:1024
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1528
static void deleteObjectsInList(ObjectAddresses *targetObjects, Relation *depRel, int flags)
Definition: dependency.c:224
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ performMultipleDeletions()

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

Definition at line 371 of file dependency.c.

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

Referenced by ATExecDropColumn(), ATPostAlterTypeCleanup(), DropClonedTriggersFromPartition(), PreCommit_on_commit_actions(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

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

◆ record_object_address_dependencies()

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

Definition at line 2674 of file dependency.c.

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

Referenced by InsertExtensionTuple(), and makeConfigurationDependencies().

2677 {
2679  recordMultipleDependencies(depender,
2680  referenced->refs, referenced->numrefs,
2681  behavior);
2682 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2306
ObjectAddress * refs
Definition: dependency.c:111
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:55

◆ recordDependencyOn()

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

Definition at line 43 of file pg_depend.c.

References recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), addFkRecurseReferenced(), addFkRecurseReferencing(), AddNewAttributeTuples(), AggregateCreate(), AlterForeignDataWrapper(), AlterFunction(), AlterPolicy(), ApplyExtensionUpdates(), ATExecAddOf(), CastCreate(), changeDependencyFor(), CloneFkReferencing(), CollationCreate(), ConstraintSetParentConstraint(), ConversionCreate(), create_toast_table(), CreateAccessMethod(), CreateConstraintEntry(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreateProceduralLanguage(), CreateStatistics(), CreateTransform(), CreateTrigger(), CreateUserMapping(), DefineOpClass(), ExecAlterExtensionContentsStmt(), ExecAlterObjectDependsStmt(), GenerateTypeDependencies(), heap_create_with_catalog(), index_constraint_create(), index_create(), IndexSetParentIndex(), insert_event_trigger_tuple(), InsertRule(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeRangeConstructors(), makeTSTemplateDependencies(), ProcedureCreate(), process_owned_by(), publication_add_relation(), RangeCreate(), recordDependencyOnCurrentExtension(), recordDependencyOnSingleRelExpr(), RemoveRoleFromObjectPolicy(), SetDefaultACL(), StoreAttrDefault(), StoreCatalogInheritance1(), storeOperators(), StorePartitionKey(), storeProcedures(), and swap_relation_files().

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

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

Definition at line 138 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 CastCreate(), CollationCreate(), ConversionCreate(), CreateAccessMethod(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreateProceduralLanguage(), CreateTransform(), DefineOpClass(), GenerateTypeDependencies(), heap_create_with_catalog(), insert_event_trigger_tuple(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeTSTemplateDependencies(), NamespaceCreate(), and ProcedureCreate().

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

◆ recordDependencyOnExpr()

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

Definition at line 1582 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(), and RemoveRoleFromObjectPolicy().

1585 {
1587 
1588  context.addrs = new_object_addresses();
1589 
1590  /* Set up interpretation for Vars at varlevelsup = 0 */
1591  context.rtables = list_make1(rtable);
1592 
1593  /* Scan the expression tree for referenceable objects */
1594  find_expr_references_walker(expr, &context);
1595 
1596  /* Remove any duplicates */
1598 
1599  /* And record 'em */
1600  recordMultipleDependencies(depender,
1601  context.addrs->refs, context.addrs->numrefs,
1602  behavior);
1603 
1604  free_object_addresses(context.addrs);
1605 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1728
ObjectAddresses * addrs
Definition: dependency.c:137
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2410
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2705
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2306
#define list_make1(x1)
Definition: pg_list.h:227
ObjectAddress * refs
Definition: dependency.c:111
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:55

◆ recordDependencyOnOwner()

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

Definition at line 164 of file pg_shdepend.c.

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

Referenced by CollationCreate(), ConversionCreate(), createdb(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), CreateProceduralLanguage(), 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().

165 {
166  ObjectAddress myself,
167  referenced;
168 
169  myself.classId = classId;
170  myself.objectId = objectId;
171  myself.objectSubId = 0;
172 
173  referenced.classId = AuthIdRelationId;
174  referenced.objectId = owner;
175  referenced.objectSubId = 0;
176 
177  recordSharedDependencyOn(&myself, &referenced, SHARED_DEPENDENCY_OWNER);
178 }
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:120

◆ recordDependencyOnSingleRelExpr()

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

Definition at line 1625 of file dependency.c.

References AccessShareLock, 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, recordDependencyOn(), recordMultipleDependencies(), ObjectAddresses::refs, RangeTblEntry::relid, RangeTblEntry::relkind, RangeTblEntry::rellockmode, find_expr_references_context::rtables, RTE_RELATION, RangeTblEntry::rtekind, T_RangeTblEntry, and RangeTblEntry::type.

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

1630 {
1632  RangeTblEntry rte;
1633 
1634  context.addrs = new_object_addresses();
1635 
1636  /* We gin up a rather bogus rangetable list to handle Vars */
1637  MemSet(&rte, 0, sizeof(rte));
1638  rte.type = T_RangeTblEntry;
1639  rte.rtekind = RTE_RELATION;
1640  rte.relid = relId;
1641  rte.relkind = RELKIND_RELATION; /* no need for exactness here */
1643 
1644  context.rtables = list_make1(list_make1(&rte));
1645 
1646  /* Scan the expression tree for referenceable objects */
1647  find_expr_references_walker(expr, &context);
1648 
1649  /* Remove any duplicates */
1651 
1652  /* Separate self-dependencies if necessary */
1653  if ((behavior != self_behavior || reverse_self) &&
1654  context.addrs->numrefs > 0)
1655  {
1656  ObjectAddresses *self_addrs;
1657  ObjectAddress *outobj;
1658  int oldref,
1659  outrefs;
1660 
1661  self_addrs = new_object_addresses();
1662 
1663  outobj = context.addrs->refs;
1664  outrefs = 0;
1665  for (oldref = 0; oldref < context.addrs->numrefs; oldref++)
1666  {
1667  ObjectAddress *thisobj = context.addrs->refs + oldref;
1668 
1669  if (thisobj->classId == RelationRelationId &&
1670  thisobj->objectId == relId)
1671  {
1672  /* Move this ref into self_addrs */
1673  add_exact_object_address(thisobj, self_addrs);
1674  }
1675  else
1676  {
1677  /* Keep it in context.addrs */
1678  *outobj = *thisobj;
1679  outobj++;
1680  outrefs++;
1681  }
1682  }
1683  context.addrs->numrefs = outrefs;
1684 
1685  /* Record the self-dependencies with the appropriate direction */
1686  if (!reverse_self)
1687  recordMultipleDependencies(depender,
1688  self_addrs->refs, self_addrs->numrefs,
1689  self_behavior);
1690  else
1691  {
1692  /* Can't use recordMultipleDependencies, so do it the hard way */
1693  int selfref;
1694 
1695  for (selfref = 0; selfref < self_addrs->numrefs; selfref++)
1696  {
1697  ObjectAddress *thisobj = self_addrs->refs + selfref;
1698 
1699  recordDependencyOn(thisobj, depender, self_behavior);
1700  }
1701  }
1702 
1703  free_object_addresses(self_addrs);
1704  }
1705 
1706  /* Record the external dependencies */
1707  recordMultipleDependencies(depender,
1708  context.addrs->refs, context.addrs->numrefs,
1709  behavior);
1710 
1711  free_object_addresses(context.addrs);
1712 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1728
ObjectAddresses * addrs
Definition: dependency.c:137
#define AccessShareLock
Definition: lockdefs.h:36
#define MemSet(start, val, len)
Definition: c.h:971
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2465
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2410
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2705
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2306
#define list_make1(x1)
Definition: pg_list.h:227
ObjectAddress * refs
Definition: dependency.c:111
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:55
RTEKind rtekind
Definition: parsenodes.h:976
NodeTag type
Definition: parsenodes.h:974

◆ recordMultipleDependencies()

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

Definition at line 55 of file pg_depend.c.

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

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

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

◆ recordSharedDependencyOn()

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

Definition at line 120 of file pg_shdepend.c.

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

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

123 {
124  Relation sdepRel;
125 
126  /*
127  * Objects in pg_shdepend can't have SubIds.
128  */
129  Assert(depender->objectSubId == 0);
130  Assert(referenced->objectSubId == 0);
131 
132  /*
133  * During bootstrap, do nothing since pg_shdepend may not exist yet.
134  * initdb will fill in appropriate pg_shdepend entries after bootstrap.
135  */
137  return;
138 
139  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
140 
141  /* If the referenced object is pinned, do nothing. */
142  if (!isSharedObjectPinned(referenced->classId, referenced->objectId,
143  sdepRel))
144  {
145  shdepAddDependency(sdepRel, depender->classId, depender->objectId,
146  depender->objectSubId,
147  referenced->classId, referenced->objectId,
148  deptype);
149  }
150 
151  table_close(sdepRel, RowExclusiveLock);
152 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1195
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:929
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Assert(condition)
Definition: c.h:738
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:392
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ ReleaseDeletionLock()

void ReleaseDeletionLock ( const ObjectAddress object)

Definition at line 1557 of file dependency.c.

References AccessExclusiveLock, ObjectAddress::classId, ObjectAddress::objectId, UnlockDatabaseObject(), and UnlockRelationOid().

Referenced by findDependentObjects(), and shdepDropOwned().

1558 {
1559  if (object->classId == RelationRelationId)
1561  else
1562  /* assume we should lock the whole object not a sub-object */
1563  UnlockDatabaseObject(object->classId, object->objectId, 0,
1565 }
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:199
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:982
#define AccessExclusiveLock
Definition: lockdefs.h:45

◆ sequenceIsOwned()

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

Definition at line 755 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, GETSTRUCT, HeapTupleIsValid, sort-test::key, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

756 {
757  bool ret = false;
758  Relation depRel;
759  ScanKeyData key[2];
760  SysScanDesc scan;
761  HeapTuple tup;
762 
763  depRel = table_open(DependRelationId, AccessShareLock);
764 
765  ScanKeyInit(&key[0],
766  Anum_pg_depend_classid,
767  BTEqualStrategyNumber, F_OIDEQ,
768  ObjectIdGetDatum(RelationRelationId));
769  ScanKeyInit(&key[1],
770  Anum_pg_depend_objid,
771  BTEqualStrategyNumber, F_OIDEQ,
772  ObjectIdGetDatum(seqId));
773 
774  scan = systable_beginscan(depRel, DependDependerIndexId, true,
775  NULL, 2, key);
776 
777  while (HeapTupleIsValid((tup = systable_getnext(scan))))
778  {
779  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
780 
781  if (depform->refclassid == RelationRelationId &&
782  depform->deptype == deptype)
783  {
784  *tableId = depform->refobjid;
785  *colId = depform->refobjsubid;
786  ret = true;
787  break; /* no need to keep scanning */
788  }
789  }
790 
791  systable_endscan(scan);
792 
793  table_close(depRel, AccessShareLock);
794 
795  return ret;
796 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ shdepDropOwned()

void shdepDropOwned ( List relids,
DropBehavior  behavior 
)

Definition at line 1247 of file pg_shdepend.c.

References AcquireDeletionLock(), add_exact_object_address(), BTEqualStrategyNumber, ObjectAddress::classId, elog, ereport, errcode(), errmsg(), ERROR, free_object_addresses(), getObjectDescription(), GETSTRUCT, InvalidOid, isSharedObjectPinned(), sort-test::key, lfirst_oid, MyDatabaseId, new_object_addresses(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, performMultipleDeletions(), ReleaseDeletionLock(), RemoveRoleFromObjectACL(), RemoveRoleFromObjectPolicy(), RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_ACL, SHARED_DEPENDENCY_INVALID, SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_PIN, SHARED_DEPENDENCY_POLICY, SharedDependReferenceIndexId, sort_object_addresses(), systable_beginscan(), systable_endscan(), systable_getnext(), systable_recheck_tuple(), table_close(), and table_open().

Referenced by DropOwnedObjects().

1248 {
1249  Relation sdepRel;
1250  ListCell *cell;
1251  ObjectAddresses *deleteobjs;
1252 
1253  deleteobjs = new_object_addresses();
1254 
1255  /*
1256  * We don't need this strong a lock here, but we'll call routines that
1257  * acquire RowExclusiveLock. Better get that right now to avoid potential
1258  * deadlock failures.
1259  */
1260  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1261 
1262  /*
1263  * For each role, find the dependent objects and drop them using the
1264  * regular (non-shared) dependency management.
1265  */
1266  foreach(cell, roleids)
1267  {
1268  Oid roleid = lfirst_oid(cell);
1269  ScanKeyData key[2];
1270  SysScanDesc scan;
1271  HeapTuple tuple;
1272 
1273  /* Doesn't work for pinned objects */
1274  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1275  {
1276  ObjectAddress obj;
1277 
1278  obj.classId = AuthIdRelationId;
1279  obj.objectId = roleid;
1280  obj.objectSubId = 0;
1281 
1282  ereport(ERROR,
1283  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1284  errmsg("cannot drop objects owned by %s because they are "
1285  "required by the database system",
1286  getObjectDescription(&obj))));
1287  }
1288 
1289  ScanKeyInit(&key[0],
1290  Anum_pg_shdepend_refclassid,
1291  BTEqualStrategyNumber, F_OIDEQ,
1292  ObjectIdGetDatum(AuthIdRelationId));
1293  ScanKeyInit(&key[1],
1294  Anum_pg_shdepend_refobjid,
1295  BTEqualStrategyNumber, F_OIDEQ,
1296  ObjectIdGetDatum(roleid));
1297 
1298  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1299  NULL, 2, key);
1300 
1301  while ((tuple = systable_getnext(scan)) != NULL)
1302  {
1303  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1304  ObjectAddress obj;
1305 
1306  /*
1307  * We only operate on shared objects and objects in the current
1308  * database
1309  */
1310  if (sdepForm->dbid != MyDatabaseId &&
1311  sdepForm->dbid != InvalidOid)
1312  continue;
1313 
1314  switch (sdepForm->deptype)
1315  {
1316  /* Shouldn't happen */
1317  case SHARED_DEPENDENCY_PIN:
1319  elog(ERROR, "unexpected dependency type");
1320  break;
1321  case SHARED_DEPENDENCY_ACL:
1322  RemoveRoleFromObjectACL(roleid,
1323  sdepForm->classid,
1324  sdepForm->objid);
1325  break;
1327 
1328  /*
1329  * Try to remove role from policy; if unable to, remove
1330  * policy.
1331  */
1332  if (!RemoveRoleFromObjectPolicy(roleid,
1333  sdepForm->classid,
1334  sdepForm->objid))
1335  {
1336  obj.classId = sdepForm->classid;
1337  obj.objectId = sdepForm->objid;
1338  obj.objectSubId = sdepForm->objsubid;
1339 
1340  /*
1341  * Acquire lock on object, then verify this dependency
1342  * is still relevant. If not, the object might have
1343  * been dropped or the policy modified. Ignore the
1344  * object in that case.
1345  */
1346  AcquireDeletionLock(&obj, 0);
1347  if (!systable_recheck_tuple(scan, tuple))
1348  {
1349  ReleaseDeletionLock(&obj);
1350  break;
1351  }
1352  add_exact_object_address(&obj, deleteobjs);
1353  }
1354  break;
1356  /* If a local object, save it for deletion below */
1357  if (sdepForm->dbid == MyDatabaseId)
1358  {
1359  obj.classId = sdepForm->classid;
1360  obj.objectId = sdepForm->objid;
1361  obj.objectSubId = sdepForm->objsubid;
1362  /* as above */
1363  AcquireDeletionLock(&obj, 0);
1364  if (!systable_recheck_tuple(scan, tuple))
1365  {
1366  ReleaseDeletionLock(&obj);
1367  break;
1368  }
1369  add_exact_object_address(&obj, deleteobjs);
1370  }
1371  break;
1372  }
1373  }
1374 
1375  systable_endscan(scan);
1376  }
1377 
1378  /*
1379  * For stability of deletion-report ordering, sort the objects into
1380  * approximate reverse creation order before deletion. (This might also
1381  * make the deletion go a bit faster, since there's less chance of having
1382  * to rearrange the objects due to dependencies.)
1383  */
1384  sort_object_addresses(deleteobjs);
1385 
1386  /* the dependency mechanism does the actual work */
1387  performMultipleDeletions(deleteobjs, behavior, 0);
1388 
1389  table_close(sdepRel, RowExclusiveLock);
1390 
1391  free_object_addresses(deleteobjs);
1392 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1195
void sort_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2693
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
void ReleaseDeletionLock(const ObjectAddress *object)
Definition: dependency.c:1557
int errcode(int sqlerrcode)
Definition: elog.c:610
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2465
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition: aclchk.c:1377
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2410
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2705
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:356
char * getObjectDescription(const ObjectAddress *object)
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Definition: genam.c:501
bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
Definition: policy.c:439
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define RowExclusiveLock
Definition: lockdefs.h:38
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1528
Oid MyDatabaseId
Definition: globals.c:85
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
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:371
#define SharedDependReferenceIndexId
Definition: indexing.h:225
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ shdepLockAndCheckObject()

void shdepLockAndCheckObject ( Oid  classId,
Oid  objectId 
)

Definition at line 1071 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().

1072 {
1073  /* AccessShareLock should be OK, since we are not modifying the object */
1074  LockSharedObject(classId, objectId, 0, AccessShareLock);
1075 
1076  switch (classId)
1077  {
1078  case AuthIdRelationId:
1080  ereport(ERROR,
1081  (errcode(ERRCODE_UNDEFINED_OBJECT),
1082  errmsg("role %u was concurrently dropped",
1083  objectId)));
1084  break;
1085 
1086  /*
1087  * Currently, this routine need not support any other shared
1088  * object types besides roles. If we wanted to record explicit
1089  * dependencies on databases or tablespaces, we'd need code along
1090  * these lines:
1091  */
1092 #ifdef NOT_USED
1093  case TableSpaceRelationId:
1094  {
1095  /* For lack of a syscache on pg_tablespace, do this: */
1096  char *tablespace = get_tablespace_name(objectId);
1097 
1098  if (tablespace == NULL)
1099  ereport(ERROR,
1100  (errcode(ERRCODE_UNDEFINED_OBJECT),
1101  errmsg("tablespace %u was concurrently dropped",
1102  objectId)));
1103  pfree(tablespace);
1104  break;
1105  }
1106 #endif
1107 
1108  case DatabaseRelationId:
1109  {
1110  /* For lack of a syscache on pg_database, do this: */
1111  char *database = get_database_name(objectId);
1112 
1113  if (database == NULL)
1114  ereport(ERROR,
1115  (errcode(ERRCODE_UNDEFINED_OBJECT),
1116  errmsg("database %u was concurrently dropped",
1117  objectId)));
1118  pfree(database);
1119  break;
1120  }
1121 
1122 
1123  default:
1124  elog(ERROR, "unrecognized shared classId: %u", classId);
1125  }
1126 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
char * tablespace
Definition: pgbench.c:188
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1002
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1467
#define elog(elevel,...)
Definition: elog.h:214

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

Definition at line 1401 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, InvalidOid, isSharedObjectPinned(), sort-test::key, lfirst_oid, MyDatabaseId, NoLock, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), SHARED_DEPENDENCY_OWNER, SHARED_DEPENDENCY_PIN, SharedDependReferenceIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ReassignOwnedObjects().

1402 {
1403  Relation sdepRel;
1404  ListCell *cell;
1405 
1406  /*
1407  * We don't need this strong a lock here, but we'll call routines that
1408  * acquire RowExclusiveLock. Better get that right now to avoid potential
1409  * deadlock problems.
1410  */
1411  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1412 
1413  foreach(cell, roleids)
1414  {
1415  SysScanDesc scan;
1416  ScanKeyData key[2];
1417  HeapTuple tuple;
1418  Oid roleid = lfirst_oid(cell);
1419 
1420  /* Refuse to work on pinned roles */
1421  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1422  {
1423  ObjectAddress obj;
1424 
1425  obj.classId = AuthIdRelationId;
1426  obj.objectId = roleid;
1427  obj.objectSubId = 0;
1428 
1429  ereport(ERROR,
1430  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1431  errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
1432  getObjectDescription(&obj))));
1433 
1434  /*
1435  * There's no need to tell the whole truth, which is that we
1436  * didn't track these dependencies at all ...
1437  */
1438  }
1439 
1440  ScanKeyInit(&key[0],
1441  Anum_pg_shdepend_refclassid,
1442  BTEqualStrategyNumber, F_OIDEQ,
1443  ObjectIdGetDatum(AuthIdRelationId));
1444  ScanKeyInit(&key[1],
1445  Anum_pg_shdepend_refobjid,
1446  BTEqualStrategyNumber, F_OIDEQ,
1447  ObjectIdGetDatum(roleid));
1448 
1449  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1450  NULL, 2, key);
1451 
1452  while ((tuple = systable_getnext(scan)) != NULL)
1453  {
1454  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1455 
1456  /*
1457  * We only operate on shared objects and objects in the current
1458  * database
1459  */
1460  if (sdepForm->dbid != MyDatabaseId &&
1461  sdepForm->dbid != InvalidOid)
1462  continue;
1463 
1464  /* Unexpected because we checked for pins above */
1465  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
1466  elog(ERROR, "unexpected shared pin");
1467 
1468  /* We leave non-owner dependencies alone */
1469  if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
1470  continue;
1471 
1472  /* Issue the appropriate ALTER OWNER call */
1473  switch (sdepForm->classid)
1474  {
1475  case TypeRelationId:
1476  AlterTypeOwner_oid(sdepForm->objid, newrole, true);
1477  break;
1478 
1479  case NamespaceRelationId:
1480  AlterSchemaOwner_oid(sdepForm->objid, newrole);
1481  break;
1482 
1483  case RelationRelationId:
1484 
1485  /*
1486  * Pass recursing = true so that we don't fail on indexes,
1487  * owned sequences, etc when we happen to visit them
1488  * before their parent table.
1489  */
1490  ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
1491  break;
1492 
1493  case DefaultAclRelationId:
1494 
1495  /*
1496  * Ignore default ACLs; they should be handled by DROP
1497  * OWNED, not REASSIGN OWNED.
1498  */
1499  break;
1500 
1501  case UserMappingRelationId:
1502  /* ditto */
1503  break;
1504 
1505  case ForeignServerRelationId:
1506  AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1507  break;
1508 
1509  case ForeignDataWrapperRelationId:
1510  AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1511  break;
1512 
1513  case EventTriggerRelationId:
1514  AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
1515  break;
1516 
1517  case PublicationRelationId:
1518  AlterPublicationOwner_oid(sdepForm->objid, newrole);
1519  break;
1520 
1521  case SubscriptionRelationId:
1522  AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
1523  break;
1524 
1525  /* Generic alter owner cases */
1526  case CollationRelationId:
1527  case ConversionRelationId:
1528  case OperatorRelationId:
1529  case ProcedureRelationId:
1530  case LanguageRelationId:
1531  case LargeObjectRelationId:
1532  case OperatorFamilyRelationId:
1533  case OperatorClassRelationId:
1534  case ExtensionRelationId:
1535  case StatisticExtRelationId:
1536  case TableSpaceRelationId:
1537  case DatabaseRelationId:
1538  case TSConfigRelationId:
1539  case TSDictionaryRelationId:
1540  {
1541  Oid classId = sdepForm->classid;
1542  Relation catalog;
1543 
1544  if (classId == LargeObjectRelationId)
1545  classId = LargeObjectMetadataRelationId;
1546 
1547  catalog = table_open(classId, RowExclusiveLock);
1548 
1549  AlterObjectOwner_internal(catalog, sdepForm->objid,
1550  newrole);
1551 
1552  table_close(catalog, NoLock);
1553  }
1554  break;
1555 
1556  default:
1557  elog(ERROR, "unexpected classid %u", sdepForm->classid);
1558  break;
1559  }
1560  /* Make sure the next iteration will see my changes */
1562  }
1563 
1564  systable_endscan(scan);
1565  }
1566 
1567  table_close(sdepRel, RowExclusiveLock);
1568 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
Definition: foreigncmds.c:313
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1195
void AlterSchemaOwner_oid(Oid oid, Oid newOwnerId)
Definition: schemacmds.c:276
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
void AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
Definition: foreigncmds.c:450
int errcode(int sqlerrcode)
Definition: elog.c:610
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:356
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
Definition: typecmds.c:3340
void AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
Definition: alter.c:934
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
void ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lockmode)
Definition: tablecmds.c:12378
void CommandCounterIncrement(void)
Definition: xact.c:1006
Oid MyDatabaseId
Definition: globals.c:85
#define InvalidOid
Definition: postgres_ext.h:36
void AlterEventTriggerOwner_oid(Oid trigOid, Oid newOwnerId)
#define ereport(elevel,...)
Definition: elog.h:144
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
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 SharedDependReferenceIndexId
Definition: indexing.h:225
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ sort_object_addresses()

void sort_object_addresses ( ObjectAddresses addrs)

Definition at line 2693 of file dependency.c.

References ObjectAddresses::numrefs, object_address_comparator(), qsort, and ObjectAddresses::refs.

Referenced by shdepDropOwned().

2694 {
2695  if (addrs->numrefs > 1)
2696  qsort((void *) addrs->refs, addrs->numrefs,
2697  sizeof(ObjectAddress),
2699 }
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2366
ObjectAddress * refs
Definition: dependency.c:111
#define qsort(a, b, c, d)
Definition: port.h:479

◆ updateAclDependencies()

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

Definition at line 426 of file pg_shdepend.c.

References getOidListDiff(), i, isSharedObjectPinned(), pfree(), RowExclusiveLock, SHARED_DEPENDENCY_ACL, shdepAddDependency(), shdepDropDependency(), table_close(), and table_open().

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

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