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

Go to the source code of this file.

Macros

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

Typedefs

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

Enumerations

enum  DependencyType {
  DEPENDENCY_NORMAL = 'n', DEPENDENCY_AUTO = 'a', DEPENDENCY_INTERNAL = 'i', DEPENDENCY_PARTITION_PRI = 'P',
  DEPENDENCY_PARTITION_SEC = 'S', DEPENDENCY_EXTENSION = 'e', DEPENDENCY_AUTO_EXTENSION = 'x'
}
 
enum  SharedDependencyType {
  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)
 
ObjectClass getObjectClass (const ObjectAddress *object)
 
ObjectAddressesnew_object_addresses (void)
 
void add_exact_object_address (const ObjectAddress *object, ObjectAddresses *addrs)
 
bool object_address_present (const ObjectAddress *object, const ObjectAddresses *addrs)
 
void record_object_address_dependencies (const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
 
void sort_object_addresses (ObjectAddresses *addrs)
 
void free_object_addresses (ObjectAddresses *addrs)
 
void recordDependencyOn (const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
 
void recordMultipleDependencies (const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
 
void recordDependencyOnCurrentExtension (const ObjectAddress *object, bool isReplace)
 
long deleteDependencyRecordsFor (Oid classId, Oid objectId, bool skipExtensionDeps)
 
long deleteDependencyRecordsForClass (Oid classId, Oid objectId, Oid refclassId, char deptype)
 
long deleteDependencyRecordsForSpecific (Oid classId, Oid objectId, char deptype, Oid refclassId, Oid refobjectId)
 
long changeDependencyFor (Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
long changeDependenciesOf (Oid classId, Oid oldObjectId, Oid newObjectId)
 
long changeDependenciesOn (Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
Oid getExtensionOfObject (Oid classId, Oid objectId)
 
ListgetAutoExtensionsOfObject (Oid classId, Oid objectId)
 
bool sequenceIsOwned (Oid seqId, char deptype, Oid *tableId, int32 *colId)
 
ListgetOwnedSequences (Oid relid)
 
Oid getIdentitySequence (Oid relid, AttrNumber attnum, bool missing_ok)
 
Oid get_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 130 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 138 of file dependency.h.

Referenced by doDeletion(), and ReindexRelationConcurrently().

◆ PERFORM_DELETION_CONCURRENTLY

#define PERFORM_DELETION_CONCURRENTLY   0x0002 /* concurrent drop */

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

Referenced by deleteObjectsInList(), and RemoveTempRelations().

Typedef Documentation

◆ DependencyType

◆ ObjectAddresses

Definition at line 82 of file dependency.h.

◆ ObjectClass

typedef enum ObjectClass ObjectClass

◆ SharedDependencyType

Enumeration Type Documentation

◆ DependencyType

Enumerator
DEPENDENCY_NORMAL 
DEPENDENCY_AUTO 
DEPENDENCY_INTERNAL 
DEPENDENCY_PARTITION_PRI 
DEPENDENCY_PARTITION_SEC 
DEPENDENCY_EXTENSION 
DEPENDENCY_AUTO_EXTENSION 

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 88 of file dependency.h.

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

◆ SharedDependencyType

Enumerator
SHARED_DEPENDENCY_OWNER 
SHARED_DEPENDENCY_ACL 
SHARED_DEPENDENCY_POLICY 
SHARED_DEPENDENCY_TABLESPACE 
SHARED_DEPENDENCY_INVALID 

Definition at line 72 of file dependency.h.

Function Documentation

◆ AcquireDeletionLock()

void AcquireDeletionLock ( const ObjectAddress object,
int  flags 
)

Definition at line 1517 of file dependency.c.

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

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

1518 {
1519  if (object->classId == RelationRelationId)
1520  {
1521  /*
1522  * In DROP INDEX CONCURRENTLY, take only ShareUpdateExclusiveLock on
1523  * the index for the moment. index_drop() will promote the lock once
1524  * it's safe to do so. In all other cases we need full exclusive
1525  * lock.
1526  */
1527  if (flags & PERFORM_DELETION_CONCURRENTLY)
1529  else
1531  }
1532  else
1533  {
1534  /* assume we should lock the whole object not a sub-object */
1535  LockDatabaseObject(object->classId, object->objectId, 0,
1537  }
1538 }
#define PERFORM_DELETION_CONCURRENTLY
Definition: dependency.h:134
void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:976
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define AccessExclusiveLock
Definition: lockdefs.h:45
void LockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:109

◆ add_exact_object_address()

void add_exact_object_address ( const ObjectAddress object,
ObjectAddresses addrs 
)

Definition at line 2485 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(), recordDependencyOnSingleRelExpr(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), shdepDropOwned(), and StorePartitionKey().

2487 {
2488  ObjectAddress *item;
2489 
2490  /* enlarge array if needed */
2491  if (addrs->numrefs >= addrs->maxrefs)
2492  {
2493  addrs->maxrefs *= 2;
2494  addrs->refs = (ObjectAddress *)
2495  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2496  Assert(!addrs->extras);
2497  }
2498  /* record this item */
2499  item = addrs->refs + addrs->numrefs;
2500  *item = *object;
2501  addrs->numrefs++;
2502 }
ObjectAddress * refs
Definition: dependency.c:112
#define Assert(condition)
Definition: c.h:804
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
ObjectAddressExtra * extras
Definition: dependency.c:113

◆ changeDependenciesOf()

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

Definition at line 507 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleUpdate(), 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().

509 {
510  long count = 0;
511  Relation depRel;
512  ScanKeyData key[2];
513  SysScanDesc scan;
514  HeapTuple tup;
515 
516  depRel = table_open(DependRelationId, RowExclusiveLock);
517 
518  ScanKeyInit(&key[0],
519  Anum_pg_depend_classid,
520  BTEqualStrategyNumber, F_OIDEQ,
521  ObjectIdGetDatum(classId));
522  ScanKeyInit(&key[1],
523  Anum_pg_depend_objid,
524  BTEqualStrategyNumber, F_OIDEQ,
525  ObjectIdGetDatum(oldObjectId));
526 
527  scan = systable_beginscan(depRel, DependDependerIndexId, true,
528  NULL, 2, key);
529 
530  while (HeapTupleIsValid((tup = systable_getnext(scan))))
531  {
532  Form_pg_depend depform;
533 
534  /* make a modifiable copy */
535  tup = heap_copytuple(tup);
536  depform = (Form_pg_depend) GETSTRUCT(tup);
537 
538  depform->objid = newObjectId;
539 
540  CatalogTupleUpdate(depRel, &tup->t_self, tup);
541 
542  heap_freetuple(tup);
543 
544  count++;
545  }
546 
547  systable_endscan(scan);
548 
549  table_close(depRel, RowExclusiveLock);
550 
551  return count;
552 }
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:654
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:551
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependenciesOn()

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

Definition at line 563 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, 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().

565 {
566  long count = 0;
567  Relation depRel;
568  ScanKeyData key[2];
569  SysScanDesc scan;
570  HeapTuple tup;
571  ObjectAddress objAddr;
572  bool newIsPinned;
573 
574  depRel = table_open(DependRelationId, RowExclusiveLock);
575 
576  /*
577  * If oldRefObjectId is pinned, there won't be any dependency entries on
578  * it --- we can't cope in that case. (This isn't really worth expending
579  * code to fix, in current usage; it just means you can't rename stuff out
580  * of pg_catalog, which would likely be a bad move anyway.)
581  */
582  objAddr.classId = refClassId;
583  objAddr.objectId = oldRefObjectId;
584  objAddr.objectSubId = 0;
585 
586  if (isObjectPinned(&objAddr))
587  ereport(ERROR,
588  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
589  errmsg("cannot remove dependency on %s because it is a system object",
590  getObjectDescription(&objAddr, false))));
591 
592  /*
593  * We can handle adding a dependency on something pinned, though, since
594  * that just means deleting the dependency entry.
595  */
596  objAddr.objectId = newRefObjectId;
597 
598  newIsPinned = isObjectPinned(&objAddr);
599 
600  /* Now search for dependency records */
601  ScanKeyInit(&key[0],
602  Anum_pg_depend_refclassid,
603  BTEqualStrategyNumber, F_OIDEQ,
604  ObjectIdGetDatum(refClassId));
605  ScanKeyInit(&key[1],
606  Anum_pg_depend_refobjid,
607  BTEqualStrategyNumber, F_OIDEQ,
608  ObjectIdGetDatum(oldRefObjectId));
609 
610  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
611  NULL, 2, key);
612 
613  while (HeapTupleIsValid((tup = systable_getnext(scan))))
614  {
615  if (newIsPinned)
616  CatalogTupleDelete(depRel, &tup->t_self);
617  else
618  {
619  Form_pg_depend depform;
620 
621  /* make a modifiable copy */
622  tup = heap_copytuple(tup);
623  depform = (Form_pg_depend) GETSTRUCT(tup);
624 
625  depform->refobjid = newRefObjectId;
626 
627  CatalogTupleUpdate(depRel, &tup->t_self, tup);
628 
629  heap_freetuple(tup);
630  }
631 
632  count++;
633  }
634 
635  systable_endscan(scan);
636 
637  table_close(depRel, RowExclusiveLock);
638 
639  return count;
640 }
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:654
int errcode(int sqlerrcode)
Definition: elog.c:698
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
static bool isObjectPinned(const ObjectAddress *object)
Definition: pg_depend.c:651
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#define ereport(elevel,...)
Definition: elog.h:157
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
int errmsg(const char *fmt,...)
Definition: elog.c:909
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 399 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, 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().

402 {
403  long count = 0;
404  Relation depRel;
405  ScanKeyData key[2];
406  SysScanDesc scan;
407  HeapTuple tup;
408  ObjectAddress objAddr;
409  ObjectAddress depAddr;
410  bool oldIsPinned;
411  bool newIsPinned;
412 
413  /*
414  * Check to see if either oldRefObjectId or newRefObjectId is pinned.
415  * Pinned objects should not have any dependency entries pointing to them,
416  * so in these cases we should add or remove a pg_depend entry, or do
417  * nothing at all, rather than update an entry as in the normal case.
418  */
419  objAddr.classId = refClassId;
420  objAddr.objectId = oldRefObjectId;
421  objAddr.objectSubId = 0;
422 
423  oldIsPinned = isObjectPinned(&objAddr);
424 
425  objAddr.objectId = newRefObjectId;
426 
427  newIsPinned = isObjectPinned(&objAddr);
428 
429  if (oldIsPinned)
430  {
431  /*
432  * If both are pinned, we need do nothing. However, return 1 not 0,
433  * else callers will think this is an error case.
434  */
435  if (newIsPinned)
436  return 1;
437 
438  /*
439  * There is no old dependency record, but we should insert a new one.
440  * Assume a normal dependency is wanted.
441  */
442  depAddr.classId = classId;
443  depAddr.objectId = objectId;
444  depAddr.objectSubId = 0;
445  recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL);
446 
447  return 1;
448  }
449 
450  depRel = table_open(DependRelationId, RowExclusiveLock);
451 
452  /* There should be existing dependency record(s), so search. */
453  ScanKeyInit(&key[0],
454  Anum_pg_depend_classid,
455  BTEqualStrategyNumber, F_OIDEQ,
456  ObjectIdGetDatum(classId));
457  ScanKeyInit(&key[1],
458  Anum_pg_depend_objid,
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(objectId));
461 
462  scan = systable_beginscan(depRel, DependDependerIndexId, true,
463  NULL, 2, key);
464 
465  while (HeapTupleIsValid((tup = systable_getnext(scan))))
466  {
467  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
468 
469  if (depform->refclassid == refClassId &&
470  depform->refobjid == oldRefObjectId)
471  {
472  if (newIsPinned)
473  CatalogTupleDelete(depRel, &tup->t_self);
474  else
475  {
476  /* make a modifiable copy */
477  tup = heap_copytuple(tup);
478  depform = (Form_pg_depend) GETSTRUCT(tup);
479 
480  depform->refobjid = newRefObjectId;
481 
482  CatalogTupleUpdate(depRel, &tup->t_self, tup);
483 
484  heap_freetuple(tup);
485  }
486 
487  count++;
488  }
489  }
490 
491  systable_endscan(scan);
492 
493  table_close(depRel, RowExclusiveLock);
494 
495  return count;
496 }
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:654
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
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:551
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
static bool isObjectPinned(const ObjectAddress *object)
Definition: pg_depend.c:651
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependencyOnOwner()

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

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

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

◆ changeDependencyOnTablespace()

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

Definition at line 380 of file pg_shdepend.c.

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

Referenced by SetRelationTableSpace().

381 {
382  Relation sdepRel;
383 
384  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
385 
386  if (newTablespaceId != DEFAULTTABLESPACE_OID &&
387  newTablespaceId != InvalidOid)
388  shdepChangeDep(sdepRel,
389  classId, objectId, 0,
390  TableSpaceRelationId, newTablespaceId,
392  else
393  shdepDropDependency(sdepRel,
394  classId, objectId, 0, true,
397 
398  table_close(sdepRel, RowExclusiveLock);
399 }
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:201
#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:1074
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 629 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, IsPinnedObject(), 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_OBJECT, storeObjectDescription(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by DropRole(), and DropTableSpace().

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

Referenced by createdb().

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

◆ deleteDependencyRecordsFor()

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

Definition at line 243 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), 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(), CreateTriggerFiringOn(), DefineQueryRewrite(), GenerateTypeDependencies(), InsertRule(), makeConfigurationDependencies(), makeOperatorDependencies(), ProcedureCreate(), swap_relation_files(), and tryAttachPartitionForeignKey().

245 {
246  long count = 0;
247  Relation depRel;
248  ScanKeyData key[2];
249  SysScanDesc scan;
250  HeapTuple tup;
251 
252  depRel = table_open(DependRelationId, RowExclusiveLock);
253 
254  ScanKeyInit(&key[0],
255  Anum_pg_depend_classid,
256  BTEqualStrategyNumber, F_OIDEQ,
257  ObjectIdGetDatum(classId));
258  ScanKeyInit(&key[1],
259  Anum_pg_depend_objid,
260  BTEqualStrategyNumber, F_OIDEQ,
261  ObjectIdGetDatum(objectId));
262 
263  scan = systable_beginscan(depRel, DependDependerIndexId, true,
264  NULL, 2, key);
265 
266  while (HeapTupleIsValid(tup = systable_getnext(scan)))
267  {
268  if (skipExtensionDeps &&
269  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
270  continue;
271 
272  CatalogTupleDelete(depRel, &tup->t_self);
273  count++;
274  }
275 
276  systable_endscan(scan);
277 
278  table_close(depRel, RowExclusiveLock);
279 
280  return count;
281 }
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:654
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#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 293 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), 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(), ATExecDropIdentity(), ConstraintSetParentConstraint(), DetachPartitionFinalize(), DropClonedTriggersFromPartition(), ExecAlterExtensionContentsStmt(), index_constraint_create(), IndexSetParentIndex(), and process_owned_by().

295 {
296  long count = 0;
297  Relation depRel;
298  ScanKeyData key[2];
299  SysScanDesc scan;
300  HeapTuple tup;
301 
302  depRel = table_open(DependRelationId, RowExclusiveLock);
303 
304  ScanKeyInit(&key[0],
305  Anum_pg_depend_classid,
306  BTEqualStrategyNumber, F_OIDEQ,
307  ObjectIdGetDatum(classId));
308  ScanKeyInit(&key[1],
309  Anum_pg_depend_objid,
310  BTEqualStrategyNumber, F_OIDEQ,
311  ObjectIdGetDatum(objectId));
312 
313  scan = systable_beginscan(depRel, DependDependerIndexId, true,
314  NULL, 2, key);
315 
316  while (HeapTupleIsValid(tup = systable_getnext(scan)))
317  {
318  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
319 
320  if (depform->refclassid == refclassId && depform->deptype == deptype)
321  {
322  CatalogTupleDelete(depRel, &tup->t_self);
323  count++;
324  }
325  }
326 
327  systable_endscan(scan);
328 
329  table_close(depRel, RowExclusiveLock);
330 
331  return count;
332 }
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:654
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#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 340 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), 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().

342 {
343  long count = 0;
344  Relation depRel;
345  ScanKeyData key[2];
346  SysScanDesc scan;
347  HeapTuple tup;
348 
349  depRel = table_open(DependRelationId, RowExclusiveLock);
350 
351  ScanKeyInit(&key[0],
352  Anum_pg_depend_classid,
353  BTEqualStrategyNumber, F_OIDEQ,
354  ObjectIdGetDatum(classId));
355  ScanKeyInit(&key[1],
356  Anum_pg_depend_objid,
357  BTEqualStrategyNumber, F_OIDEQ,
358  ObjectIdGetDatum(objectId));
359 
360  scan = systable_beginscan(depRel, DependDependerIndexId, true,
361  NULL, 2, key);
362 
363  while (HeapTupleIsValid(tup = systable_getnext(scan)))
364  {
365  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
366 
367  if (depform->refclassid == refclassId &&
368  depform->refobjid == refobjectId &&
369  depform->deptype == deptype)
370  {
371  CatalogTupleDelete(depRel, &tup->t_self);
372  count++;
373  }
374  }
375 
376  systable_endscan(scan);
377 
378  table_close(depRel, RowExclusiveLock);
379 
380  return count;
381 }
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:654
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:350
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#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 997 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().

998 {
999  Relation sdepRel;
1000 
1001  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
1002 
1003  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
1004  (objectSubId == 0),
1007 
1008  table_close(sdepRel, RowExclusiveLock);
1009 }
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:1074
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

Definition at line 949 of file pg_shdepend.c.

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

Referenced by dropdb().

950 {
951  Relation sdepRel;
952  ScanKeyData key[1];
953  SysScanDesc scan;
954  HeapTuple tup;
955 
956  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
957 
958  /*
959  * First, delete all the entries that have the database Oid in the dbid
960  * field.
961  */
962  ScanKeyInit(&key[0],
963  Anum_pg_shdepend_dbid,
964  BTEqualStrategyNumber, F_OIDEQ,
965  ObjectIdGetDatum(databaseId));
966  /* We leave the other index fields unspecified */
967 
968  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
969  NULL, 1, key);
970 
971  while (HeapTupleIsValid(tup = systable_getnext(scan)))
972  {
973  CatalogTupleDelete(sdepRel, &tup->t_self);
974  }
975 
976  systable_endscan(scan);
977 
978  /* Now delete all entries corresponding to the database itself */
979  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
982 
983  table_close(sdepRel, RowExclusiveLock);
984 }
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:350
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:551
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:1074
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ free_object_addresses()

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 911 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, 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().

912 {
913  Oid constraintId = InvalidOid;
914  Relation depRel;
915  ScanKeyData key[3];
916  SysScanDesc scan;
917  HeapTuple tup;
918 
919  /* Search the dependency table for the index */
920  depRel = table_open(DependRelationId, AccessShareLock);
921 
922  ScanKeyInit(&key[0],
923  Anum_pg_depend_classid,
924  BTEqualStrategyNumber, F_OIDEQ,
925  ObjectIdGetDatum(RelationRelationId));
926  ScanKeyInit(&key[1],
927  Anum_pg_depend_objid,
928  BTEqualStrategyNumber, F_OIDEQ,
929  ObjectIdGetDatum(indexId));
930  ScanKeyInit(&key[2],
931  Anum_pg_depend_objsubid,
932  BTEqualStrategyNumber, F_INT4EQ,
933  Int32GetDatum(0));
934 
935  scan = systable_beginscan(depRel, DependDependerIndexId, true,
936  NULL, 3, key);
937 
938  while (HeapTupleIsValid(tup = systable_getnext(scan)))
939  {
940  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
941 
942  /*
943  * We assume any internal dependency on a constraint must be what we
944  * are looking for.
945  */
946  if (deprec->refclassid == ConstraintRelationId &&
947  deprec->refobjsubid == 0 &&
948  deprec->deptype == DEPENDENCY_INTERNAL)
949  {
950  constraintId = deprec->refobjid;
951  break;
952  }
953  }
954 
955  systable_endscan(scan);
956  table_close(depRel, AccessShareLock);
957 
958  return constraintId;
959 }
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:654
#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:551
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:523
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 967 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_NORMAL, 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().

968 {
969  List *result = NIL;
970  Relation depRel;
971  ScanKeyData key[3];
972  SysScanDesc scan;
973  HeapTuple tup;
974 
975  /* Search the dependency table for the index */
976  depRel = table_open(DependRelationId, AccessShareLock);
977 
978  ScanKeyInit(&key[0],
979  Anum_pg_depend_refclassid,
980  BTEqualStrategyNumber, F_OIDEQ,
981  ObjectIdGetDatum(RelationRelationId));
982  ScanKeyInit(&key[1],
983  Anum_pg_depend_refobjid,
984  BTEqualStrategyNumber, F_OIDEQ,
985  ObjectIdGetDatum(indexId));
986  ScanKeyInit(&key[2],
987  Anum_pg_depend_refobjsubid,
988  BTEqualStrategyNumber, F_INT4EQ,
989  Int32GetDatum(0));
990 
991  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
992  NULL, 3, key);
993 
994  while (HeapTupleIsValid(tup = systable_getnext(scan)))
995  {
996  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
997 
998  /*
999  * We assume any normal dependency from a constraint must be what we
1000  * are looking for.
1001  */
1002  if (deprec->classid == ConstraintRelationId &&
1003  deprec->objsubid == 0 &&
1004  deprec->deptype == DEPENDENCY_NORMAL)
1005  {
1006  result = lappend_oid(result, deprec->objid);
1007  }
1008  }
1009 
1010  systable_endscan(scan);
1011  table_close(depRel, AccessShareLock);
1012 
1013  return result;
1014 }
#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:654
#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:551
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:523
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 720 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, 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().

721 {
722  List *result = NIL;
723  Relation depRel;
724  ScanKeyData key[2];
725  SysScanDesc scan;
726  HeapTuple tup;
727 
728  depRel = table_open(DependRelationId, AccessShareLock);
729 
730  ScanKeyInit(&key[0],
731  Anum_pg_depend_classid,
732  BTEqualStrategyNumber, F_OIDEQ,
733  ObjectIdGetDatum(classId));
734  ScanKeyInit(&key[1],
735  Anum_pg_depend_objid,
736  BTEqualStrategyNumber, F_OIDEQ,
737  ObjectIdGetDatum(objectId));
738 
739  scan = systable_beginscan(depRel, DependDependerIndexId, true,
740  NULL, 2, key);
741 
742  while (HeapTupleIsValid((tup = systable_getnext(scan))))
743  {
744  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
745 
746  if (depform->refclassid == ExtensionRelationId &&
747  depform->deptype == DEPENDENCY_AUTO_EXTENSION)
748  result = lappend_oid(result, depform->refobjid);
749  }
750 
751  systable_endscan(scan);
752 
753  table_close(depRel, AccessShareLock);
754 
755  return result;
756 }
#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:654
#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:551
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#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 674 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, 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().

675 {
676  Oid result = InvalidOid;
677  Relation depRel;
678  ScanKeyData key[2];
679  SysScanDesc scan;
680  HeapTuple tup;
681 
682  depRel = table_open(DependRelationId, AccessShareLock);
683 
684  ScanKeyInit(&key[0],
685  Anum_pg_depend_classid,
686  BTEqualStrategyNumber, F_OIDEQ,
687  ObjectIdGetDatum(classId));
688  ScanKeyInit(&key[1],
689  Anum_pg_depend_objid,
690  BTEqualStrategyNumber, F_OIDEQ,
691  ObjectIdGetDatum(objectId));
692 
693  scan = systable_beginscan(depRel, DependDependerIndexId, true,
694  NULL, 2, key);
695 
696  while (HeapTupleIsValid((tup = systable_getnext(scan))))
697  {
698  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
699 
700  if (depform->refclassid == ExtensionRelationId &&
701  depform->deptype == DEPENDENCY_EXTENSION)
702  {
703  result = depform->refobjid;
704  break; /* no need to keep scanning */
705  }
706  }
707 
708  systable_endscan(scan);
709 
710  table_close(depRel, AccessShareLock);
711 
712  return result;
713 }
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:654
#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:551
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#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 887 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().

888 {
890 
891  if (list_length(seqlist) > 1)
892  elog(ERROR, "more than one owned sequence found");
893  else if (list_length(seqlist) < 1)
894  {
895  if (missing_ok)
896  return InvalidOid;
897  else
898  elog(ERROR, "no owned sequence found");
899  }
900 
901  return linitial_oid(seqlist);
902 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:819
#define ERROR
Definition: elog.h:46
#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:232
Definition: pg_list.h:50

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

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

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

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 878 of file pg_depend.c.

References getOwnedSequences_internal().

Referenced by ExecuteTruncateGuts().

879 {
880  return getOwnedSequences_internal(relid, 0, 0);
881 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:819

◆ new_object_addresses()

ObjectAddresses* new_object_addresses ( void  )

Definition at line 2430 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(), recordDependencyOnExpr(), recordDependencyOnSingleRelExpr(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), shdepDropOwned(), and StorePartitionKey().

2431 {
2432  ObjectAddresses *addrs;
2433 
2434  addrs = palloc(sizeof(ObjectAddresses));
2435 
2436  addrs->numrefs = 0;
2437  addrs->maxrefs = 32;
2438  addrs->refs = (ObjectAddress *)
2439  palloc(addrs->maxrefs * sizeof(ObjectAddress));
2440  addrs->extras = NULL; /* until/unless needed */
2441 
2442  return addrs;
2443 }
ObjectAddress * refs
Definition: dependency.c:112
ObjectAddressExtra * extras
Definition: dependency.c:113
void * palloc(Size size)
Definition: mcxt.c:1062

◆ object_address_present()

bool object_address_present ( const ObjectAddress object,
const ObjectAddresses addrs 
)

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

2547 {
2548  int i;
2549 
2550  for (i = addrs->numrefs - 1; i >= 0; i--)
2551  {
2552  const ObjectAddress *thisobj = addrs->refs + i;
2553 
2554  if (object->classId == thisobj->classId &&
2555  object->objectId == thisobj->objectId)
2556  {
2557  if (object->objectSubId == thisobj->objectSubId ||
2558  thisobj->objectSubId == 0)
2559  return true;
2560  }
2561  }
2562 
2563  return false;
2564 }
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(), ATExecDropConstraint(), ATExecDropIdentity(), DefineQueryRewrite(), DetachPartitionFinalize(), 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:472
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2430
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2725
#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:1014
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1517
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:472
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2430
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2725
#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:1014
void AcquireDeletionLock(const ObjectAddress *object, int flags)
Definition: dependency.c:1517
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 2694 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().

2697 {
2699  recordMultipleDependencies(depender,
2700  referenced->refs, referenced->numrefs,
2701  behavior);
2702 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2326
ObjectAddress * refs
Definition: dependency.c:112
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:56

◆ recordDependencyOn()

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

Definition at line 44 of file pg_depend.c.

References recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), addFkRecurseReferenced(), addFkRecurseReferencing(), AddNewAttributeTuples(), AlterForeignDataWrapper(), AlterFunction(), AlterPolicy(), ApplyExtensionUpdates(), ATExecAddOf(), changeDependencyFor(), CloneFkReferencing(), CollationCreate(), ConstraintSetParentConstraint(), ConversionCreate(), create_toast_table(), CreateAccessMethod(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreateStatistics(), CreateTriggerFiringOn(), 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(), SetDefaultACL(), StoreAttrDefault(), StoreCatalogInheritance1(), storeOperators(), StorePartitionKey(), storeProcedures(), and swap_relation_files().

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

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

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

193 {
194  /* Only whole objects can be extension members */
195  Assert(object->objectSubId == 0);
196 
197  if (creating_extension)
198  {
199  ObjectAddress extension;
200 
201  /* Only need to check for existing membership if isReplace */
202  if (isReplace)
203  {
204  Oid oldext;
205 
206  oldext = getExtensionOfObject(object->classId, object->objectId);
207  if (OidIsValid(oldext))
208  {
209  /* If already a member of this extension, nothing to do */
210  if (oldext == CurrentExtensionObject)
211  return;
212  /* Already a member of some other extension, so reject */
213  ereport(ERROR,
214  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
215  errmsg("%s is already a member of extension \"%s\"",
216  getObjectDescription(object, false),
217  get_extension_name(oldext))));
218  }
219  }
220 
221  /* OK, record it as a member of CurrentExtensionObject */
222  extension.classId = ExtensionRelationId;
223  extension.objectId = CurrentExtensionObject;
224  extension.objectSubId = 0;
225 
226  recordDependencyOn(object, &extension, DEPENDENCY_EXTENSION);
227  }
228 }
Oid CurrentExtensionObject
Definition: extension.c:72
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:674
char * get_extension_name(Oid ext_oid)
Definition: extension.c:185
int errcode(int sqlerrcode)
Definition: elog.c:698
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
bool creating_extension
Definition: extension.c:71
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ recordDependencyOnExpr()

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

Definition at line 1571 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(), CreateTriggerFiringOn(), GenerateTypeDependencies(), InsertRule(), and ProcedureCreate().

1574 {
1576 
1577  context.addrs = new_object_addresses();
1578 
1579  /* Set up interpretation for Vars at varlevelsup = 0 */
1580  context.rtables = list_make1(rtable);
1581 
1582  /* Scan the expression tree for referenceable objects */
1583  find_expr_references_walker(expr, &context);
1584 
1585  /* Remove any duplicates */
1587 
1588  /* And record 'em */
1589  recordMultipleDependencies(depender,
1590  context.addrs->refs, context.addrs->numrefs,
1591  behavior);
1592 
1593  free_object_addresses(context.addrs);
1594 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1717
ObjectAddresses * addrs
Definition: dependency.c:138
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2430
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2725
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2326
#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)
Definition: pg_depend.c:56

◆ recordDependencyOnOwner()

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

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

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

◆ recordDependencyOnSingleRelExpr()

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

Definition at line 1614 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(), CreateStatistics(), index_create(), StoreAttrDefault(), and StorePartitionKey().

1619 {
1621  RangeTblEntry rte;
1622 
1623  context.addrs = new_object_addresses();
1624 
1625  /* We gin up a rather bogus rangetable list to handle Vars */
1626  MemSet(&rte, 0, sizeof(rte));
1627  rte.type = T_RangeTblEntry;
1628  rte.rtekind = RTE_RELATION;
1629  rte.relid = relId;
1630  rte.relkind = RELKIND_RELATION; /* no need for exactness here */
1632 
1633  context.rtables = list_make1(list_make1(&rte));
1634 
1635  /* Scan the expression tree for referenceable objects */
1636  find_expr_references_walker(expr, &context);
1637 
1638  /* Remove any duplicates */
1640 
1641  /* Separate self-dependencies if necessary */
1642  if ((behavior != self_behavior || reverse_self) &&
1643  context.addrs->numrefs > 0)
1644  {
1645  ObjectAddresses *self_addrs;
1646  ObjectAddress *outobj;
1647  int oldref,
1648  outrefs;
1649 
1650  self_addrs = new_object_addresses();
1651 
1652  outobj = context.addrs->refs;
1653  outrefs = 0;
1654  for (oldref = 0; oldref < context.addrs->numrefs; oldref++)
1655  {
1656  ObjectAddress *thisobj = context.addrs->refs + oldref;
1657 
1658  if (thisobj->classId == RelationRelationId &&
1659  thisobj->objectId == relId)
1660  {
1661  /* Move this ref into self_addrs */
1662  add_exact_object_address(thisobj, self_addrs);
1663  }
1664  else
1665  {
1666  /* Keep it in context.addrs */
1667  *outobj = *thisobj;
1668  outobj++;
1669  outrefs++;
1670  }
1671  }
1672  context.addrs->numrefs = outrefs;
1673 
1674  /* Record the self-dependencies with the appropriate direction */
1675  if (!reverse_self)
1676  recordMultipleDependencies(depender,
1677  self_addrs->refs, self_addrs->numrefs,
1678  self_behavior);
1679  else
1680  {
1681  /* Can't use recordMultipleDependencies, so do it the hard way */
1682  int selfref;
1683 
1684  for (selfref = 0; selfref < self_addrs->numrefs; selfref++)
1685  {
1686  ObjectAddress *thisobj = self_addrs->refs + selfref;
1687 
1688  recordDependencyOn(thisobj, depender, self_behavior);
1689  }
1690  }
1691 
1692  free_object_addresses(self_addrs);
1693  }
1694 
1695  /* Record the external dependencies */
1696  recordMultipleDependencies(depender,
1697  context.addrs->refs, context.addrs->numrefs,
1698  behavior);
1699 
1700  free_object_addresses(context.addrs);
1701 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1717
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:44
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2485
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2430
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2725
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2326
#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)
Definition: pg_depend.c:56
RTEKind rtekind
Definition: parsenodes.h:1007
NodeTag type
Definition: parsenodes.h:1005

◆ recordDependencyOnTablespace()

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

Definition at line 359 of file pg_shdepend.c.

References ObjectAddressSet, recordSharedDependencyOn(), and SHARED_DEPENDENCY_TABLESPACE.

Referenced by heap_create().

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

◆ recordMultipleDependencies()

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

Definition at line 56 of file pg_depend.c.

References CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTuplesMultiInsertWithInfo(), CharGetDatum, ObjectAddress::classId, ExecClearTuple(), ExecDropSingleTupleTableSlot(), ExecStoreVirtualTuple(), FormData_pg_depend, 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_values, and TTSOpsHeapTuple.

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

60 {
61  Relation dependDesc;
62  CatalogIndexState indstate;
63  TupleTableSlot **slot;
64  int i,
65  max_slots,
66  slot_init_count,
67  slot_stored_count;
68 
69  if (nreferenced <= 0)
70  return; /* nothing to do */
71 
72  /*
73  * During bootstrap, do nothing since pg_depend may not exist yet.
74  *
75  * Objects created during bootstrap are most likely pinned, and the few
76  * that are not do not have dependencies on each other, so that there
77  * would be no need to make a pg_depend entry anyway.
78  */
80  return;
81 
82  dependDesc = table_open(DependRelationId, RowExclusiveLock);
83 
84  /*
85  * Allocate the slots to use, but delay costly initialization until we
86  * know that they will be used.
87  */
88  max_slots = Min(nreferenced,
90  slot = palloc(sizeof(TupleTableSlot *) * max_slots);
91 
92  /* Don't open indexes unless we need to make an update */
93  indstate = NULL;
94 
95  /* number of slots currently storing tuples */
96  slot_stored_count = 0;
97  /* number of slots currently initialized */
98  slot_init_count = 0;
99  for (i = 0; i < nreferenced; i++, referenced++)
100  {
101  /*
102  * If the referenced object is pinned by the system, there's no real
103  * need to record dependencies on it. This saves lots of space in
104  * pg_depend, so it's worth the time taken to check.
105  */
106  if (isObjectPinned(referenced))
107  continue;
108 
109  if (slot_init_count < max_slots)
110  {
111  slot[slot_stored_count] = MakeSingleTupleTableSlot(RelationGetDescr(dependDesc),
112  &TTSOpsHeapTuple);
113  slot_init_count++;
114  }
115 
116  ExecClearTuple(slot[slot_stored_count]);
117 
118  /*
119  * Record the dependency. Note we don't bother to check for duplicate
120  * dependencies; there's no harm in them.
121  */
122  slot[slot_stored_count]->tts_values[Anum_pg_depend_refclassid - 1] = ObjectIdGetDatum(referenced->classId);
123  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjid - 1] = ObjectIdGetDatum(referenced->objectId);
124  slot[slot_stored_count]->tts_values[Anum_pg_depend_refobjsubid - 1] = Int32GetDatum(referenced->objectSubId);
125  slot[slot_stored_count]->tts_values[Anum_pg_depend_deptype - 1] = CharGetDatum((char) behavior);
126  slot[slot_stored_count]->tts_values[Anum_pg_depend_classid - 1] = ObjectIdGetDatum(depender->classId);
127  slot[slot_stored_count]->tts_values[Anum_pg_depend_objid - 1] = ObjectIdGetDatum(depender->objectId);
128  slot[slot_stored_count]->tts_values[Anum_pg_depend_objsubid - 1] = Int32GetDatum(depender->objectSubId);
129 
130  memset(slot[slot_stored_count]->tts_isnull, false,
131  slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
132 
133  ExecStoreVirtualTuple(slot[slot_stored_count]);
134  slot_stored_count++;
135 
136  /* If slots are full, insert a batch of tuples */
137  if (slot_stored_count == max_slots)
138  {
139  /* fetch index info only when we know we need it */
140  if (indstate == NULL)
141  indstate = CatalogOpenIndexes(dependDesc);
142 
143  CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
144  indstate);
145  slot_stored_count = 0;
146  }
147  }
148 
149  /* Insert any tuples left in the buffer */
150  if (slot_stored_count > 0)
151  {
152  /* fetch index info only when we know we need it */
153  if (indstate == NULL)
154  indstate = CatalogOpenIndexes(dependDesc);
155 
156  CatalogTuplesMultiInsertWithInfo(dependDesc, slot, slot_stored_count,
157  indstate);
158  }
159 
160  if (indstate != NULL)
161  CatalogCloseIndexes(indstate);
162 
163  table_close(dependDesc, RowExclusiveLock);
164 
165  /* Drop only the number of slots used */
166  for (i = 0; i < slot_init_count; i++)
168  pfree(slot);
169 }
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:503
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
Definition: execTuples.c:1238
#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
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
void CatalogTuplesMultiInsertWithInfo(Relation heapRel, TupleTableSlot **slot, int ntuples, CatalogIndexState indstate)
Definition: indexing.c:261
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1254
#define RowExclusiveLock
Definition: lockdefs.h:38
static bool isObjectPinned(const ObjectAddress *object)
Definition: pg_depend.c:651
CatalogIndexState CatalogOpenIndexes(Relation heapRel)
Definition: indexing.c:43
#define CharGetDatum(X)
Definition: postgres.h:460
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:406
#define Int32GetDatum(X)
Definition: postgres.h:523
void * palloc(Size size)
Definition: mcxt.c:1062
int i
const TupleTableSlotOps TTSOpsHeapTuple
Definition: execTuples.c:84
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:65
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
Definition: execTuples.c:1552

◆ recordSharedDependencyOn()

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

Definition at line 120 of file pg_shdepend.c.

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

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

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

◆ ReleaseDeletionLock()

void ReleaseDeletionLock ( const ObjectAddress object)

Definition at line 1546 of file dependency.c.

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

Referenced by findDependentObjects(), and shdepDropOwned().

1547 {
1548  if (object->classId == RelationRelationId)
1550  else
1551  /* assume we should lock the whole object not a sub-object */
1552  UnlockDatabaseObject(object->classId, object->objectId, 0,
1554 }
void UnlockRelationOid(Oid relid, LOCKMODE lockmode)
Definition: lmgr.c:200
void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:997
#define AccessExclusiveLock
Definition: lockdefs.h:45

◆ sequenceIsOwned()

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

Definition at line 770 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, 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().

771 {
772  bool ret = false;
773  Relation depRel;
774  ScanKeyData key[2];
775  SysScanDesc scan;
776  HeapTuple tup;
777 
778  depRel = table_open(DependRelationId, AccessShareLock);
779 
780  ScanKeyInit(&key[0],
781  Anum_pg_depend_classid,
782  BTEqualStrategyNumber, F_OIDEQ,
783  ObjectIdGetDatum(RelationRelationId));
784  ScanKeyInit(&key[1],
785  Anum_pg_depend_objid,
786  BTEqualStrategyNumber, F_OIDEQ,
787  ObjectIdGetDatum(seqId));
788 
789  scan = systable_beginscan(depRel, DependDependerIndexId, true,
790  NULL, 2, key);
791 
792  while (HeapTupleIsValid((tup = systable_getnext(scan))))
793  {
794  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
795 
796  if (depform->refclassid == RelationRelationId &&
797  depform->deptype == deptype)
798  {
799  *tableId = depform->refobjid;
800  *colId = depform->refobjsubid;
801  ret = true;
802  break; /* no need to keep scanning */
803  }
804  }
805 
806  systable_endscan(scan);
807 
808  table_close(depRel, AccessShareLock);
809 
810  return ret;
811 }
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:654
#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:551
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
#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 1284 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, IsPinnedObject(), 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_POLICY, sort_object_addresses(), systable_beginscan(), systable_endscan(), systable_getnext(), systable_recheck_tuple(), table_close(), and table_open().

Referenced by DropOwnedObjects().

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

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

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

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

Referenced by ReassignOwnedObjects().

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

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

Referenced by shdepDropOwned().

2714 {
2715  if (addrs->numrefs > 1)
2716  qsort((void *) addrs->refs, addrs->numrefs,
2717  sizeof(ObjectAddress),
2719 }
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2386
ObjectAddress * refs
Definition: dependency.c:112
#define qsort(a, b, c, d)
Definition: port.h:505

◆ updateAclDependencies()

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

Definition at line 480 of file pg_shdepend.c.

References getOidListDiff(), i, IsPinnedObject(), 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().

484 {
485  Relation sdepRel;
486  int i;
487 
488  /*
489  * Remove entries that are common to both lists; those represent existing
490  * dependencies we don't need to change.
491  *
492  * OK to overwrite the inputs since we'll pfree them anyway.
493  */
494  getOidListDiff(oldmembers, &noldmembers, newmembers, &nnewmembers);
495 
496  if (noldmembers > 0 || nnewmembers > 0)
497  {
498  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
499 
500  /* Add new dependencies that weren't already present */
501  for (i = 0; i < nnewmembers; i++)
502  {
503  Oid roleid = newmembers[i];
504 
505  /*
506  * Skip the owner: he has an OWNER shdep entry instead. (This is
507  * not just a space optimization; it makes ALTER OWNER easier. See
508  * notes in changeDependencyOnOwner.)
509  */
510  if (roleid == ownerId)
511  continue;
512 
513  /* Skip pinned roles; they don't need dependency entries */
514  if (IsPinnedObject(AuthIdRelationId, roleid))
515  continue;
516 
517  shdepAddDependency(sdepRel, classId, objectId, objsubId,
518  AuthIdRelationId, roleid,
520  }
521 
522  /* Drop no-longer-used old dependencies */
523  for (i = 0; i < noldmembers; i++)
524  {
525  Oid roleid = oldmembers[i];
526 
527  /* Skip the owner, same as above */
528  if (roleid == ownerId)
529  continue;
530 
531  /* Skip pinned roles */
532  if (IsPinnedObject(AuthIdRelationId, roleid))
533  continue;
534 
535  shdepDropDependency(sdepRel, classId, objectId, objsubId,
536  false, /* exact match on objsubId */
537  AuthIdRelationId, roleid,
539  }
540 
541  table_close(sdepRel, RowExclusiveLock);
542  }
543 
544  if (oldmembers)
545  pfree(oldmembers);
546  if (newmembers)
547  pfree(newmembers);
548 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
static void getOidListDiff(Oid *list1, int *nlist1, Oid *list2, int *nlist2)
Definition: pg_shdepend.c:410
static void shdepAddDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:1019
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:1169
bool IsPinnedObject(Oid classId, Oid objectId)
Definition: catalog.c:307
#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:1074
int i
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39