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
 
typedef bool(* VisitDependenciesOfCB) (const ObjectAddress *otherObject, const char *version, char **new_version, void *data)
 

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, bool record_version)
 
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 visitDependenciesOf (const ObjectAddress *object, VisitDependenciesOfCB callback, void *data)
 
void recordDependencyOn (const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
 
void recordDependencyOnCollations (ObjectAddress *myself, List *collations, bool record_version)
 
void recordMultipleDependencies (const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
 
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

◆ VisitDependenciesOfCB

typedef bool(* VisitDependenciesOfCB) (const ObjectAddress *otherObject, const char *version, char **new_version, void *data)

Definition at line 184 of file dependency.h.

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 1603 of file dependency.c.

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

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

1604 {
1605  if (object->classId == RelationRelationId)
1606  {
1607  /*
1608  * In DROP INDEX CONCURRENTLY, take only ShareUpdateExclusiveLock on
1609  * the index for the moment. index_drop() will promote the lock once
1610  * it's safe to do so. In all other cases we need full exclusive
1611  * lock.
1612  */
1613  if (flags & PERFORM_DELETION_CONCURRENTLY)
1615  else
1617  }
1618  else
1619  {
1620  /* assume we should lock the whole object not a sub-object */
1621  LockDatabaseObject(object->classId, object->objectId, 0,
1623  }
1624 }
#define PERFORM_DELETION_CONCURRENTLY
Definition: dependency.h:135
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:976
#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 2594 of file dependency.c.

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

Referenced by AggregateCreate(), AlterConstraintNamespaces(), AlterIndexNamespaces(), AlterRelationNamespaceInternal(), AlterTypeNamespaceInternal(), ATExecDropColumn(), ATPostAlterTypeCleanup(), CastCreate(), CreateConstraintEntry(), CreateProceduralLanguage(), CreateTransform(), DropClonedTriggersFromPartition(), GenerateTypeDependencies(), heap_create_with_catalog(), index_create(), InsertExtensionTuple(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeTSTemplateDependencies(), PreCommit_on_commit_actions(), ProcedureCreate(), RangeCreate(), recordDependencyOnCollations(), recordDependencyOnSingleRelExpr(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), shdepDropOwned(), and StorePartitionKey().

2596 {
2597  ObjectAddress *item;
2598 
2599  /* enlarge array if needed */
2600  if (addrs->numrefs >= addrs->maxrefs)
2601  {
2602  addrs->maxrefs *= 2;
2603  addrs->refs = (ObjectAddress *)
2604  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2605  Assert(!addrs->extras);
2606  }
2607  /* record this item */
2608  item = addrs->refs + addrs->numrefs;
2609  *item = *object;
2610  addrs->numrefs++;
2611 }
ObjectAddress * refs
Definition: dependency.c:112
#define Assert(condition)
Definition: c.h:800
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1070
ObjectAddressExtra * extras
Definition: dependency.c:113

◆ changeDependenciesOf()

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

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

540 {
541  long count = 0;
542  Relation depRel;
543  ScanKeyData key[2];
544  SysScanDesc scan;
545  HeapTuple tup;
546 
547  depRel = table_open(DependRelationId, RowExclusiveLock);
548 
549  ScanKeyInit(&key[0],
550  Anum_pg_depend_classid,
551  BTEqualStrategyNumber, F_OIDEQ,
552  ObjectIdGetDatum(classId));
553  ScanKeyInit(&key[1],
554  Anum_pg_depend_objid,
555  BTEqualStrategyNumber, F_OIDEQ,
556  ObjectIdGetDatum(oldObjectId));
557 
558  scan = systable_beginscan(depRel, DependDependerIndexId, true,
559  NULL, 2, key);
560 
561  while (HeapTupleIsValid((tup = systable_getnext(scan))))
562  {
563  Form_pg_depend depform;
564 
565  /* make a modifiable copy */
566  tup = heap_copytuple(tup);
567  depform = (Form_pg_depend) GETSTRUCT(tup);
568 
569  depform->objid = newObjectId;
570 
571  CatalogTupleUpdate(depRel, &tup->t_self, tup);
572 
573  heap_freetuple(tup);
574 
575  count++;
576  }
577 
578  systable_endscan(scan);
579 
580  table_close(depRel, RowExclusiveLock);
581 
582  return count;
583 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#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:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
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 594 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().

596 {
597  long count = 0;
598  Relation depRel;
599  ScanKeyData key[2];
600  SysScanDesc scan;
601  HeapTuple tup;
602  ObjectAddress objAddr;
603  bool newIsPinned;
604 
605  depRel = table_open(DependRelationId, RowExclusiveLock);
606 
607  /*
608  * If oldRefObjectId is pinned, there won't be any dependency entries on
609  * it --- we can't cope in that case. (This isn't really worth expending
610  * code to fix, in current usage; it just means you can't rename stuff out
611  * of pg_catalog, which would likely be a bad move anyway.)
612  */
613  objAddr.classId = refClassId;
614  objAddr.objectId = oldRefObjectId;
615  objAddr.objectSubId = 0;
616 
617  if (isObjectPinned(&objAddr, depRel))
618  ereport(ERROR,
619  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
620  errmsg("cannot remove dependency on %s because it is a system object",
621  getObjectDescription(&objAddr, false))));
622 
623  /*
624  * We can handle adding a dependency on something pinned, though, since
625  * that just means deleting the dependency entry.
626  */
627  objAddr.objectId = newRefObjectId;
628 
629  newIsPinned = isObjectPinned(&objAddr, depRel);
630 
631  /* Now search for dependency records */
632  ScanKeyInit(&key[0],
633  Anum_pg_depend_refclassid,
634  BTEqualStrategyNumber, F_OIDEQ,
635  ObjectIdGetDatum(refClassId));
636  ScanKeyInit(&key[1],
637  Anum_pg_depend_refobjid,
638  BTEqualStrategyNumber, F_OIDEQ,
639  ObjectIdGetDatum(oldRefObjectId));
640 
641  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
642  NULL, 2, key);
643 
644  while (HeapTupleIsValid((tup = systable_getnext(scan))))
645  {
646  if (newIsPinned)
647  CatalogTupleDelete(depRel, &tup->t_self);
648  else
649  {
650  Form_pg_depend depform;
651 
652  /* make a modifiable copy */
653  tup = heap_copytuple(tup);
654  depform = (Form_pg_depend) GETSTRUCT(tup);
655 
656  depform->refobjid = newRefObjectId;
657 
658  CatalogTupleUpdate(depRel, &tup->t_self, tup);
659 
660  heap_freetuple(tup);
661  }
662 
663  count++;
664  }
665 
666  systable_endscan(scan);
667 
668  table_close(depRel, RowExclusiveLock);
669 
670  return count;
671 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int errcode(int sqlerrcode)
Definition: elog.c:691
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:683
#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:74
#define DependReferenceIndexId
Definition: pg_depend.h:81
#define ereport(elevel,...)
Definition: elog.h:155
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
int errmsg(const char *fmt,...)
Definition: elog.c:902
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 428 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().

431 {
432  long count = 0;
433  Relation depRel;
434  ScanKeyData key[2];
435  SysScanDesc scan;
436  HeapTuple tup;
437  ObjectAddress objAddr;
438  ObjectAddress depAddr;
439  bool oldIsPinned;
440  bool newIsPinned;
441 
442  depRel = table_open(DependRelationId, RowExclusiveLock);
443 
444  /*
445  * Check to see if either oldRefObjectId or newRefObjectId is pinned.
446  * Pinned objects should not have any dependency entries pointing to them,
447  * so in these cases we should add or remove a pg_depend entry, or do
448  * nothing at all, rather than update an entry as in the normal case.
449  */
450  objAddr.classId = refClassId;
451  objAddr.objectId = oldRefObjectId;
452  objAddr.objectSubId = 0;
453 
454  oldIsPinned = isObjectPinned(&objAddr, depRel);
455 
456  objAddr.objectId = newRefObjectId;
457 
458  newIsPinned = isObjectPinned(&objAddr, depRel);
459 
460  if (oldIsPinned)
461  {
462  table_close(depRel, RowExclusiveLock);
463 
464  /*
465  * If both are pinned, we need do nothing. However, return 1 not 0,
466  * else callers will think this is an error case.
467  */
468  if (newIsPinned)
469  return 1;
470 
471  /*
472  * There is no old dependency record, but we should insert a new one.
473  * Assume a normal dependency is wanted.
474  */
475  depAddr.classId = classId;
476  depAddr.objectId = objectId;
477  depAddr.objectSubId = 0;
478  recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL);
479 
480  return 1;
481  }
482 
483  /* There should be existing dependency record(s), so search. */
484  ScanKeyInit(&key[0],
485  Anum_pg_depend_classid,
486  BTEqualStrategyNumber, F_OIDEQ,
487  ObjectIdGetDatum(classId));
488  ScanKeyInit(&key[1],
489  Anum_pg_depend_objid,
490  BTEqualStrategyNumber, F_OIDEQ,
491  ObjectIdGetDatum(objectId));
492 
493  scan = systable_beginscan(depRel, DependDependerIndexId, true,
494  NULL, 2, key);
495 
496  while (HeapTupleIsValid((tup = systable_getnext(scan))))
497  {
498  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
499 
500  if (depform->refclassid == refClassId &&
501  depform->refobjid == oldRefObjectId)
502  {
503  if (newIsPinned)
504  CatalogTupleDelete(depRel, &tup->t_self);
505  else
506  {
507  /* make a modifiable copy */
508  tup = heap_copytuple(tup);
509  depform = (Form_pg_depend) GETSTRUCT(tup);
510 
511  depform->refobjid = newRefObjectId;
512 
513  CatalogTupleUpdate(depRel, &tup->t_self, tup);
514 
515  heap_freetuple(tup);
516  }
517 
518  count++;
519  }
520  }
521 
522  systable_endscan(scan);
523 
524  table_close(depRel, RowExclusiveLock);
525 
526  return count;
527 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46
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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:683
#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:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
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:167
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:1022
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, false))));
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
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
static int shared_dependency_comparator(const void *a, const void *b)
Definition: pg_shdepend.c:509
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#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:1182
int errcode(int sqlerrcode)
Definition: elog.c:691
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:357
SharedDependencyObjectType objtype
Definition: pg_shdepend.c:80
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
void pfree(void *pointer)
Definition: mcxt.c:1057
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define SharedDependReferenceIndexId
Definition: pg_shdepend.h:75
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:1178
Oid MyDatabaseId
Definition: globals.c:85
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:155
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:169
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1070
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:902
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define qsort(a, b, c, d)
Definition: port.h:497
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 796 of file pg_shdepend.c.

