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_TABLESPACE = 't', 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_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 recordDependencyOnTablespace (Oid classId, Oid objectId, Oid tablespace)
 
void changeDependencyOnTablespace (Oid classId, Oid objectId, Oid newTablespaceId)
 
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 138 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 146 of file dependency.h.

Referenced by doDeletion(), and ReindexRelationConcurrently().

◆ PERFORM_DELETION_CONCURRENTLY

#define PERFORM_DELETION_CONCURRENTLY   0x0002 /* concurrent drop */

Definition at line 142 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 145 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 144 of file dependency.h.

Referenced by deleteObjectsInList(), and RemoveTempRelations().

Typedef Documentation

◆ DependencyType

◆ ObjectAddresses

Definition at line 90 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 191 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 96 of file dependency.h.

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

◆ SharedDependencyType

Enumerator
SHARED_DEPENDENCY_PIN 
SHARED_DEPENDENCY_OWNER 
SHARED_DEPENDENCY_ACL 
SHARED_DEPENDENCY_POLICY 
SHARED_DEPENDENCY_TABLESPACE 
SHARED_DEPENDENCY_INVALID 

Definition at line 79 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:142
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:975
#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 2625 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().

2627 {
2628  ObjectAddress *item;
2629 
2630  /* enlarge array if needed */
2631  if (addrs->numrefs >= addrs->maxrefs)
2632  {
2633  addrs->maxrefs *= 2;
2634  addrs->refs = (ObjectAddress *)
2635  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2636  Assert(!addrs->extras);
2637  }
2638  /* record this item */
2639  item = addrs->refs + addrs->numrefs;
2640  *item = *object;
2641  addrs->numrefs++;
2642 }
ObjectAddress * refs
Definition: dependency.c:112
#define Assert(condition)
Definition: c.h:804
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 539 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().

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

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

432 {
433  long count = 0;
434  Relation depRel;
435  ScanKeyData key[2];
436  SysScanDesc scan;
437  HeapTuple tup;
438  ObjectAddress objAddr;
439  ObjectAddress depAddr;
440  bool oldIsPinned;
441  bool newIsPinned;
442 
443  depRel = table_open(DependRelationId, RowExclusiveLock);
444 
445  /*
446  * Check to see if either oldRefObjectId or newRefObjectId is pinned.
447  * Pinned objects should not have any dependency entries pointing to them,
448  * so in these cases we should add or remove a pg_depend entry, or do
449  * nothing at all, rather than update an entry as in the normal case.
450  */
451  objAddr.classId = refClassId;
452  objAddr.objectId = oldRefObjectId;
453  objAddr.objectSubId = 0;
454 
455  oldIsPinned = isObjectPinned(&objAddr, depRel);
456 
457  objAddr.objectId = newRefObjectId;
458 
459  newIsPinned = isObjectPinned(&objAddr, depRel);
460 
461  if (oldIsPinned)
462  {
463  table_close(depRel, RowExclusiveLock);
464 
465  /*
466  * If both are pinned, we need do nothing. However, return 1 not 0,
467  * else callers will think this is an error case.
468  */
469  if (newIsPinned)
470  return 1;
471 
472  /*
473  * There is no old dependency record, but we should insert a new one.
474  * Assume a normal dependency is wanted.
475  */
476  depAddr.classId = classId;
477  depAddr.objectId = objectId;
478  depAddr.objectSubId = 0;
479  recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL);
480 
481  return 1;
482  }
483 
484  /* There should be existing dependency record(s), so search. */
485  ScanKeyInit(&key[0],
486  Anum_pg_depend_classid,
487  BTEqualStrategyNumber, F_OIDEQ,
488  ObjectIdGetDatum(classId));
489  ScanKeyInit(&key[1],
490  Anum_pg_depend_objid,
491  BTEqualStrategyNumber, F_OIDEQ,
492  ObjectIdGetDatum(objectId));
493 
494  scan = systable_beginscan(depRel, DependDependerIndexId, true,
495  NULL, 2, key);
496 
497  while (HeapTupleIsValid((tup = systable_getnext(scan))))
498  {
499  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
500 
501  if (depform->refclassid == refClassId &&
502  depform->refobjid == oldRefObjectId)
503  {
504  if (newIsPinned)
505  CatalogTupleDelete(depRel, &tup->t_self);
506  else
507  {
508  /* make a modifiable copy */
509  tup = heap_copytuple(tup);
510  depform = (Form_pg_depend) GETSTRUCT(tup);
511 
512  depform->refobjid = newRefObjectId;
513 
514  CatalogTupleUpdate(depRel, &tup->t_self, tup);
515 
516  heap_freetuple(tup);
517  }
518 
519  count++;
520  }
521  }
522 
523  systable_endscan(scan);
524 
525  table_close(depRel, RowExclusiveLock);
526 
527  return count;
528 }
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:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:351
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:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:684
#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:76
#define DependDependerIndexId
Definition: pg_depend.h:81
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:302
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 313 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().

314 {
315  Relation sdepRel;
316 
317  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
318 
319  /* Adjust the SHARED_DEPENDENCY_OWNER entry */
320  shdepChangeDep(sdepRel,
321  classId, objectId, 0,
322  AuthIdRelationId, newOwnerId,
324 
325  /*----------
326  * There should never be a SHARED_DEPENDENCY_ACL entry for the owner,
327  * so get rid of it if there is one. This can happen if the new owner
328  * was previously granted some rights to the object.
329  *
330  * This step is analogous to aclnewowner's removal of duplicate entries
331  * in the ACL. We have to do it to handle this scenario:
332  * A grants some rights on an object to B
333  * ALTER OWNER changes the object's owner to B
334  * ALTER OWNER changes the object's owner to C
335  * The third step would remove all mention of B from the object's ACL,
336  * but we'd still have a SHARED_DEPENDENCY_ACL for B if we did not do
337  * things this way.
338  *
339  * The rule against having a SHARED_DEPENDENCY_ACL entry for the owner
340  * allows us to fix things up in just this one place, without having
341  * to make the various ALTER OWNER routines each know about it.
342  *----------
343  */
344  shdepDropDependency(sdepRel, classId, objectId, 0, true,
345  AuthIdRelationId, newOwnerId,
347 
348  table_close(sdepRel, RowExclusiveLock);
349 }
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:203
#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:1078
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ changeDependencyOnTablespace()

void changeDependencyOnTablespace ( Oid  classId,
Oid  objectId,
Oid  newTablespaceId 
)

Definition at line 382 of file pg_shdepend.c.

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

Referenced by SetRelationTableSpace().

383 {
384  Relation sdepRel;
385 
386  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
387 
388  if (newTablespaceId != DEFAULTTABLESPACE_OID &&
389  newTablespaceId != InvalidOid)
390  shdepChangeDep(sdepRel,
391  classId, objectId, 0,
392  TableSpaceRelationId, newTablespaceId,
394  else
395  shdepDropDependency(sdepRel,
396  classId, objectId, 0, true,
399 
400  table_close(sdepRel, RowExclusiveLock);
401 }
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:203
#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:1078
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 633 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(), and DropTableSpace().

635 {
636  Relation sdepRel;
637  ScanKeyData key[2];
638  SysScanDesc scan;
639  HeapTuple tup;
640  int numReportedDeps = 0;
641  int numNotReportedDeps = 0;
642  int numNotReportedDbs = 0;
643  List *remDeps = NIL;
644  ListCell *cell;
645  ObjectAddress object;
646  ShDependObjectInfo *objects;
647  int numobjects;
648  int allocedobjects;
649  StringInfoData descs;
650  StringInfoData alldescs;
651 
652  /*
653  * We limit the number of dependencies reported to the client to
654  * MAX_REPORTED_DEPS, since client software may not deal well with
655  * enormous error strings. The server log always gets a full report.
656  *
657  * For stability of regression test results, we sort local and shared
658  * objects by OID before reporting them. We don't worry about the order
659  * in which other databases are reported, though.
660  */
661 #define MAX_REPORTED_DEPS 100
662 
663  allocedobjects = 128; /* arbitrary initial array size */
664  objects = (ShDependObjectInfo *)
665  palloc(allocedobjects * sizeof(ShDependObjectInfo));
666  numobjects = 0;
667  initStringInfo(&descs);
668  initStringInfo(&alldescs);
669 
670  sdepRel = table_open(SharedDependRelationId, AccessShareLock);
671 
672  ScanKeyInit(&key[0],
673  Anum_pg_shdepend_refclassid,
674  BTEqualStrategyNumber, F_OIDEQ,
675  ObjectIdGetDatum(classId));
676  ScanKeyInit(&key[1],
677  Anum_pg_shdepend_refobjid,
678  BTEqualStrategyNumber, F_OIDEQ,
679  ObjectIdGetDatum(objectId));
680 
681  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
682  NULL, 2, key);
683 
684  while (HeapTupleIsValid(tup = systable_getnext(scan)))
685  {
686  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tup);
687 
688  /* This case can be dispatched quickly */
689  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
690  {
691  object.classId = classId;
692  object.objectId = objectId;
693  object.objectSubId = 0;
694  ereport(ERROR,
695  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
696  errmsg("cannot drop %s because it is required by the database system",
697  getObjectDescription(&object, false))));
698  }
699 
700  object.classId = sdepForm->classid;
701  object.objectId = sdepForm->objid;
702  object.objectSubId = sdepForm->objsubid;
703 
704  /*
705  * If it's a dependency local to this database or it's a shared
706  * object, add it to the objects array.
707  *
708  * If it's a remote dependency, keep track of it so we can report the
709  * number of them later.
710  */
711  if (sdepForm->dbid == MyDatabaseId ||
712  sdepForm->dbid == InvalidOid)
713  {
714  if (numobjects >= allocedobjects)
715  {
716  allocedobjects *= 2;
717  objects = (ShDependObjectInfo *)
718  repalloc(objects,
719  allocedobjects * sizeof(ShDependObjectInfo));
720  }
721  objects[numobjects].object = object;
722  objects[numobjects].deptype = sdepForm->deptype;
723  objects[numobjects].objtype = (sdepForm->dbid == MyDatabaseId) ?
725  numobjects++;
726  }
727  else
728  {
729  /* It's not local nor shared, so it must be remote. */
730  remoteDep *dep;
731  bool stored = false;
732 
733  /*
734  * XXX this info is kept on a simple List. Maybe it's not good
735  * for performance, but using a hash table seems needlessly
736  * complex. The expected number of databases is not high anyway,
737  * I suppose.
738  */
739  foreach(cell, remDeps)
740  {
741  dep = lfirst(cell);
742  if (dep->dbOid == sdepForm->dbid)
743  {
744  dep->count++;
745  stored = true;
746  break;
747  }
748  }
749  if (!stored)
750  {
751  dep = (remoteDep *) palloc(sizeof(remoteDep));
752  dep->dbOid = sdepForm->dbid;
753  dep->count = 1;
754  remDeps = lappend(remDeps, dep);
755  }
756  }
757  }
758 
759  systable_endscan(scan);
760 
761  table_close(sdepRel, AccessShareLock);
762 
763  /*
764  * Sort and report local and shared objects.
765  */
766  if (numobjects > 1)
767  qsort((void *) objects, numobjects,
769 
770  for (int i = 0; i < numobjects; i++)
771  {
772  if (numReportedDeps < MAX_REPORTED_DEPS)
773  {
774  numReportedDeps++;
775  storeObjectDescription(&descs,
776  objects[i].objtype,
777  &objects[i].object,
778  objects[i].deptype,
779  0);
780  }
781  else
782  numNotReportedDeps++;
783  storeObjectDescription(&alldescs,
784  objects[i].objtype,
785  &objects[i].object,
786  objects[i].deptype,
787  0);
788  }
789 
790  /*
791  * Summarize dependencies in remote databases.
792  */
793  foreach(cell, remDeps)
794  {
795  remoteDep *dep = lfirst(cell);
796 
797  object.classId = DatabaseRelationId;
798  object.objectId = dep->dbOid;
799  object.objectSubId = 0;
800 
801  if (numReportedDeps < MAX_REPORTED_DEPS)
802  {
803  numReportedDeps++;
804  storeObjectDescription(&descs, REMOTE_OBJECT, &object,
806  }
807  else
808  numNotReportedDbs++;
809  storeObjectDescription(&alldescs, REMOTE_OBJECT, &object,
811  }
812 
813  pfree(objects);
814  list_free_deep(remDeps);
815 
816  if (descs.len == 0)
817  {
818  pfree(descs.data);
819  pfree(alldescs.data);
820  *detail_msg = *detail_log_msg = NULL;
821  return false;
822  }
823 
824  if (numNotReportedDeps > 0)
825  appendStringInfo(&descs, ngettext("\nand %d other object "
826  "(see server log for list)",
827  "\nand %d other objects "
828  "(see server log for list)",
829  numNotReportedDeps),
830  numNotReportedDeps);
831  if (numNotReportedDbs > 0)
832  appendStringInfo(&descs, ngettext("\nand objects in %d other database "
833  "(see server log for list)",
834  "\nand objects in %d other databases "
835  "(see server log for list)",
836  numNotReportedDbs),
837  numNotReportedDbs);
838 
839  *detail_msg = descs.data;
840  *detail_log_msg = alldescs.data;
841  return true;
842 }
#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:565
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:73
#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:1230
int errcode(int sqlerrcode)
Definition: elog.c:694
void list_free_deep(List *list)
Definition: list.c:1405
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
SharedDependencyObjectType objtype
Definition: pg_shdepend.c:81
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
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:45
#define SharedDependReferenceIndexId
Definition: pg_shdepend.h:78
List * lappend(List *list, void *datum)
Definition: list.c:336
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define ngettext(s, p, n)
Definition: c.h:1182
Oid MyDatabaseId
Definition: globals.c:86
#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:905
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:504
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:79

◆ copyTemplateDependencies()

void copyTemplateDependencies ( Oid  templateDbId,
Oid  newDbId 
)

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

853 {
854  Relation sdepRel;
855  TupleDesc sdepDesc;
856  ScanKeyData key[1];
857  SysScanDesc scan;
858  HeapTuple tup;
859  CatalogIndexState indstate;
860  TupleTableSlot **slot;
861  int max_slots,
862  slot_init_count,
863  slot_stored_count;
864 
865  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
866  sdepDesc = RelationGetDescr(sdepRel);
867 
868  /*
869  * Allocate the slots to use, but delay costly initialization until we
870  * know that they will be used.
871  */
873  slot = palloc(sizeof(TupleTableSlot *) * max_slots);
874 
875  indstate = CatalogOpenIndexes(sdepRel);
876 
877  /* Scan all entries with dbid = templateDbId */
878  ScanKeyInit(&key[0],
879  Anum_pg_shdepend_dbid,
880  BTEqualStrategyNumber, F_OIDEQ,
881  ObjectIdGetDatum(templateDbId));
882 
883  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
884  NULL, 1, key);
885 
886  /* number of slots currently storing tuples */
887  slot_stored_count = 0;
888  /* number of slots currently initialized */
889  slot_init_count = 0;
890 
891  /*
892  * Copy the entries of the original database, changing the database Id to
893  * that of the new database. Note that because we are not copying rows
894  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
895  * copy the ownership dependency of the template database itself; this is
896  * what we want.
897  */
898  while (HeapTupleIsValid(tup = systable_getnext(scan)))
899  {
900  Form_pg_shdepend shdep;
901 
902  if (slot_init_count < max_slots)
903  {
904  slot[slot_stored_count] = MakeSingleTupleTableSlot(sdepDesc, &TTSOpsHeapTuple);
905  slot_init_count++;
906  }
907 
908  ExecClearTuple(slot[slot_stored_count]);
909 
910  shdep = (Form_pg_shdepend) GETSTRUCT(tup);
911 
912  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_dbid] = ObjectIdGetDatum(newDbId);
913  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_classid] = shdep->classid;
914  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objid] = shdep->objid;
915  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_objsubid] = shdep->objsubid;
916  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refclassid] = shdep->refclassid;
917  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_refobjid] = shdep->refobjid;
918  slot[slot_stored_count]->tts_values[Anum_pg_shdepend_deptype] = shdep->deptype;
919 
920  ExecStoreVirtualTuple(slot[slot_stored_count]);
921  slot_stored_count++;
922 
923  /* If slots are full, insert a batch of tuples */
924  if (slot_stored_count == max_slots)
925  {
926  CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
927  slot_stored_count = 0;
928  }
929  }
930 
931  /* Insert any tuples left in the buffer */
932  if (slot_stored_count > 0)
933  CatalogTuplesMultiInsertWithInfo(sdepRel, slot, slot_stored_count, indstate);
934 
935  systable_endscan(scan);
936 
937  CatalogCloseIndexes(indstate);
938  table_close(sdepRel, RowExclusiveLock);
939 
940  /* Drop only the number of slots used */
941  for (int i = 0; i < slot_init_count; i++)
943  pfree(slot);
944 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
#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:73
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:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
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:262
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:66
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:76
#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 273 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().

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

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

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