References BTEqualStrategyNumber, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTuplesMultiInsertWithInfo(), ExecClearTuple(), ExecDropSingleTupleTableSlot(), ExecStoreVirtualTuple(), FormData_pg_shdepend, GETSTRUCT, HeapTupleIsValid, i, sort-test::key, MakeSingleTupleTableSlot(), MAX_CATALOG_MULTI_INSERT_BYTES, ObjectIdGetDatum, palloc(), pfree(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SharedDependDependerIndexId, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), TupleTableSlot::tts_values, and TTSOpsHeapTuple.

Referenced by createdb().

797 {
798  Relation sdepRel;
799  TupleDesc sdepDesc;
800  ScanKeyData key[1];
801  SysScanDesc scan;
802  HeapTuple tup;
803  CatalogIndexState indstate;
804  TupleTableSlot **slot;
805  int max_slots,
806  slot_init_count,
807  slot_stored_count;
808 
809  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
810  sdepDesc = RelationGetDescr(sdepRel);
811 
812  /*
813  * Allocate the slots to use, but delay costly initialization until we
814  * know that they will be used.
815  */
817  slot = palloc(sizeof(TupleTableSlot *) * max_slots);
818 
819  indstate = CatalogOpenIndexes(sdepRel);
820 
821  /* Scan all entries with dbid = templateDbId */
822  ScanKeyInit(&key[0],
823  Anum_pg_shdepend_dbid,
824  BTEqualStrategyNumber, F_OIDEQ,
825  ObjectIdGetDatum(templateDbId));
826 
827  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
828  NULL, 1, key);
829 
830  /* number of slots currently storing tuples */
831  slot_stored_count = 0;
832  /* number of slots currently initialized */
833  slot_init_count = 0;
834 
835  /*
836  * Copy the entries of the original database, changing the database Id to
837  * that of the new database. Note that because we are not copying rows
838  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
839  * copy the ownership dependency of the template database itself; this is
840  * what we want.
841  */
842  while (HeapTupleIsValid(tup = systable_getnext(scan)))
843  {
844  Form_pg_shdepend shdep;
845 
846  if (slot_init_count < max_slots)
847  {
848  slot[slot_stored_count] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple);
849  slot_init_count++;
850  }
851 
852  ExecClearTuple(slot[slot_stored_count]);
853 
854  shdep = (Form_pg_shdepend) GETSTRUCT(tup);
855 
856  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_dbid] = ObjectIdGetDatum(newDbId);
857  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_classid] = shdep->classid;
858  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objid] = shdep->objid;
859  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objsubid] = shdep->objsubid;
860  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refclassid] = shdep->refclassid;
861  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refobjid] = shdep->refobjid;
862  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_deptype] = shdep->deptype;
863 
864  ExecStoreVirtualTuple(slot[slot_stored_count]);
865  slot_stored_count++;
866 
867  /* If slots are full, insert a batch of tuples */
868  if (slot_stored_count == max_slots)
869  {
870  CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
871  slot_stored_count = 0;
872  }
873  }
874 
875  /* Insert any tuples left in the buffer */
876  if (slot_stored_count > 0)
877  CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
878 
879  systable_endscan(scan);
880 
881  CatalogCloseIndexes(indstate);
882  table_close(sdepRel, RowExclusiveLock);
883 
884  /* Drop only the number of slots used */
885  for (int i = 0; i < slot_init_count; i++)
887  pfree(slot);
888 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
#define RelationGetDescr(relation)
Definition: rel.h:483
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1208
#define MAX_CATALOG_MULTI_INSERT_BYTES
Definition: indexing.h:33
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
Datum * tts_values
Definition: tuptable.h:126
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
void CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot, int ntuples, CatalogIndexState indstate)
Definition: indexing.c:261
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
#define RowExclusiveLock
Definition: lockdefs.h:38
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_shdepend
Definition: pg_shdepend.h:63
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:43
void * palloc(Size size)
Definition: mcxt.c:950
int i
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:84
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:61
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define SharedDependDependerIndexId
Definition: pg_shdepend.h:73
#define BTEqualStrategyNumber
Definition: stratnum.h:31
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1522

◆ deleteDependencyRecordsFor()

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

Definition at line 272 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(), CreateTrigger(), DefineQueryRewrite(), GenerateTypeDependencies(), InsertRule(), makeConfigurationDependencies(), makeOperatorDependencies(), ProcedureCreate(), RemoveRoleFromObjectPolicy(), swap_relation_files(), and tryAttachPartitionForeignKey().