1002 {
1003  Relation sdepRel;
1004 
1005  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1006 
1007  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
1008  (objectSubId == 0),
1011 
1012  table_close(sdepRel, RowExclusiveLock);
1013 }
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:1078
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

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

954 {
955  Relation sdepRel;
956  ScanKeyData key[1];
957  SysScanDesc scan;
958  HeapTuple tup;
959 
960  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
961 
962  /*
963  * First, delete all the entries that have the database Oid in the dbid
964  * field.
965  */
966  ScanKeyInit(&key[0],
967  Anum_pg_shdepend_dbid,
968  BTEqualStrategyNumber, F_OIDEQ,
969  ObjectIdGetDatum(databaseId));
970  /* We leave the other index fields unspecified */
971 
972  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
973  NULL, 1, key);
974 
975  while (HeapTupleIsValid(tup = systable_getnext(scan)))
976  {
977  CatalogTupleDelete(sdepRel, &tup->t_self);
978  }
979 
980  systable_endscan(scan);
981 
982  /* Now delete all entries corresponding to the database itself */
983  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
986 
987  table_close(sdepRel, RowExclusiveLock);
988 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:351
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#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:1078
#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:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ free_object_addresses()

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

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

980 {
981  Oid constraintId = InvalidOid;
982  Relation depRel;
983  ScanKeyData key[3];
984  SysScanDesc scan;
985  HeapTuple tup;
986 
987  /* Search the dependency table for the index */
988  depRel = table_open(DependRelationId, AccessShareLock);
989 
990  ScanKeyInit(&key[0],
991  Anum_pg_depend_classid,
992  BTEqualStrategyNumber, F_OIDEQ,
993  ObjectIdGetDatum(RelationRelationId));
994  ScanKeyInit(&key[1],
995  Anum_pg_depend_objid,
996  BTEqualStrategyNumber, F_OIDEQ,
997  ObjectIdGetDatum(indexId));
998  ScanKeyInit(&key[2],
999  Anum_pg_depend_objsubid,
1000  BTEqualStrategyNumber, F_INT4EQ,
1001  Int32GetDatum(0));
1002 
1003  scan = systable_beginscan(depRel, DependDependerIndexId, true,
1004  NULL, 3, key);
1005 
1006  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1007  {
1008  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1009 
1010  /*
1011  * We assume any internal dependency on a constraint must be what we
1012  * are looking for.
1013  */
1014  if (deprec->refclassid == ConstraintRelationId &&
1015  deprec->refobjsubid == 0 &&
1016  deprec->deptype == DEPENDENCY_INTERNAL)
1017  {
1018  constraintId = deprec->refobjid;
1019  break;
1020  }
1021  }
1022 
1023  systable_endscan(scan);
1024  table_close(depRel, AccessShareLock);
1025 
1026  return constraintId;
1027 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
#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:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:76
#define DependDependerIndexId
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_ref_constraints()

List* get_index_ref_constraints ( Oid  indexId)

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

1036 {
1037  List *result = NIL;
1038  Relation depRel;
1039  ScanKeyData key[3];
1040  SysScanDesc scan;
1041  HeapTuple tup;
1042 
1043  /* Search the dependency table for the index */
1044  depRel = table_open(DependRelationId, AccessShareLock);
1045 
1046  ScanKeyInit(&key[0],
1047  Anum_pg_depend_refclassid,
1048  BTEqualStrategyNumber, F_OIDEQ,
1049  ObjectIdGetDatum(RelationRelationId));
1050  ScanKeyInit(&key[1],
1051  Anum_pg_depend_refobjid,
1052  BTEqualStrategyNumber, F_OIDEQ,
1053  ObjectIdGetDatum(indexId));
1054  ScanKeyInit(&key[2],
1055  Anum_pg_depend_refobjsubid,
1056  BTEqualStrategyNumber, F_INT4EQ,
1057  Int32GetDatum(0));
1058 
1059  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
1060  NULL, 3, key);
1061 
1062  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1063  {
1064  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1065 
1066  /*
1067  * We assume any normal dependency from a constraint must be what we
1068  * are looking for.
1069  */
1070  if (deprec->classid == ConstraintRelationId &&
1071  deprec->objsubid == 0 &&
1072  deprec->deptype == DEPENDENCY_NORMAL)
1073  {
1074  result = lappend_oid(result, deprec->objid);
1075  }
1076  }
1077 
1078  systable_endscan(scan);
1079  table_close(depRel, AccessShareLock);
1080 
1081  return result;
1082 }
#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:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
List * lappend_oid(List *list, Oid datum)
Definition: list.c:372
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:76
#define DependReferenceIndexId
Definition: pg_depend.h:83
#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 788 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().

789 {
790  List *result = NIL;
791  Relation depRel;
792  ScanKeyData key[2];
793  SysScanDesc scan;
794  HeapTuple tup;
795 
796  depRel = table_open(DependRelationId, AccessShareLock);
797 
798  ScanKeyInit(&key[0],
799  Anum_pg_depend_classid,
800  BTEqualStrategyNumber, F_OIDEQ,
801  ObjectIdGetDatum(classId));
802  ScanKeyInit(&key[1],
803  Anum_pg_depend_objid,
804  BTEqualStrategyNumber, F_OIDEQ,
805  ObjectIdGetDatum(objectId));
806 
807  scan = systable_beginscan(depRel, DependDependerIndexId, true,
808  NULL, 2, key);
809 
810  while (HeapTupleIsValid((tup = systable_getnext(scan))))
811  {
812  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
813 
814  if (depform->refclassid == ExtensionRelationId &&
815  depform->deptype == DEPENDENCY_AUTO_EXTENSION)
816  result = lappend_oid(result, depform->refobjid);
817  }
818 
819  systable_endscan(scan);
820 
821  table_close(depRel, AccessShareLock);
822 
823  return result;
824 }
#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:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
List * lappend_oid(List *list, Oid datum)
Definition: list.c:372
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:76
#define DependDependerIndexId
Definition: pg_depend.h:81
#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 742 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().

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