274 {
275  long count = 0;
276  Relation depRel;
277  ScanKeyData key[2];
278  SysScanDesc scan;
279  HeapTuple tup;
280 
281  depRel = table_open(DependRelationId, RowExclusiveLock);
282 
283  ScanKeyInit(&key[0],
284  Anum_pg_depend_classid,
285  BTEqualStrategyNumber, F_OIDEQ,
286  ObjectIdGetDatum(classId));
287  ScanKeyInit(&key[1],
288  Anum_pg_depend_objid,
289  BTEqualStrategyNumber, F_OIDEQ,
290  ObjectIdGetDatum(objectId));
291 
292  scan = systable_beginscan(depRel, DependDependerIndexId, true,
293  NULL, 2, key);
294 
295  while (HeapTupleIsValid(tup = systable_getnext(scan)))
296  {
297  if (skipExtensionDeps &&
298  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
299  continue;
300 
301  CatalogTupleDelete(depRel, &tup->t_self);
302  count++;
303  }
304 
305  systable_endscan(scan);
306 
307  table_close(depRel, RowExclusiveLock);
308 
309  return count;
310 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#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:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 322 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().

324 {
325  long count = 0;
326  Relation depRel;
327  ScanKeyData key[2];
328  SysScanDesc scan;
329  HeapTuple tup;
330 
331  depRel = table_open(DependRelationId, RowExclusiveLock);
332 
333  ScanKeyInit(&key[0],
334  Anum_pg_depend_classid,
335  BTEqualStrategyNumber, F_OIDEQ,
336  ObjectIdGetDatum(classId));
337  ScanKeyInit(&key[1],
338  Anum_pg_depend_objid,
339  BTEqualStrategyNumber, F_OIDEQ,
340  ObjectIdGetDatum(objectId));
341 
342  scan = systable_beginscan(depRel, DependDependerIndexId, true,
343  NULL, 2, key);
344 
345  while (HeapTupleIsValid(tup = systable_getnext(scan)))
346  {
347  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
348 
349  if (depform->refclassid == refclassId && depform->deptype == deptype)
350  {
351  CatalogTupleDelete(depRel, &tup->t_self);
352  count++;
353  }
354  }
355 
356  systable_endscan(scan);
357 
358  table_close(depRel, RowExclusiveLock);
359 
360  return count;
361 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#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:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 369 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().

371 {
372  long count = 0;
373  Relation depRel;
374  ScanKeyData key[2];
375  SysScanDesc scan;
376  HeapTuple tup;
377 
378  depRel = table_open(DependRelationId, RowExclusiveLock);
379 
380  ScanKeyInit(&key[0],
381  Anum_pg_depend_classid,
382  BTEqualStrategyNumber, F_OIDEQ,
383  ObjectIdGetDatum(classId));
384  ScanKeyInit(&key[1],
385  Anum_pg_depend_objid,
386  BTEqualStrategyNumber, F_OIDEQ,
387  ObjectIdGetDatum(objectId));
388 
389  scan = systable_beginscan(depRel, DependDependerIndexId, true,
390  NULL, 2, key);
391 
392  while (HeapTupleIsValid(tup = systable_getnext(scan)))
393  {
394  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
395 
396  if (depform->refclassid == refclassId &&
397  depform->refobjid == refobjectId &&
398  depform->deptype == deptype)
399  {
400  CatalogTupleDelete(depRel, &tup->t_self);
401  count++;
402  }
403  }
404 
405  systable_endscan(scan);
406 
407  table_close(depRel, RowExclusiveLock);
408 
409  return count;
410 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#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:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 945 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().

946 {
947  Relation sdepRel;
948 
949  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
950 
951  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
952  (objectSubId == 0),
955 
956  table_close(sdepRel, RowExclusiveLock);
957 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
#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:1022
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

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

898 {
899  Relation sdepRel;
900  ScanKeyData key[1];
901  SysScanDesc scan;
902  HeapTuple tup;
903 
904  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
905 
906  /*
907  * First, delete all the entries that have the database Oid in the dbid
908  * field.
909  */
910  ScanKeyInit(&key[0],
911  Anum_pg_shdepend_dbid,
912  BTEqualStrategyNumber, F_OIDEQ,
913  ObjectIdGetDatum(databaseId));
914  /* We leave the other index fields unspecified */
915 
916  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
917  NULL, 1, key);
918 
919  while (HeapTupleIsValid(tup = systable_getnext(scan)))
920  {
921  CatalogTupleDelete(sdepRel, &tup->t_self);
922  }
923 
924  systable_endscan(scan);
925 
926  /* Now delete all entries corresponding to the database itself */
927  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
930 
931  table_close(sdepRel, RowExclusiveLock);
932 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#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:1022
#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 SharedDependDependerIndexId
Definition: pg_shdepend.h:73
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ free_object_addresses()

◆ get_constraint_index()

Oid get_constraint_index ( Oid  constraintId)

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

981 {
982  Oid indexId = InvalidOid;
983  Relation depRel;
984  ScanKeyData key[3];
985  SysScanDesc scan;
986  HeapTuple tup;
987 
988  /* Search the dependency table for the dependent index */
989  depRel = table_open(DependRelationId, AccessShareLock);
990 
991  ScanKeyInit(&key[0],
992  Anum_pg_depend_refclassid,
993  BTEqualStrategyNumber, F_OIDEQ,
994  ObjectIdGetDatum(ConstraintRelationId));
995  ScanKeyInit(&key[1],
996  Anum_pg_depend_refobjid,
997  BTEqualStrategyNumber, F_OIDEQ,
998  ObjectIdGetDatum(constraintId));
999  ScanKeyInit(&key[2],
1000  Anum_pg_depend_refobjsubid,
1001  BTEqualStrategyNumber, F_INT4EQ,
1002  Int32GetDatum(0));
1003 
1004  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
1005  NULL, 3, key);
1006 
1007  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1008  {
1009  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1010 
1011  /*
1012  * We assume any internal dependency of an index on the constraint
1013  * must be what we are looking for.
1014  */
1015  if (deprec->classid == RelationRelationId &&
1016  deprec->objsubid == 0 &&
1017  deprec->deptype == DEPENDENCY_INTERNAL)
1018  {
1019  char relkind = get_rel_relkind(deprec->objid);
1020 
1021  /*
1022  * This is pure paranoia; there shouldn't be any other relkinds
1023  * dependent on a constraint.
1024  */
1025  if (relkind != RELKIND_INDEX &&
1026  relkind != RELKIND_PARTITIONED_INDEX)
1027  continue;
1028 
1029  indexId = deprec->objid;
1030  break;
1031  }
1032  }
1033 
1034  systable_endscan(scan);
1035  table_close(depRel, AccessShareLock);
1036 
1037  return indexId;
1038 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
#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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependReferenceIndexId
Definition: pg_depend.h:81
#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 1047 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().

1048 {
1049  Oid constraintId = InvalidOid;
1050  Relation depRel;
1051  ScanKeyData key[3];
1052  SysScanDesc scan;
1053  HeapTuple tup;
1054 
1055  /* Search the dependency table for the index */
1056  depRel = table_open(DependRelationId, AccessShareLock);
1057 
1058  ScanKeyInit(&key[0],
1059  Anum_pg_depend_classid,
1060  BTEqualStrategyNumber, F_OIDEQ,
1061  ObjectIdGetDatum(RelationRelationId));
1062  ScanKeyInit(&key[1],
1063  Anum_pg_depend_objid,
1064  BTEqualStrategyNumber, F_OIDEQ,
1065  ObjectIdGetDatum(indexId));
1066  ScanKeyInit(&key[2],
1067  Anum_pg_depend_objsubid,
1068  BTEqualStrategyNumber, F_INT4EQ,
1069  Int32GetDatum(0));
1070 
1071  scan = systable_beginscan(depRel, DependDependerIndexId, true,
1072  NULL, 3, key);
1073 
1074  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1075  {
1076  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1077 
1078  /*
1079  * We assume any internal dependency on a constraint must be what we
1080  * are looking for.
1081  */
1082  if (deprec->refclassid == ConstraintRelationId &&
1083  deprec->refobjsubid == 0 &&
1084  deprec->deptype == DEPENDENCY_INTERNAL)
1085  {
1086  constraintId = deprec->refobjid;
1087  break;
1088  }
1089  }
1090 
1091  systable_endscan(scan);
1092  table_close(depRel, AccessShareLock);
1093 
1094  return constraintId;
1095 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 1103 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().

1104 {
1105  List *result = NIL;
1106  Relation depRel;
1107  ScanKeyData key[3];
1108  SysScanDesc scan;
1109  HeapTuple tup;
1110 
1111  /* Search the dependency table for the index */
1112  depRel = table_open(DependRelationId, AccessShareLock);
1113 
1114  ScanKeyInit(&key[0],
1115  Anum_pg_depend_refclassid,
1116  BTEqualStrategyNumber, F_OIDEQ,
1117  ObjectIdGetDatum(RelationRelationId));
1118  ScanKeyInit(&key[1],
1119  Anum_pg_depend_refobjid,
1120  BTEqualStrategyNumber, F_OIDEQ,
1121  ObjectIdGetDatum(indexId));
1122  ScanKeyInit(&key[2],
1123  Anum_pg_depend_refobjsubid,
1124  BTEqualStrategyNumber, F_INT4EQ,
1125  Int32GetDatum(0));
1126 
1127  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
1128  NULL, 3, key);
1129 
1130  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1131  {
1132  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1133 
1134  /*
1135  * We assume any normal dependency from a constraint must be what we
1136  * are looking for.
1137  */
1138  if (deprec->classid == ConstraintRelationId &&
1139  deprec->objsubid == 0 &&
1140  deprec->deptype == DEPENDENCY_NORMAL)
1141  {
1142  result = lappend_oid(result, deprec->objid);
1143  }
1144  }
1145 
1146  systable_endscan(scan);
1147  table_close(depRel, AccessShareLock);
1148 
1149  return result;
1150 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependReferenceIndexId
Definition: pg_depend.h:81
#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 787 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().

788 {
789  List *result = NIL;
790  Relation depRel;
791  ScanKeyData key[2];
792  SysScanDesc scan;
793  HeapTuple tup;
794 
795  depRel = table_open(DependRelationId, AccessShareLock);
796 
797  ScanKeyInit(&key[0],
798  Anum_pg_depend_classid,
799  BTEqualStrategyNumber, F_OIDEQ,
800  ObjectIdGetDatum(classId));
801  ScanKeyInit(&key[1],
802  Anum_pg_depend_objid,
803  BTEqualStrategyNumber, F_OIDEQ,
804  ObjectIdGetDatum(objectId));
805 
806  scan = systable_beginscan(depRel, DependDependerIndexId, true,
807  NULL, 2, key);
808 
809  while (HeapTupleIsValid((tup = systable_getnext(scan))))
810  {
811  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
812 
813  if (depform->refclassid == ExtensionRelationId &&
814  depform->deptype == DEPENDENCY_AUTO_EXTENSION)
815  result = lappend_oid(result, depform->refobjid);
816  }
817 
818  systable_endscan(scan);
819 
820  table_close(depRel, AccessShareLock);
821 
822  return result;
823 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 741 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().

742 {
743  Oid result = InvalidOid;
744  Relation depRel;
745  ScanKeyData key[2];
746  SysScanDesc scan;
747  HeapTuple tup;
748 
749  depRel = table_open(DependRelationId, AccessShareLock);
750 
751  ScanKeyInit(&key[0],
752  Anum_pg_depend_classid,
753  BTEqualStrategyNumber, F_OIDEQ,
754  ObjectIdGetDatum(classId));
755  ScanKeyInit(&key[1],
756  Anum_pg_depend_objid,
757  BTEqualStrategyNumber, F_OIDEQ,
758  ObjectIdGetDatum(objectId));
759 
760  scan = systable_beginscan(depRel, DependDependerIndexId, true,
761  NULL, 2, key);
762 
763  while (HeapTupleIsValid((tup = systable_getnext(scan))))
764  {
765  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
766 
767  if (depform->refclassid == ExtensionRelationId &&
768  depform->deptype == DEPENDENCY_EXTENSION)
769  {
770  result = depform->refobjid;
771  break; /* no need to keep scanning */
772  }
773  }
774 
775  systable_endscan(scan);
776 
777  table_close(depRel, AccessShareLock);
778 
779  return result;
780 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 954 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().

955 {
957 
958  if (list_length(seqlist) > 1)
959  elog(ERROR, "more than one owned sequence found");
960  else if (list_length(seqlist) < 1)
961  {
962  if (missing_ok)
963  return InvalidOid;
964  else
965  elog(ERROR, "no owned sequence found");
966  }
967 
968  return linitial_oid(seqlist);
969 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:886
#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:176
static int list_length(const List *l)
Definition: pg_list.h:149
#define elog(elevel,...)
Definition: elog.h:228
Definition: pg_list.h:50

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

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

2851 {
2852  /* only pg_class entries can have nonzero objectSubId */
2853  if (object->classId != RelationRelationId &&
2854  object->objectSubId != 0)
2855  elog(ERROR, "invalid non-zero objectSubId for object class %u",
2856  object->classId);
2857 
2858  switch (object->classId)
2859  {
2860  case RelationRelationId:
2861  /* caller must check objectSubId */
2862  return OCLASS_CLASS;
2863 
2864  case ProcedureRelationId:
2865  return OCLASS_PROC;
2866 
2867  case TypeRelationId:
2868  return OCLASS_TYPE;
2869 
2870  case CastRelationId:
2871  return OCLASS_CAST;
2872 
2873  case CollationRelationId:
2874  return OCLASS_COLLATION;
2875 
2876  case ConstraintRelationId:
2877  return OCLASS_CONSTRAINT;
2878 
2879  case ConversionRelationId:
2880  return OCLASS_CONVERSION;
2881 
2882  case AttrDefaultRelationId:
2883  return OCLASS_DEFAULT;
2884 
2885  case LanguageRelationId:
2886  return OCLASS_LANGUAGE;
2887 
2888  case LargeObjectRelationId:
2889  return OCLASS_LARGEOBJECT;
2890 
2891  case OperatorRelationId:
2892  return OCLASS_OPERATOR;
2893 
2894  case OperatorClassRelationId:
2895  return OCLASS_OPCLASS;
2896 
2897  case OperatorFamilyRelationId:
2898  return OCLASS_OPFAMILY;
2899 
2900  case AccessMethodRelationId:
2901  return OCLASS_AM;
2902 
2903  case AccessMethodOperatorRelationId:
2904  return OCLASS_AMOP;
2905 
2906  case AccessMethodProcedureRelationId:
2907  return OCLASS_AMPROC;
2908 
2909  case RewriteRelationId:
2910  return OCLASS_REWRITE;
2911 
2912  case TriggerRelationId:
2913  return OCLASS_TRIGGER;
2914 
2915  case NamespaceRelationId:
2916  return OCLASS_SCHEMA;
2917 
2918  case StatisticExtRelationId:
2919  return OCLASS_STATISTIC_EXT;
2920 
2921  case TSParserRelationId:
2922  return OCLASS_TSPARSER;
2923 
2924  case TSDictionaryRelationId:
2925  return OCLASS_TSDICT;
2926 
2927  case TSTemplateRelationId:
2928  return OCLASS_TSTEMPLATE;
2929 
2930  case TSConfigRelationId:
2931  return OCLASS_TSCONFIG;
2932 
2933  case AuthIdRelationId:
2934  return OCLASS_ROLE;
2935 
2936  case DatabaseRelationId:
2937  return OCLASS_DATABASE;
2938 
2939  case TableSpaceRelationId:
2940  return OCLASS_TBLSPACE;
2941 
2942  case ForeignDataWrapperRelationId:
2943  return OCLASS_FDW;
2944 
2945  case ForeignServerRelationId:
2946  return OCLASS_FOREIGN_SERVER;
2947 
2948  case UserMappingRelationId:
2949  return OCLASS_USER_MAPPING;
2950 
2951  case DefaultAclRelationId:
2952  return OCLASS_DEFACL;
2953 
2954  case ExtensionRelationId:
2955  return OCLASS_EXTENSION;
2956 
2957  case EventTriggerRelationId:
2958  return OCLASS_EVENT_TRIGGER;
2959 
2960  case PolicyRelationId:
2961  return OCLASS_POLICY;
2962 
2963  case PublicationRelationId:
2964  return OCLASS_PUBLICATION;
2965 
2966  case PublicationRelRelationId:
2967  return OCLASS_PUBLICATION_REL;
2968 
2969  case SubscriptionRelationId:
2970  return OCLASS_SUBSCRIPTION;
2971 
2972  case TransformRelationId:
2973  return OCLASS_TRANSFORM;
2974  }
2975 
2976  /* shouldn't get here */
2977  elog(ERROR, "unrecognized object class: %u", object->classId);
2978  return OCLASS_CLASS; /* keep compiler quiet */
2979 }
#define ERROR
Definition: elog.h:43
#define elog(elevel,...)
Definition: elog.h:228

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 945 of file pg_depend.c.

References getOwnedSequences_internal().

Referenced by ExecuteTruncateGuts().

946 {
947  return getOwnedSequences_internal(relid, 0, 0);
948 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:886

◆ new_object_addresses()

ObjectAddresses* new_object_addresses ( void  )

Definition at line 2539 of file dependency.c.

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

Referenced by AggregateCreate(), AlterExtensionNamespace(), AlterTableNamespace(), AlterTypeNamespace(), ATExecDropColumn(), ATPostAlterTypeCleanup(), CastCreate(), CreateConstraintEntry(), CreateProceduralLanguage(), CreateTransform(), DropClonedTriggersFromPartition(), GenerateTypeDependencies(), heap_create_with_catalog(), index_create(), InsertExtensionTuple(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeTSTemplateDependencies(), performDeletion(), performMultipleDeletions(), PreCommit_on_commit_actions(), ProcedureCreate(), RangeCreate(), recordDependencyOnCollations(), recordDependencyOnExpr(), recordDependencyOnSingleRelExpr(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), shdepDropOwned(), and StorePartitionKey().

2540 {
2541  ObjectAddresses *addrs;
2542 
2543  addrs = palloc(sizeof(ObjectAddresses));
2544 
2545  addrs->numrefs = 0;
2546  addrs->maxrefs = 32;
2547  addrs->refs = (ObjectAddress *)
2548  palloc(addrs->maxrefs * sizeof(ObjectAddress));
2549  addrs->extras = NULL; /* until/unless needed */
2550 
2551  return addrs;
2552 }
ObjectAddress * refs
Definition: dependency.c:112
ObjectAddressExtra * extras
Definition: dependency.c:113
void * palloc(Size size)
Definition: mcxt.c:950

◆ object_address_present()

bool object_address_present ( const ObjectAddress object,
const ObjectAddresses addrs 
)

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

2656 {
2657  int i;
2658 
2659  for (i = addrs->numrefs - 1; i >= 0; i--)
2660  {
2661  const ObjectAddress *thisobj = addrs->refs + i;
2662 
2663  if (object->classId == thisobj->classId &&
2664  object->objectId == thisobj->objectId)
2665  {
2666  if (object->objectSubId == thisobj->objectSubId ||
2667  thisobj->objectSubId == 0)
2668  return true;
2669  }
2670  }
2671 
2672  return false;
2673 }
ObjectAddress * refs
Definition: dependency.c:112
int i

◆ performDeletion()

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

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

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

◆ performMultipleDeletions()

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

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

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

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

Referenced by AggregateCreate(), CastCreate(), CreateConstraintEntry(), CreateProceduralLanguage(), CreateTransform(), GenerateTypeDependencies(), heap_create_with_catalog(), index_create(), InsertExtensionTuple(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeTSTemplateDependencies(), ProcedureCreate(), RangeCreate(), and StorePartitionKey().

2806 {
2808  recordMultipleDependencies(depender,
2809  referenced->refs, referenced->numrefs,
2810  behavior,
2811  false);
2812 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2435
ObjectAddress * refs
Definition: dependency.c:112
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
Definition: pg_depend.c:63

◆ recordDependencyOn()

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

Definition at line 46 of file pg_depend.c.

References recordMultipleDependencies().

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

49 {
50  recordMultipleDependencies(depender, referenced, 1, behavior, false);
51 }
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
Definition: pg_depend.c:63

◆ recordDependencyOnCollations()

void recordDependencyOnCollations ( ObjectAddress myself,
List collations,
bool  record_version 
)

Definition at line 1647 of file dependency.c.

References add_exact_object_address(), DEPENDENCY_NORMAL, eliminate_duplicate_dependencies(), free_object_addresses(), lfirst_oid, list_length(), new_object_addresses(), ObjectAddresses::numrefs, ObjectAddressSet, recordMultipleDependencies(), and ObjectAddresses::refs.

Referenced by index_create().

1650 {
1651  ObjectAddresses *addrs;
1652  ListCell *lc;
1653 
1654  if (list_length(collations) == 0)
1655  return;
1656 
1657  addrs = new_object_addresses();
1658  foreach(lc, collations)
1659  {
1660  ObjectAddress referenced;
1661 
1662  ObjectAddressSet(referenced, CollationRelationId, lfirst_oid(lc));
1663 
1664  add_exact_object_address(&referenced, addrs);
1665  }
1666 
1668  recordMultipleDependencies(myself, addrs->refs, addrs->numrefs,
1669  DEPENDENCY_NORMAL, record_version);
1670 
1671  free_object_addresses(addrs);
1672 }
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2594
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2539
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2835
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2435
ObjectAddress * refs
Definition: dependency.c:112
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
Definition: pg_depend.c:63
static int list_length(const List *l)
Definition: pg_list.h:149
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

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

222 {
223  /* Only whole objects can be extension members */
224  Assert(object->objectSubId == 0);
225 
226  if (creating_extension)
227  {
228  ObjectAddress extension;
229 
230  /* Only need to check for existing membership if isReplace */
231  if (isReplace)
232  {
233  Oid oldext;
234 
235  oldext = getExtensionOfObject(object->classId, object->objectId);
236  if (OidIsValid(oldext))
237  {
238  /* If already a member of this extension, nothing to do */
239  if (oldext == CurrentExtensionObject)
240  return;
241  /* Already a member of some other extension, so reject */
242  ereport(ERROR,
243  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
244  errmsg("%s is already a member of extension \"%s\"",
245  getObjectDescription(object, false),
246  get_extension_name(oldext))));
247  }
248  }
249 
250  /* OK, record it as a member of CurrentExtensionObject */
251  extension.classId = ExtensionRelationId;
252  extension.objectId = CurrentExtensionObject;
253  extension.objectSubId = 0;
254 
255  recordDependencyOn(object, &extension, DEPENDENCY_EXTENSION);
256  }
257 }
Oid CurrentExtensionObject
Definition: extension.c:72
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:741
char * get_extension_name(Oid ext_oid)
Definition: extension.c:185
int errcode(int sqlerrcode)
Definition: elog.c:691
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:706
#define ERROR
Definition: elog.h:43
bool creating_extension
Definition: extension.c:71
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:800
int errmsg(const char *fmt,...)
Definition: elog.c:902

◆ recordDependencyOnExpr()

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

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

1692 {
1694 
1695  context.addrs = new_object_addresses();
1696 
1697  /* Set up interpretation for Vars at varlevelsup = 0 */
1698  context.rtables = list_make1(rtable);
1699 
1700  /* Scan the expression tree for referenceable objects */
1701  find_expr_references_walker(expr, &context);
1702 
1703  /* Remove any duplicates */
1705 
1706  /* And record 'em */
1707  recordMultipleDependencies(depender,
1708  context.addrs->refs,
1709  context.addrs->numrefs,
1710  behavior,
1711  false);
1712 
1713  free_object_addresses(context.addrs);
1714 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1842
ObjectAddresses * addrs
Definition: dependency.c:138
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2539
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2835
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2435
#define list_make1(x1)
Definition: pg_list.h:206
ObjectAddress * refs
Definition: dependency.c:112
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
Definition: pg_depend.c:63

◆ 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,
bool  record_version 
)

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

1740 {
1742  RangeTblEntry rte;
1743 
1744  context.addrs = new_object_addresses();
1745 
1746  /* We gin up a rather bogus rangetable list to handle Vars */
1747  MemSet(&rte, 0, sizeof(rte));
1748  rte.type = T_RangeTblEntry;
1749  rte.rtekind = RTE_RELATION;
1750  rte.relid = relId;
1751  rte.relkind = RELKIND_RELATION; /* no need for exactness here */
1753 
1754  context.rtables = list_make1(list_make1(&rte));
1755 
1756  /* Scan the expression tree for referenceable objects */
1757  find_expr_references_walker(expr, &context);
1758 
1759  /* Remove any duplicates */
1761 
1762  /* Separate self-dependencies if necessary */
1763  if ((behavior != self_behavior || reverse_self) &&
1764  context.addrs->numrefs > 0)
1765  {
1766  ObjectAddresses *self_addrs;
1767  ObjectAddress *outobj;
1768  int oldref,
1769  outrefs;
1770 
1771  self_addrs = new_object_addresses();
1772 
1773  outobj = context.addrs->refs;
1774  outrefs = 0;
1775  for (oldref = 0; oldref < context.addrs->numrefs; oldref++)
1776  {
1777  ObjectAddress *thisobj = context.addrs->refs + oldref;
1778 
1779  if (thisobj->classId == RelationRelationId &&
1780  thisobj->objectId == relId)
1781  {
1782  /* Move this ref into self_addrs */
1783  add_exact_object_address(thisobj, self_addrs);
1784  }
1785  else
1786  {
1787  /* Keep it in context.addrs */
1788  *outobj = *thisobj;
1789  outobj++;
1790  outrefs++;
1791  }
1792  }
1793  context.addrs->numrefs = outrefs;
1794 
1795  /* Record the self-dependencies with the appropriate direction */
1796  if (!reverse_self)
1797  recordMultipleDependencies(depender,
1798  self_addrs->refs,
1799  self_addrs->numrefs,
1800  self_behavior,
1801  record_version);
1802  else
1803  {
1804  /* Can't use recordMultipleDependencies, so do it the hard way */
1805  int selfref;
1806 
1807  for (selfref = 0; selfref < self_addrs->numrefs; selfref++)
1808  {
1809  ObjectAddress *thisobj = self_addrs->refs + selfref;
1810 
1811  recordDependencyOn(thisobj, depender, self_behavior);
1812  }
1813  }
1814 
1815  free_object_addresses(self_addrs);
1816  }
1817 
1818  /* Record the external dependencies */
1819  recordMultipleDependencies(depender,
1820  context.addrs->refs,
1821  context.addrs->numrefs,
1822  behavior,
1823  record_version);
1824 
1825  free_object_addresses(context.addrs);
1826 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1842
ObjectAddresses * addrs
Definition: dependency.c:138
#define AccessShareLock
Definition: lockdefs.h:36
#define MemSet(start, val, len)
Definition: c.h:1004
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2594
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2539
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2835
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2435
#define list_make1(x1)
Definition: pg_list.h:206
ObjectAddress * refs
Definition: dependency.c:112
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior, bool record_version)
Definition: pg_depend.c:63
RTEKind rtekind
Definition: parsenodes.h:981
NodeTag type
Definition: parsenodes.h:979

◆ recordMultipleDependencies()

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

Definition at line 63 of file pg_depend.c.

References Assert, CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTuplesMultiInsertWithInfo(), CharGetDatum, ObjectAddress::classId, CStringGetTextDatum, ExecClearTuple(), ExecDropSingleTupleTableSlot(), ExecStoreVirtualTuple(), FormData_pg_depend, get_collation_version_for_oid(), i, Int32GetDatum, IsBootstrapProcessingMode, isObjectPinned(), MakeSingleTupleTableSlot(), MAX_CATALOG_MULTI_INSERT_BYTES, Min, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, palloc(), pfree(), RelationGetDescr, RowExclusiveLock, table_close(), table_open(), TupleTableSlot::tts_isnull, TupleTableSlot::tts_values, and TTSOpsHeapTuple.

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

68 {
69  Relation dependDesc;
70  CatalogIndexState indstate;
71  TupleTableSlot **slot;
72  int i,
73  max_slots,
74  slot_init_count,
75  slot_stored_count;
76  char *version = NULL;
77 
78  if (nreferenced <= 0)
79  return; /* nothing to do */
80 
81  /*
82  * During bootstrap, do nothing since pg_depend may not exist yet. initdb
83  * will fill in appropriate pg_depend entries after bootstrap.
84  */
86  return;
87 
88  dependDesc = table_open(DependRelationId, RowExclusiveLock);
89 
90  /*
91  * Allocate the slots to use, but delay costly initialization until we
92  * know that they will be used.
93  */
94  max_slots = Min(nreferenced,
96  slot = palloc(sizeof(TupleTableSlot *) * max_slots);
97 
98  /* Don't open indexes unless we need to make an update */
99  indstate = NULL;
100 
101  /* number of slots currently storing tuples */
102  slot_stored_count = 0;
103  /* number of slots currently initialized */
104  slot_init_count = 0;
105  for (i = 0; i < nreferenced; i++, referenced++)
106  {
107  bool ignore_systempin = false;
108 
109  if (record_version)
110  {
111  /* For now we only know how to deal with collations. */
112  if (referenced->classId == CollationRelationId)
113  {
114  /* C and POSIX don't need version tracking. */
115  if (referenced->objectId == C_COLLATION_OID ||
116  referenced->objectId == POSIX_COLLATION_OID)
117  continue;
118 
119  version = get_collation_version_for_oid(referenced->objectId);
120 
121  /*
122  * Default collation is pinned, so we need to force recording
123  * the dependency to store the version.
124  */
125  if (referenced->objectId == DEFAULT_COLLATION_OID)
126  ignore_systempin = true;
127  }
128  }
129  else
130  Assert(!version);
131 
132  /*
133  * If the referenced object is pinned by the system, there's no real
134  * need to record dependencies on it, unless we need to record a
135  * version. This saves lots of space in pg_depend, so it's worth the
136  * time taken to check.
137  */
138  if (!ignore_systempin && isObjectPinned(referenced, dependDesc))
139  continue;
140 
141  if (slot_init_count < max_slots)
142  {
143  slot[slot_stored_count] = MakeSingleTupleTableSlot(RelationGetDescr(dependDesc),
144  &TTSOpsHeapTuple);
145  slot_init_count++;
146  }
147 
148  ExecClearTuple(slot[slot_stored_count]);
149 
150  /*
151  * Record the dependency. Note we don't bother to check for duplicate
152  * dependencies; there's no harm in them.
153  */
154  memset(slot[slot_stored_count]->tts_isnull, false,
155  slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
156 
157  slot[slot_stored_count]->tts_values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
158  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
159  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
160  slot[slot_stored_count]->tts_values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
161  slot[slot_stored_count]->tts_values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
162  slot[slot_stored_count]->tts_values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
163  slot[slot_stored_count]->tts_values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
164  if (version)
165  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjversion - 1] = CStringGetTextDatum(version);
166  else
167  slot[slot_stored_count]->tts_isnull[Anum_pg_depend_refobjversion - 1] = true;
168 
169  ExecStoreVirtualTuple(slot[slot_stored_count]);
170  slot_stored_count++;
171 
172  /* If slots are full, insert a batch of tuples */
173  if (slot_stored_count == max_slots)
174  {
175  /* fetch index info only when we know we need it */
176  if (indstate == NULL)
177  indstate = CatalogOpenIndexes(dependDesc);
178 
179  CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
180  indstate);
181  slot_stored_count = 0;
182  }
183  }
184 
185  /* Insert any tuples left in the buffer */
186  if (slot_stored_count > 0)
187  {
188  /* fetch index info only when we know we need it */
189  if (indstate == NULL)
190  indstate = CatalogOpenIndexes(dependDesc);
191 
192  CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
193  indstate);
194  }
195 
196  if (indstate != NULL)
197  CatalogCloseIndexes(indstate);
198 
199  table_close(dependDesc, RowExclusiveLock);
200 
201  /* Drop only the number of slots used */
202  for (i = 0; i < slot_init_count; i++)
204  pfree(slot);
205 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition: tuptable.h:425
#define RelationGetDescr(relation)
Definition: rel.h:483
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1208
#define MAX_CATALOG_MULTI_INSERT_BYTES
Definition: indexing.h:33
#define Min(x, y)
Definition: c.h:982
Datum * tts_values
Definition: tuptable.h:126
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:683
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
void CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot, int ntuples, CatalogIndexState indstate)
Definition: indexing.c:261
bool * tts_isnull
Definition: tuptable.h:128
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
#define RowExclusiveLock
Definition: lockdefs.h:38
char * get_collation_version_for_oid(Oid oid)
Definition: pg_locale.c:1758
#define Assert(condition)
Definition: c.h:800
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:43
#define CharGetDatum(X)
Definition: postgres.h:416
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:393
#define Int32GetDatum(X)
Definition: postgres.h:479
void * palloc(Size size)
Definition: mcxt.c:950
int i
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:84
#define CStringGetTextDatum(s)
Definition: builtins.h:86
void CatalogCloseIndexes(CatalogIndexState indstate)
Definition: indexing.c:61
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
FormData_pg_depend
Definition: pg_depend.h:67
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1522

◆ 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:167
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1233
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:967
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Assert(condition)
Definition: c.h:800
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:393
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ ReleaseDeletionLock()

void ReleaseDeletionLock ( const ObjectAddress object)

Definition at line 1632 of file dependency.c.

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

Referenced by findDependentObjects(), and shdepDropOwned().

1633 {
1634  if (object->classId == RelationRelationId)
1636  else
1637  /* assume we should lock the whole object not a sub-object */
1638  UnlockDatabaseObject(object->classId, object->objectId, 0,
1640 }
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:199
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:997
#define AccessExclusiveLock
Definition: lockdefs.h:45

◆ sequenceIsOwned()

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

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

838 {
839  bool ret = false;
840  Relation depRel;
841  ScanKeyData key[2];
842  SysScanDesc scan;
843  HeapTuple tup;
844 
845  depRel = table_open(DependRelationId, AccessShareLock);
846 
847  ScanKeyInit(&key[0],
848  Anum_pg_depend_classid,
849  BTEqualStrategyNumber, F_OIDEQ,
850  ObjectIdGetDatum(RelationRelationId));
851  ScanKeyInit(&key[1],
852  Anum_pg_depend_objid,
853  BTEqualStrategyNumber, F_OIDEQ,
854  ObjectIdGetDatum(seqId));
855 
856  scan = systable_beginscan(depRel, DependDependerIndexId, true,
857  NULL, 2, key);
858 
859  while (HeapTupleIsValid((tup = systable_getnext(scan))))
860  {
861  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
862 
863  if (depform->refclassid == RelationRelationId &&
864  depform->deptype == deptype)
865  {
866  *tableId = depform->refobjid;
867  *colId = depform->refobjsubid;
868  ret = true;
869  break; /* no need to keep scanning */
870  }
871  }
872 
873  systable_endscan(scan);
874 
875  table_close(depRel, AccessShareLock);
876 
877  return ret;
878 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#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 1285 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().

1286 {
1287  Relation sdepRel;
1288  ListCell *cell;
1289  ObjectAddresses *deleteobjs;
1290 
1291  deleteobjs = new_object_addresses();
1292 
1293  /*
1294  * We don't need this strong a lock here, but we'll call routines that
1295  * acquire RowExclusiveLock. Better get that right now to avoid potential
1296  * deadlock failures.
1297  */
1298  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1299 
1300  /*
1301  * For each role, find the dependent objects and drop them using the
1302  * regular (non-shared) dependency management.
1303  */
1304  foreach(cell, roleids)
1305  {
1306  Oid roleid = lfirst_oid(cell);
1307  ScanKeyData key[2];
1308  SysScanDesc scan;
1309  HeapTuple tuple;
1310 
1311  /* Doesn't work for pinned objects */
1312  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1313  {
1314  ObjectAddress obj;
1315 
1316  obj.classId = AuthIdRelationId;
1317  obj.objectId = roleid;
1318  obj.objectSubId = 0;
1319 
1320  ereport(ERROR,
1321  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1322  errmsg("cannot drop objects owned by %s because they are "
1323  "required by the database system",
1324  getObjectDescription(&obj, false))));
1325  }
1326 
1327  ScanKeyInit(&key[0],
1328  Anum_pg_shdepend_refclassid,
1329  BTEqualStrategyNumber, F_OIDEQ,
1330  ObjectIdGetDatum(AuthIdRelationId));
1331  ScanKeyInit(&key[1],
1332  Anum_pg_shdepend_refobjid,
1333  BTEqualStrategyNumber, F_OIDEQ,
1334  ObjectIdGetDatum(roleid));
1335 
1336  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1337  NULL, 2, key);
1338 
1339  while ((tuple = systable_getnext(scan)) != NULL)
1340  {
1341  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1342  ObjectAddress obj;
1343 
1344  /*
1345  * We only operate on shared objects and objects in the current
1346  * database
1347  */
1348  if (sdepForm->dbid != MyDatabaseId &&
1349  sdepForm->dbid != InvalidOid)
1350  continue;
1351 
1352  switch (sdepForm->deptype)
1353  {
1354  /* Shouldn't happen */
1355  case SHARED_DEPENDENCY_PIN:
1357  elog(ERROR, "unexpected dependency type");
1358  break;
1359  case SHARED_DEPENDENCY_ACL:
1360  RemoveRoleFromObjectACL(roleid,
1361  sdepForm->classid,
1362  sdepForm->objid);
1363  break;
1365 
1366  /*
1367  * Try to remove role from policy; if unable to, remove
1368  * policy.
1369  */
1370  if (!RemoveRoleFromObjectPolicy(roleid,
1371  sdepForm->classid,
1372  sdepForm->objid))
1373  {
1374  obj.classId = sdepForm->classid;
1375  obj.objectId = sdepForm->objid;
1376  obj.objectSubId = sdepForm->objsubid;
1377 
1378  /*
1379  * Acquire lock on object, then verify this dependency
1380  * is still relevant. If not, the object might have
1381  * been dropped or the policy modified. Ignore the
1382  * object in that case.
1383  */
1384  AcquireDeletionLock(&obj, 0);
1385  if (!systable_recheck_tuple(scan, tuple))
1386  {
1387  ReleaseDeletionLock(&obj);
1388  break;
1389  }
1390  add_exact_object_address(&obj, deleteobjs);
1391  }
1392  break;
1394  /* If a local object, save it for deletion below */
1395  if (sdepForm->dbid == MyDatabaseId)
1396  {
1397  obj.classId = sdepForm->classid;
1398  obj.objectId = sdepForm->objid;
1399  obj.objectSubId = sdepForm->objsubid;
1400  /* as above */
1401  AcquireDeletionLock(&obj, 0);
1402  if (!systable_recheck_tuple(scan, tuple))
1403  {
1404  ReleaseDeletionLock(&obj);
1405  break;
1406  }
1407  add_exact_object_address(&obj, deleteobjs);
1408  }
1409  break;
1410  }
1411  }
1412 
1413  systable_endscan(scan);
1414  }
1415 
1416  /*
1417  * For stability of deletion-report ordering, sort the objects into
1418  * approximate reverse creation order before deletion. (This might also
1419  * make the deletion go a bit faster, since there's less chance of having
1420  * to rearrange the objects due to dependencies.)
1421  */
1422  sort_object_addresses(deleteobjs);
1423 
1424  /* the dependency mechanism does the actual work */
1425  performMultipleDeletions(deleteobjs, behavior, 0);
1426 
1427  table_close(sdepRel, RowExclusiveLock);
1428 
1429  free_object_addresses(deleteobjs);
1430 }
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1233
void sort_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2823
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:70
void ReleaseDeletionLock(const ObjectAddress *object)
Definition: dependency.c:1632
int errcode(int sqlerrcode)
Definition: elog.c:691
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2594
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition: aclchk.c:1377
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2539
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2835
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:357
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Definition: genam.c:535
bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
Definition: policy.c:419
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define SharedDependReferenceIndexId
Definition: pg_shdepend.h:75
#define RowExclusiveLock
Definition: lockdefs.h:38
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1603
Oid MyDatabaseId
Definition: globals.c:85
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:902
#define elog(elevel,...)
Definition: elog.h:228
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:372
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:171

◆ shdepLockAndCheckObject()

void shdepLockAndCheckObject ( Oid  classId,
Oid  objectId 
)

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

1110 {
1111  /* AccessShareLock should be OK, since we are not modifying the object */
1112  LockSharedObject(classId, objectId, 0, AccessShareLock);
1113 
1114  switch (classId)
1115  {
1116  case AuthIdRelationId:
1118  ereport(ERROR,
1119  (errcode(ERRCODE_UNDEFINED_OBJECT),
1120  errmsg("role %u was concurrently dropped",
1121  objectId)));
1122  break;
1123 
1124  /*
1125  * Currently, this routine need not support any other shared
1126  * object types besides roles. If we wanted to record explicit
1127  * dependencies on databases or tablespaces, we'd need code along
1128  * these lines:
1129  */
1130 #ifdef NOT_USED
1131  case TableSpaceRelationId:
1132  {
1133  /* For lack of a syscache on pg_tablespace, do this: */
1134  char *tablespace = get_tablespace_name(objectId);
1135 
1136  if (tablespace == NULL)
1137  ereport(ERROR,
1138  (errcode(ERRCODE_UNDEFINED_OBJECT),
1139  errmsg("tablespace %u was concurrently dropped",
1140  objectId)));
1141  pfree(tablespace);
1142  break;
1143  }
1144 #endif
1145 
1146  case DatabaseRelationId:
1147  {
1148  /* For lack of a syscache on pg_database, do this: */
1149  char *database = get_database_name(objectId);
1150 
1151  if (database == NULL)
1152  ereport(ERROR,
1153  (errcode(ERRCODE_UNDEFINED_OBJECT),
1154  errmsg("database %u was concurrently dropped",
1155  objectId)));
1156  pfree(database);
1157  break;
1158  }
1159 
1160 
1161  default:
1162  elog(ERROR, "unrecognized shared classId: %u", classId);
1163  }
1164 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:691
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
void pfree(void *pointer)
Definition: mcxt.c:1057
#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:189
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1017
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:902
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1467
#define elog(elevel,...)
Definition: elog.h:228

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

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

1440 {
1441  Relation sdepRel;
1442  ListCell *cell;
1443 
1444  /*
1445  * We don't need this strong a lock here, but we'll call routines that
1446  * acquire RowExclusiveLock. Better get that right now to avoid potential
1447  * deadlock problems.
1448  */
1449  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1450 
1451  foreach(cell, roleids)
1452  {
1453  SysScanDesc scan;
1454  ScanKeyData key[2];
1455  HeapTuple tuple;
1456  Oid roleid = lfirst_oid(cell);
1457 
1458  /* Refuse to work on pinned roles */
1459  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1460  {
1461  ObjectAddress obj;
1462 
1463  obj.classId = AuthIdRelationId;
1464  obj.objectId = roleid;
1465  obj.objectSubId = 0;
1466 
1467  ereport(ERROR,
1468  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1469  errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
1470  getObjectDescription(&obj, false))));
1471 
1472  /*
1473  * There's no need to tell the whole truth, which is that we
1474  * didn't track these dependencies at all ...
1475  */
1476  }
1477 
1478  ScanKeyInit(&key[0],
1479  Anum_pg_shdepend_refclassid,
1480  BTEqualStrategyNumber, F_OIDEQ,
1481  ObjectIdGetDatum(AuthIdRelationId));
1482  ScanKeyInit(&key[1],
1483  Anum_pg_shdepend_refobjid,
1484  BTEqualStrategyNumber, F_OIDEQ,
1485  ObjectIdGetDatum(roleid));
1486 
1487  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1488  NULL, 2, key);
1489 
1490  while ((tuple = systable_getnext(scan)) != NULL)
1491  {
1492  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1493 
1494  /*
1495  * We only operate on shared objects and objects in the current
1496  * database
1497  */
1498  if (sdepForm->dbid != MyDatabaseId &&
1499  sdepForm->dbid != InvalidOid)
1500  continue;
1501 
1502  /* Unexpected because we checked for pins above */
1503  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
1504  elog(ERROR, "unexpected shared pin");
1505 
1506  /* We leave non-owner dependencies alone */
1507  if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
1508  continue;
1509 
1510  /* Issue the appropriate ALTER OWNER call */
1511  switch (sdepForm->classid)
1512  {
1513  case TypeRelationId:
1514  AlterTypeOwner_oid(sdepForm->objid, newrole, true);
1515  break;
1516 
1517  case NamespaceRelationId:
1518  AlterSchemaOwner_oid(sdepForm->objid, newrole);
1519  break;
1520 
1521  case RelationRelationId:
1522 
1523  /*
1524  * Pass recursing = true so that we don't fail on indexes,
1525  * owned sequences, etc when we happen to visit them
1526  * before their parent table.
1527  */
1528  ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
1529  break;
1530 
1531  case DefaultAclRelationId:
1532 
1533  /*
1534  * Ignore default ACLs; they should be handled by DROP
1535  * OWNED, not REASSIGN OWNED.
1536  */
1537  break;
1538 
1539  case UserMappingRelationId:
1540  /* ditto */
1541  break;
1542 
1543  case ForeignServerRelationId:
1544  AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1545  break;
1546 
1547  case ForeignDataWrapperRelationId:
1548  AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1549  break;
1550 
1551  case EventTriggerRelationId:
1552  AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
1553  break;
1554 
1555  case PublicationRelationId:
1556  AlterPublicationOwner_oid(sdepForm->objid, newrole);
1557  break;
1558 
1559  case SubscriptionRelationId:
1560  AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
1561  break;
1562 
1563  /* Generic alter owner cases */
1564  case CollationRelationId:
1565  case ConversionRelationId:
1566  case OperatorRelationId:
1567  case ProcedureRelationId:
1568  case LanguageRelationId:
1569  case LargeObjectRelationId:
1570  case OperatorFamilyRelationId:
1571  case OperatorClassRelationId:
1572  case ExtensionRelationId:
1573  case StatisticExtRelationId:
1574  case TableSpaceRelationId:
1575  case DatabaseRelationId:
1576  case TSConfigRelationId:
1577  case TSDictionaryRelationId:
1578  {
1579  Oid classId = sdepForm->classid;
1580  Relation catalog;
1581 
1582  if (classId == LargeObjectRelationId)
1583  classId = LargeObjectMetadataRelationId;
1584 
1585  catalog = table_open(classId, RowExclusiveLock);
1586 
1587  AlterObjectOwner_internal(catalog, sdepForm->objid,
1588  newrole);
1589 
1590  table_close(catalog, NoLock);
1591  }
1592  break;
1593 
1594  default:
1595  elog(ERROR, "unexpected classid %u", sdepForm->classid);
1596  break;
1597  }
1598  /* Make sure the next iteration will see my changes */
1600  }
1601 
1602  systable_endscan(scan);
1603  }
1604 
1605  table_close(sdepRel, RowExclusiveLock);
1606 }
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#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:1233
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:691
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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define SharedDependReferenceIndexId
Definition: pg_shdepend.h:75
void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
Definition: typecmds.c:3363
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:12514
void CommandCounterIncrement(void)
Definition: xact.c:1021
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:155
#define AccessExclusiveLock
Definition: lockdefs.h:45
int errmsg(const char *fmt,...)
Definition: elog.c:902
#define elog(elevel,...)
Definition: elog.h:228
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)
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:171

◆ sort_object_addresses()

void sort_object_addresses ( ObjectAddresses addrs)

Definition at line 2823 of file dependency.c.

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

Referenced by shdepDropOwned().

2824 {
2825  if (addrs->numrefs > 1)
2826  qsort((void *) addrs->refs, addrs->numrefs,
2827  sizeof(ObjectAddress),
2829 }
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2495
ObjectAddress * refs
Definition: dependency.c:112
#define qsort(a, b, c, d)
Definition: port.h:497

◆ 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:167
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1233
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:967
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:1057
#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:1022
int i
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ visitDependenciesOf()

void visitDependenciesOf ( const ObjectAddress object,
VisitDependenciesOfCB  callback,
void *  data 
)

Definition at line 443 of file dependency.c.

References BTEqualStrategyNumber, callback(), CatalogTupleUpdate(), ObjectAddress::classId, CStringGetTextDatum, DependDependerIndexId, GETSTRUCT, heap_freetuple(), heap_getattr, heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum, sort-test::key, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), table_open(), TextDatumGetCString, and values.

Referenced by index_check_collation_versions(), and index_update_collation_versions().

446 {
447  Relation depRel;
448  ScanKeyData key[3];
449  SysScanDesc scan;
450  HeapTuple tup;
451  ObjectAddress otherObject;
452 
453  ScanKeyInit(&key[0],
454  Anum_pg_depend_classid,
455  BTEqualStrategyNumber, F_OIDEQ,
456  ObjectIdGetDatum(object->classId));
457  ScanKeyInit(&key[1],
458  Anum_pg_depend_objid,
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(object->objectId));
461  ScanKeyInit(&key[2],
462  Anum_pg_depend_objsubid,
463  BTEqualStrategyNumber, F_INT4EQ,
464  Int32GetDatum(object->objectSubId));
465 
466  depRel = table_open(DependRelationId, RowExclusiveLock);
467  scan = systable_beginscan(depRel, DependDependerIndexId, true,
468  NULL, 3, key);
469 
470  while (HeapTupleIsValid(tup = systable_getnext(scan)))
471  {
472  Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
473  char *new_version;
474  Datum depversion;
475  bool isnull;
476 
477  otherObject.classId = foundDep->refclassid;
478  otherObject.objectId = foundDep->refobjid;
479  otherObject.objectSubId = foundDep->refobjsubid;
480 
481  depversion = heap_getattr(tup, Anum_pg_depend_refobjversion,
482  RelationGetDescr(depRel), &isnull);
483 
484  /* Does the callback want to update the version? */
485  if (callback(&otherObject,
486  isnull ? NULL : TextDatumGetCString(depversion),
487  &new_version,
488  userdata))
489  {
490  Datum values[Natts_pg_depend];
491  bool nulls[Natts_pg_depend];
492  bool replaces[Natts_pg_depend];
493 
494  memset(values, 0, sizeof(values));
495  memset(nulls, false, sizeof(nulls));
496  memset(replaces, false, sizeof(replaces));
497 
498  if (new_version)
499  values[Anum_pg_depend_refobjversion - 1] =
500  CStringGetTextDatum(new_version);
501  else
502  nulls[Anum_pg_depend_refobjversion - 1] = true;
503  replaces[Anum_pg_depend_refobjversion - 1] = true;
504 
505  tup = heap_modify_tuple(tup, RelationGetDescr(depRel), values,
506  nulls, replaces);
507  CatalogTupleUpdate(depRel, &tup->t_self, tup);
508 
509  heap_freetuple(tup);
510  }
511  }
512  systable_endscan(scan);
513  table_close(depRel, RowExclusiveLock);
514 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:483
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:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:74
#define DependDependerIndexId
Definition: pg_depend.h:79
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
#define TextDatumGetCString(d)
Definition: builtins.h:87
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
static Datum values[MAXATTR]
Definition: bootstrap.c:165
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define CStringGetTextDatum(s)
Definition: builtins.h:86
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