956 {
958 
959  if (list_length(seqlist) > 1)
960  elog(ERROR, "more than one owned sequence found");
961  else if (list_length(seqlist) < 1)
962  {
963  if (missing_ok)
964  return InvalidOid;
965  else
966  elog(ERROR, "no owned sequence found");
967  }
968 
969  return linitial_oid(seqlist);
970 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:887
#define ERROR
Definition: elog.h:45
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:83
#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:227
Definition: pg_list.h:50

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

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

2882 {
2883  /* only pg_class entries can have nonzero objectSubId */
2884  if (object->classId != RelationRelationId &&
2885  object->objectSubId != 0)
2886  elog(ERROR, "invalid non-zero objectSubId for object class %u",
2887  object->classId);
2888 
2889  switch (object->classId)
2890  {
2891  case RelationRelationId:
2892  /* caller must check objectSubId */
2893  return OCLASS_CLASS;
2894 
2895  case ProcedureRelationId:
2896  return OCLASS_PROC;
2897 
2898  case TypeRelationId:
2899  return OCLASS_TYPE;
2900 
2901  case CastRelationId:
2902  return OCLASS_CAST;
2903 
2904  case CollationRelationId:
2905  return OCLASS_COLLATION;
2906 
2907  case ConstraintRelationId:
2908  return OCLASS_CONSTRAINT;
2909 
2910  case ConversionRelationId:
2911  return OCLASS_CONVERSION;
2912 
2913  case AttrDefaultRelationId:
2914  return OCLASS_DEFAULT;
2915 
2916  case LanguageRelationId:
2917  return OCLASS_LANGUAGE;
2918 
2919  case LargeObjectRelationId:
2920  return OCLASS_LARGEOBJECT;
2921 
2922  case OperatorRelationId:
2923  return OCLASS_OPERATOR;
2924 
2925  case OperatorClassRelationId:
2926  return OCLASS_OPCLASS;
2927 
2928  case OperatorFamilyRelationId:
2929  return OCLASS_OPFAMILY;
2930 
2931  case AccessMethodRelationId:
2932  return OCLASS_AM;
2933 
2934  case AccessMethodOperatorRelationId:
2935  return OCLASS_AMOP;
2936 
2937  case AccessMethodProcedureRelationId:
2938  return OCLASS_AMPROC;
2939 
2940  case RewriteRelationId:
2941  return OCLASS_REWRITE;
2942 
2943  case TriggerRelationId:
2944  return OCLASS_TRIGGER;
2945 
2946  case NamespaceRelationId:
2947  return OCLASS_SCHEMA;
2948 
2949  case StatisticExtRelationId:
2950  return OCLASS_STATISTIC_EXT;
2951 
2952  case TSParserRelationId:
2953  return OCLASS_TSPARSER;
2954 
2955  case TSDictionaryRelationId:
2956  return OCLASS_TSDICT;
2957 
2958  case TSTemplateRelationId:
2959  return OCLASS_TSTEMPLATE;
2960 
2961  case TSConfigRelationId:
2962  return OCLASS_TSCONFIG;
2963 
2964  case AuthIdRelationId:
2965  return OCLASS_ROLE;
2966 
2967  case DatabaseRelationId:
2968  return OCLASS_DATABASE;
2969 
2970  case TableSpaceRelationId:
2971  return OCLASS_TBLSPACE;
2972 
2973  case ForeignDataWrapperRelationId:
2974  return OCLASS_FDW;
2975 
2976  case ForeignServerRelationId:
2977  return OCLASS_FOREIGN_SERVER;
2978 
2979  case UserMappingRelationId:
2980  return OCLASS_USER_MAPPING;
2981 
2982  case DefaultAclRelationId:
2983  return OCLASS_DEFACL;
2984 
2985  case ExtensionRelationId:
2986  return OCLASS_EXTENSION;
2987 
2988  case EventTriggerRelationId:
2989  return OCLASS_EVENT_TRIGGER;
2990 
2991  case PolicyRelationId:
2992  return OCLASS_POLICY;
2993 
2994  case PublicationRelationId:
2995  return OCLASS_PUBLICATION;
2996 
2997  case PublicationRelRelationId:
2998  return OCLASS_PUBLICATION_REL;
2999 
3000  case SubscriptionRelationId:
3001  return OCLASS_SUBSCRIPTION;
3002 
3003  case TransformRelationId:
3004  return OCLASS_TRANSFORM;
3005  }
3006 
3007  /* shouldn't get here */
3008  elog(ERROR, "unrecognized object class: %u", object->classId);
3009  return OCLASS_CLASS; /* keep compiler quiet */
3010 }
#define ERROR
Definition: elog.h:45
#define elog(elevel,...)
Definition: elog.h:227

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 946 of file pg_depend.c.

References getOwnedSequences_internal().

Referenced by ExecuteTruncateGuts().

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

◆ new_object_addresses()

ObjectAddresses* new_object_addresses ( void  )

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

2571 {
2572  ObjectAddresses *addrs;
2573 
2574  addrs = palloc(sizeof(ObjectAddresses));
2575 
2576  addrs->numrefs = 0;
2577  addrs->maxrefs = 32;
2578  addrs->refs = (ObjectAddress *)
2579  palloc(addrs->maxrefs * sizeof(ObjectAddress));
2580  addrs->extras = NULL; /* until/unless needed */
2581 
2582  return addrs;
2583 }
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 2685 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().

2687 {
2688  int i;
2689 
2690  for (i = addrs->numrefs - 1; i >= 0; i--)
2691  {
2692  const ObjectAddress *thisobj = addrs->refs + i;
2693 
2694  if (object->classId == thisobj->classId &&
2695  object->objectId == thisobj->objectId)
2696  {
2697  if (object->objectSubId == thisobj->objectSubId ||
2698  thisobj->objectSubId == 0)
2699  return true;
2700  }
2701  }
2702 
2703  return false;
2704 }
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:2570
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2866
#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:2570
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2866
#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 2834 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().

2837 {
2839  recordMultipleDependencies(depender,
2840  referenced->refs, referenced->numrefs,
2841  behavior,
2842  false);
2843 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2466
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(), makeMultirangeConstructors(), makeRangeConstructors(), process_owned_by(), publication_add_relation(), RangeCreate(), 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:2625
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2570
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2866
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2466
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 221 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().

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

◆ 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:2570
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2866
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2466
#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 165 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().

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

◆ 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:1008
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:2625
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2570
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2866
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2466
#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

◆ recordDependencyOnTablespace()

void recordDependencyOnTablespace ( Oid  classId,
Oid  objectId,
Oid  tablespace 
)

Definition at line 361 of file pg_shdepend.c.

References ObjectAddressSet, recordSharedDependencyOn(), and SHARED_DEPENDENCY_TABLESPACE.

Referenced by heap_create().

362 {
363  ObjectAddress myself,
364  referenced;
365 
366  ObjectAddressSet(myself, classId, objectId);
367  ObjectAddressSet(referenced, TableSpaceRelationId, tablespace);
368 
369  recordSharedDependencyOn(&myself, &referenced,
371 }
void recordSharedDependencyOn(ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
Definition: pg_shdepend.c:121
char * tablespace
Definition: pgbench.c:190
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40

◆ 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  false);
121 
122  /*
123  * Default collation is pinned, so we need to force recording
124  * the dependency to store the version.
125  */
126  if (referenced->objectId == DEFAULT_COLLATION_OID)
127  ignore_systempin = true;
128  }
129  }
130  else
131  Assert(!version);
132 
133  /*
134  * If the referenced object is pinned by the system, there's no real
135  * need to record dependencies on it, unless we need to record a
136  * version. This saves lots of space in pg_depend, so it's worth the
137  * time taken to check.
138  */
139  if (!ignore_systempin && isObjectPinned(referenced, dependDesc))
140  continue;
141 
142  if (slot_init_count < max_slots)
143  {
144  slot[slot_stored_count] = MakeSingleTupleTableSlot(RelationGetDescr(dependDesc),
145  &TTSOpsHeapTuple);
146  slot_init_count++;
147  }
148 
149  ExecClearTuple(slot[slot_stored_count]);
150 
151  /*
152  * Record the dependency. Note we don't bother to check for duplicate
153  * dependencies; there's no harm in them.
154  */
155  memset(slot[slot_stored_count]->tts_isnull, false,
156  slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
157 
158  slot[slot_stored_count]->tts_values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
159  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
160  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
161  slot[slot_stored_count]->tts_values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
162  slot[slot_stored_count]->tts_values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
163  slot[slot_stored_count]->tts_values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
164  slot[slot_stored_count]->tts_values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
165  if (version)
166  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjversion - 1] = CStringGetTextDatum(version);
167  else
168  slot[slot_stored_count]->tts_isnull[Anum_pg_depend_refobjversion - 1] = true;
169 
170  ExecStoreVirtualTuple(slot[slot_stored_count]);
171  slot_stored_count++;
172 
173  /* If slots are full, insert a batch of tuples */
174  if (slot_stored_count == max_slots)
175  {
176  /* fetch index info only when we know we need it */
177  if (indstate == NULL)
178  indstate = CatalogOpenIndexes(dependDesc);
179 
180  CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
181  indstate);
182  slot_stored_count = 0;
183  }
184  }
185 
186  /* Insert any tuples left in the buffer */
187  if (slot_stored_count > 0)
188  {
189  /* fetch index info only when we know we need it */
190  if (indstate == NULL)
191  indstate = CatalogOpenIndexes(dependDesc);
192 
193  CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
194  indstate);
195  }
196 
197  if (indstate != NULL)
198  CatalogCloseIndexes(indstate);
199 
200  table_close(dependDesc, RowExclusiveLock);
201 
202  /* Drop only the number of slots used */
203  for (i = 0; i < slot_init_count; i++)
205  pfree(slot);
206 }
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:986
Datum * tts_values
Definition: tuptable.h:126
char * get_collation_version_for_oid(Oid oid, bool missing_ok)
Definition: pg_locale.c:1707
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:684
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:262
bool * tts_isnull
Definition: tuptable.h:128
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1224
#define RowExclusiveLock
Definition: lockdefs.h:38
#define Assert(condition)
Definition: c.h:804
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:43
#define CharGetDatum(X)
Definition: postgres.h:416
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:394
#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:82
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:69
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1522

◆ recordSharedDependencyOn()

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

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

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

◆ sequenceIsOwned()

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

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

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

1336 {
1337  Relation sdepRel;
1338  ListCell *cell;
1339  ObjectAddresses *deleteobjs;
1340 
1341  deleteobjs = new_object_addresses();
1342 
1343  /*
1344  * We don't need this strong a lock here, but we'll call routines that
1345  * acquire RowExclusiveLock. Better get that right now to avoid potential
1346  * deadlock failures.
1347  */
1348  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1349 
1350  /*
1351  * For each role, find the dependent objects and drop them using the
1352  * regular (non-shared) dependency management.
1353  */
1354  foreach(cell, roleids)
1355  {
1356  Oid roleid = lfirst_oid(cell);
1357  ScanKeyData key[2];
1358  SysScanDesc scan;
1359  HeapTuple tuple;
1360 
1361  /* Doesn't work for pinned objects */
1362  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1363  {
1364  ObjectAddress obj;
1365 
1366  obj.classId = AuthIdRelationId;
1367  obj.objectId = roleid;
1368  obj.objectSubId = 0;
1369 
1370  ereport(ERROR,
1371  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1372  errmsg("cannot drop objects owned by %s because they are "
1373  "required by the database system",
1374  getObjectDescription(&obj, false))));
1375  }
1376 
1377  ScanKeyInit(&key[0],
1378  Anum_pg_shdepend_refclassid,
1379  BTEqualStrategyNumber, F_OIDEQ,
1380  ObjectIdGetDatum(AuthIdRelationId));
1381  ScanKeyInit(&key[1],
1382  Anum_pg_shdepend_refobjid,
1383  BTEqualStrategyNumber, F_OIDEQ,
1384  ObjectIdGetDatum(roleid));
1385 
1386  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1387  NULL, 2, key);
1388 
1389  while ((tuple = systable_getnext(scan)) != NULL)
1390  {
1391  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1392  ObjectAddress obj;
1393 
1394  /*
1395  * We only operate on shared objects and objects in the current
1396  * database
1397  */
1398  if (sdepForm->dbid != MyDatabaseId &&
1399  sdepForm->dbid != InvalidOid)
1400  continue;
1401 
1402  switch (sdepForm->deptype)
1403  {
1404  /* Shouldn't happen */
1405  case SHARED_DEPENDENCY_PIN:
1407  elog(ERROR, "unexpected dependency type");
1408  break;
1409  case SHARED_DEPENDENCY_ACL:
1410  RemoveRoleFromObjectACL(roleid,
1411  sdepForm->classid,
1412  sdepForm->objid);
1413  break;
1415 
1416  /*
1417  * Try to remove role from policy; if unable to, remove
1418  * policy.
1419  */
1420  if (!RemoveRoleFromObjectPolicy(roleid,
1421  sdepForm->classid,
1422  sdepForm->objid))
1423  {
1424  obj.classId = sdepForm->classid;
1425  obj.objectId = sdepForm->objid;
1426  obj.objectSubId = sdepForm->objsubid;
1427 
1428  /*
1429  * Acquire lock on object, then verify this dependency
1430  * is still relevant. If not, the object might have
1431  * been dropped or the policy modified. Ignore the
1432  * object in that case.
1433  */
1434  AcquireDeletionLock(&obj, 0);
1435  if (!systable_recheck_tuple(scan, tuple))
1436  {
1437  ReleaseDeletionLock(&obj);
1438  break;
1439  }
1440  add_exact_object_address(&obj, deleteobjs);
1441  }
1442  break;
1444  /* If a local object, save it for deletion below */
1445  if (sdepForm->dbid == MyDatabaseId)
1446  {
1447  obj.classId = sdepForm->classid;
1448  obj.objectId = sdepForm->objid;
1449  obj.objectSubId = sdepForm->objsubid;
1450  /* as above */
1451  AcquireDeletionLock(&obj, 0);
1452  if (!systable_recheck_tuple(scan, tuple))
1453  {
1454  ReleaseDeletionLock(&obj);
1455  break;
1456  }
1457  add_exact_object_address(&obj, deleteobjs);
1458  }
1459  break;
1460  }
1461  }
1462 
1463  systable_endscan(scan);
1464  }
1465 
1466  /*
1467  * For stability of deletion-report ordering, sort the objects into
1468  * approximate reverse creation order before deletion. (This might also
1469  * make the deletion go a bit faster, since there's less chance of having
1470  * to rearrange the objects due to dependencies.)
1471  */
1472  sort_object_addresses(deleteobjs);
1473 
1474  /* the dependency mechanism does the actual work */
1475  performMultipleDeletions(deleteobjs, behavior, 0);
1476 
1477  table_close(sdepRel, RowExclusiveLock);
1478 
1479  free_object_addresses(deleteobjs);
1480 }
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:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1283
void sort_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2854
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:73
void ReleaseDeletionLock(const ObjectAddress *object)
Definition: dependency.c:1632
int errcode(int sqlerrcode)
Definition: elog.c:694
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2625
void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
Definition: aclchk.c:1396
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2570
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2866
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:383
bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
Definition: genam.c:561
bool RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
Definition: policy.c:419
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:45
#define SharedDependReferenceIndexId
Definition: pg_shdepend.h:78
#define RowExclusiveLock
Definition: lockdefs.h:38
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1603
Oid MyDatabaseId
Definition: globals.c:86
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:905
#define elog(elevel,...)
Definition: elog.h:227
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 1165 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().

1166 {
1167  /* AccessShareLock should be OK, since we are not modifying the object */
1168  LockSharedObject(classId, objectId, 0, AccessShareLock);
1169 
1170  switch (classId)
1171  {
1172  case AuthIdRelationId:
1174  ereport(ERROR,
1175  (errcode(ERRCODE_UNDEFINED_OBJECT),
1176  errmsg("role %u was concurrently dropped",
1177  objectId)));
1178  break;
1179 
1180  case TableSpaceRelationId:
1181  {
1182  /* For lack of a syscache on pg_tablespace, do this: */
1183  char *tablespace = get_tablespace_name(objectId);
1184 
1185  if (tablespace == NULL)
1186  ereport(ERROR,
1187  (errcode(ERRCODE_UNDEFINED_OBJECT),
1188  errmsg("tablespace %u was concurrently dropped",
1189  objectId)));
1190  pfree(tablespace);
1191  break;
1192  }
1193 
1194  case DatabaseRelationId:
1195  {
1196  /* For lack of a syscache on pg_database, do this: */
1197  char *database = get_database_name(objectId);
1198 
1199  if (database == NULL)
1200  ereport(ERROR,
1201  (errcode(ERRCODE_UNDEFINED_OBJECT),
1202  errmsg("database %u was concurrently dropped",
1203  objectId)));
1204  pfree(database);
1205  break;
1206  }
1207 
1208 
1209  default:
1210  elog(ERROR, "unrecognized shared classId: %u", classId);
1211  }
1212 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:694
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:184
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:45
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
char * tablespace
Definition: pgbench.c:190
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:1016
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:905
char * get_tablespace_name(Oid spc_oid)
Definition: tablespace.c:1479
#define elog(elevel,...)
Definition: elog.h:227

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

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

1490 {
1491  Relation sdepRel;
1492  ListCell *cell;
1493 
1494  /*
1495  * We don't need this strong a lock here, but we'll call routines that
1496  * acquire RowExclusiveLock. Better get that right now to avoid potential
1497  * deadlock problems.
1498  */
1499  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1500 
1501  foreach(cell, roleids)
1502  {
1503  SysScanDesc scan;
1504  ScanKeyData key[2];
1505  HeapTuple tuple;
1506  Oid roleid = lfirst_oid(cell);
1507 
1508  /* Refuse to work on pinned roles */
1509  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
1510  {
1511  ObjectAddress obj;
1512 
1513  obj.classId = AuthIdRelationId;
1514  obj.objectId = roleid;
1515  obj.objectSubId = 0;
1516 
1517  ereport(ERROR,
1518  (errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
1519  errmsg("cannot reassign ownership of objects owned by %s because they are required by the database system",
1520  getObjectDescription(&obj, false))));
1521 
1522  /*
1523  * There's no need to tell the whole truth, which is that we
1524  * didn't track these dependencies at all ...
1525  */
1526  }
1527 
1528  ScanKeyInit(&key[0],
1529  Anum_pg_shdepend_refclassid,
1530  BTEqualStrategyNumber, F_OIDEQ,
1531  ObjectIdGetDatum(AuthIdRelationId));
1532  ScanKeyInit(&key[1],
1533  Anum_pg_shdepend_refobjid,
1534  BTEqualStrategyNumber, F_OIDEQ,
1535  ObjectIdGetDatum(roleid));
1536 
1537  scan = systable_beginscan(sdepRel, SharedDependReferenceIndexId, true,
1538  NULL, 2, key);
1539 
1540  while ((tuple = systable_getnext(scan)) != NULL)
1541  {
1542  Form_pg_shdepend sdepForm = (Form_pg_shdepend) GETSTRUCT(tuple);
1543 
1544  /*
1545  * We only operate on shared objects and objects in the current
1546  * database
1547  */
1548  if (sdepForm->dbid != MyDatabaseId &&
1549  sdepForm->dbid != InvalidOid)
1550  continue;
1551 
1552  /* Unexpected because we checked for pins above */
1553  if (sdepForm->deptype == SHARED_DEPENDENCY_PIN)
1554  elog(ERROR, "unexpected shared pin");
1555 
1556  /* We leave non-owner dependencies alone */
1557  if (sdepForm->deptype != SHARED_DEPENDENCY_OWNER)
1558  continue;
1559 
1560  /* Issue the appropriate ALTER OWNER call */
1561  switch (sdepForm->classid)
1562  {
1563  case TypeRelationId:
1564  AlterTypeOwner_oid(sdepForm->objid, newrole, true);
1565  break;
1566 
1567  case NamespaceRelationId:
1568  AlterSchemaOwner_oid(sdepForm->objid, newrole);
1569  break;
1570 
1571  case RelationRelationId:
1572 
1573  /*
1574  * Pass recursing = true so that we don't fail on indexes,
1575  * owned sequences, etc when we happen to visit them
1576  * before their parent table.
1577  */
1578  ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock);
1579  break;
1580 
1581  case DefaultAclRelationId:
1582 
1583  /*
1584  * Ignore default ACLs; they should be handled by DROP
1585  * OWNED, not REASSIGN OWNED.
1586  */
1587  break;
1588 
1589  case UserMappingRelationId:
1590  /* ditto */
1591  break;
1592 
1593  case ForeignServerRelationId:
1594  AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1595  break;
1596 
1597  case ForeignDataWrapperRelationId:
1598  AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1599  break;
1600 
1601  case EventTriggerRelationId:
1602  AlterEventTriggerOwner_oid(sdepForm->objid, newrole);
1603  break;
1604 
1605  case PublicationRelationId:
1606  AlterPublicationOwner_oid(sdepForm->objid, newrole);
1607  break;
1608 
1609  case SubscriptionRelationId:
1610  AlterSubscriptionOwner_oid(sdepForm->objid, newrole);
1611  break;
1612 
1613  /* Generic alter owner cases */
1614  case CollationRelationId:
1615  case ConversionRelationId:
1616  case OperatorRelationId:
1617  case ProcedureRelationId:
1618  case LanguageRelationId:
1619  case LargeObjectRelationId:
1620  case OperatorFamilyRelationId:
1621  case OperatorClassRelationId:
1622  case ExtensionRelationId:
1623  case StatisticExtRelationId:
1624  case TableSpaceRelationId:
1625  case DatabaseRelationId:
1626  case TSConfigRelationId:
1627  case TSDictionaryRelationId:
1628  {
1629  Oid classId = sdepForm->classid;
1630  Relation catalog;
1631 
1632  if (classId == LargeObjectRelationId)
1633  classId = LargeObjectMetadataRelationId;
1634 
1635  catalog = table_open(classId, RowExclusiveLock);
1636 
1637  AlterObjectOwner_internal(catalog, sdepForm->objid,
1638  newrole);
1639 
1640  table_close(catalog, NoLock);
1641  }
1642  break;
1643 
1644  default:
1645  elog(ERROR, "unexpected classid %u", sdepForm->classid);
1646  break;
1647  }
1648  /* Make sure the next iteration will see my changes */
1650  }
1651 
1652  systable_endscan(scan);
1653  }
1654 
1655  table_close(sdepRel, RowExclusiveLock);
1656 }
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:595
#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:1283
void AlterSchemaOwner_oid(Oid oid, Oid newOwnerId)
Definition: schemacmds.c:276
FormData_pg_shdepend * Form_pg_shdepend
Definition: pg_shdepend.h:73
void AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
Definition: foreigncmds.c:450
int errcode(int sqlerrcode)
Definition: elog.c:694
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:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:45
#define SharedDependReferenceIndexId
Definition: pg_shdepend.h:78
void AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry)
Definition: typecmds.c:3796
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:12620
void CommandCounterIncrement(void)
Definition: xact.c:1021
Oid MyDatabaseId
Definition: globals.c:86
#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:905
#define elog(elevel,...)
Definition: elog.h:227
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 2854 of file dependency.c.

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

Referenced by shdepDropOwned().

2855 {
2856  if (addrs->numrefs > 1)
2857  qsort((void *) addrs->refs, addrs->numrefs,
2858  sizeof(ObjectAddress),
2860 }
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2526
ObjectAddress * refs
Definition: dependency.c:112
#define qsort(a, b, c, d)
Definition: port.h:504

◆ updateAclDependencies()

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

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

486 {
487  Relation sdepRel;
488  int i;
489 
490  /*
491  * Remove entries that are common to both lists; those represent existing
492  * dependencies we don't need to change.
493  *
494  * OK to overwrite the inputs since we'll pfree them anyway.
495  */
496  getOidListDiff(oldmembers, &noldmembers, newmembers, &nnewmembers);
497 
498  if (noldmembers > 0 || nnewmembers > 0)
499  {
500  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
501 
502  /* Add new dependencies that weren't already present */
503  for (i = 0; i < nnewmembers; i++)
504  {
505  Oid roleid = newmembers[i];
506 
507  /*
508  * Skip the owner: he has an OWNER shdep entry instead. (This is
509  * not just a space optimization; it makes ALTER OWNER easier. See
510  * notes in changeDependencyOnOwner.)
511  */
512  if (roleid == ownerId)
513  continue;
514 
515  /* Skip pinned roles; they don't need dependency entries */
516  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
517  continue;
518 
519  shdepAddDependency(sdepRel, classId, objectId, objsubId,
520  AuthIdRelationId, roleid,
522  }
523 
524  /* Drop no-longer-used old dependencies */
525  for (i = 0; i < noldmembers; i++)
526  {
527  Oid roleid = oldmembers[i];
528 
529  /* Skip the owner, same as above */
530  if (roleid == ownerId)
531  continue;
532 
533  /* Skip pinned roles */
534  if (isSharedObjectPinned(AuthIdRelationId, roleid, sdepRel))
535  continue;
536 
537  shdepDropDependency(sdepRel, classId, objectId, objsubId,
538  false, /* exact match on objsubId */
539  AuthIdRelationId, roleid,
541  }
542 
543  table_close(sdepRel, RowExclusiveLock);
544  }
545 
546  if (oldmembers)
547  pfree(oldmembers);
548  if (newmembers)
549  pfree(newmembers);
550 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
static bool isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
Definition: pg_shdepend.c:1283
static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2)
Definition: pg_shdepend.c:412
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:1023
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:1078
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:595
#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:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#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:76
#define DependDependerIndexId
Definition: pg_depend.h:81
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
#define TextDatumGetCString(d)
Definition: builtins.h:83
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:302
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:82
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