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

Go to the source code of this file.

Macros

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

Typedefs

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

Enumerations

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

Functions

void 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 changeDependencyFor (Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
long changeDependenciesOf (Oid classId, Oid oldObjectId, Oid newObjectId)
 
long changeDependenciesOn (Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
Oid getExtensionOfObject (Oid classId, Oid objectId)
 
ListgetAutoExtensionsOfObject (Oid classId, Oid objectId)
 
bool sequenceIsOwned (Oid seqId, char deptype, Oid *tableId, int32 *colId)
 
ListgetOwnedSequences (Oid relid)
 
Oid getIdentitySequence (Oid relid, AttrNumber attnum, bool missing_ok)
 
Oid get_constraint_index (Oid constraintId)
 
Oid get_index_constraint (Oid indexId)
 
Listget_index_ref_constraints (Oid indexId)
 
void recordSharedDependencyOn (ObjectAddress *depender, ObjectAddress *referenced, SharedDependencyType deptype)
 
void deleteSharedDependencyRecordsFor (Oid classId, Oid objectId, int32 objectSubId)
 
void recordDependencyOnOwner (Oid classId, Oid objectId, Oid owner)
 
void changeDependencyOnOwner (Oid classId, Oid objectId, Oid newOwnerId)
 
void updateAclDependencies (Oid classId, Oid objectId, int32 objectSubId, Oid ownerId, int noldmembers, Oid *oldmembers, int nnewmembers, Oid *newmembers)
 
bool checkSharedDependencies (Oid classId, Oid objectId, char **detail_msg, char **detail_log_msg)
 
void shdepLockAndCheckObject (Oid classId, Oid objectId)
 
void copyTemplateDependencies (Oid templateDbId, Oid newDbId)
 
void dropDatabaseDependencies (Oid databaseId)
 
void shdepDropOwned (List *relids, DropBehavior behavior)
 
void shdepReassignOwned (List *relids, Oid newrole)
 

Macro Definition Documentation

◆ LAST_OCLASS

#define LAST_OCLASS   OCLASS_TRANSFORM

Definition at line 131 of file dependency.h.

Referenced by add_object_address().

◆ PERFORM_DELETION_CONCURRENT_LOCK

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

Definition at line 139 of file dependency.h.

Referenced by doDeletion(), and ReindexRelationConcurrently().

◆ PERFORM_DELETION_CONCURRENTLY

#define PERFORM_DELETION_CONCURRENTLY   0x0002 /* concurrent drop */

Definition at line 135 of file dependency.h.

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

◆ PERFORM_DELETION_INTERNAL

◆ PERFORM_DELETION_QUIETLY

#define PERFORM_DELETION_QUIETLY   0x0004 /* suppress notices */

◆ PERFORM_DELETION_SKIP_EXTENSIONS

#define PERFORM_DELETION_SKIP_EXTENSIONS   0x0010 /* keep extensions */

Definition at line 138 of file dependency.h.

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

◆ PERFORM_DELETION_SKIP_ORIGINAL

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

Definition at line 137 of file dependency.h.

Referenced by deleteObjectsInList(), and RemoveTempRelations().

Typedef Documentation

◆ DependencyType

◆ ObjectAddresses

Definition at line 83 of file dependency.h.

◆ ObjectClass

typedef enum ObjectClass ObjectClass

◆ SharedDependencyType

Enumeration Type Documentation

◆ DependencyType

Enumerator
DEPENDENCY_NORMAL 
DEPENDENCY_AUTO 
DEPENDENCY_INTERNAL 
DEPENDENCY_PARTITION_PRI 
DEPENDENCY_PARTITION_SEC 
DEPENDENCY_EXTENSION 
DEPENDENCY_AUTO_EXTENSION 
DEPENDENCY_PIN 

Definition at line 31 of file dependency.h.

◆ ObjectClass

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

Definition at line 89 of file dependency.h.

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

◆ SharedDependencyType

Enumerator
SHARED_DEPENDENCY_PIN 
SHARED_DEPENDENCY_OWNER 
SHARED_DEPENDENCY_ACL 
SHARED_DEPENDENCY_POLICY 
SHARED_DEPENDENCY_INVALID 

Definition at line 73 of file dependency.h.

Function Documentation

◆ add_exact_object_address()

void add_exact_object_address ( const ObjectAddress object,
ObjectAddresses addrs 
)

Definition at line 2470 of file dependency.c.

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

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

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

◆ changeDependenciesOf()

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

Definition at line 407 of file pg_depend.c.

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

Referenced by index_concurrently_swap().

409 {
410  long count = 0;
411  Relation depRel;
412  ScanKeyData key[2];
413  SysScanDesc scan;
414  HeapTuple tup;
415 
416  depRel = table_open(DependRelationId, RowExclusiveLock);
417 
418  ScanKeyInit(&key[0],
419  Anum_pg_depend_classid,
420  BTEqualStrategyNumber, F_OIDEQ,
421  ObjectIdGetDatum(classId));
422  ScanKeyInit(&key[1],
423  Anum_pg_depend_objid,
424  BTEqualStrategyNumber, F_OIDEQ,
425  ObjectIdGetDatum(oldObjectId));
426 
427  scan = systable_beginscan(depRel, DependDependerIndexId, true,
428  NULL, 2, key);
429 
430  while (HeapTupleIsValid((tup = systable_getnext(scan))))
431  {
432  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
433 
434  /* make a modifiable copy */
435  tup = heap_copytuple(tup);
436  depform = (Form_pg_depend) GETSTRUCT(tup);
437 
438  depform->objid = newObjectId;
439 
440  CatalogTupleUpdate(depRel, &tup->t_self, tup);
441 
442  heap_freetuple(tup);
443 
444  count++;
445  }
446 
447  systable_endscan(scan);
448 
449  table_close(depRel, RowExclusiveLock);
450 
451  return count;
452 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependenciesOn()

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

Definition at line 463 of file pg_depend.c.

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

Referenced by index_concurrently_swap().

465 {
466  long count = 0;
467  Relation depRel;
468  ScanKeyData key[2];
469  SysScanDesc scan;
470  HeapTuple tup;
471  ObjectAddress objAddr;
472  bool newIsPinned;
473 
474  depRel = table_open(DependRelationId, RowExclusiveLock);
475 
476  /*
477  * If oldRefObjectId is pinned, there won't be any dependency entries on
478  * it --- we can't cope in that case. (This isn't really worth expending
479  * code to fix, in current usage; it just means you can't rename stuff out
480  * of pg_catalog, which would likely be a bad move anyway.)
481  */
482  objAddr.classId = refClassId;
483  objAddr.objectId = oldRefObjectId;
484  objAddr.objectSubId = 0;
485 
486  if (isObjectPinned(&objAddr, depRel))
487  ereport(ERROR,
488  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
489  errmsg("cannot remove dependency on %s because it is a system object",
490  getObjectDescription(&objAddr))));
491 
492  /*
493  * We can handle adding a dependency on something pinned, though, since
494  * that just means deleting the dependency entry.
495  */
496  objAddr.objectId = newRefObjectId;
497 
498  newIsPinned = isObjectPinned(&objAddr, depRel);
499 
500  /* Now search for dependency records */
501  ScanKeyInit(&key[0],
502  Anum_pg_depend_refclassid,
503  BTEqualStrategyNumber, F_OIDEQ,
504  ObjectIdGetDatum(refClassId));
505  ScanKeyInit(&key[1],
506  Anum_pg_depend_refobjid,
507  BTEqualStrategyNumber, F_OIDEQ,
508  ObjectIdGetDatum(oldRefObjectId));
509 
510  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
511  NULL, 2, key);
512 
513  while (HeapTupleIsValid((tup = systable_getnext(scan))))
514  {
515  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
516 
517  if (newIsPinned)
518  CatalogTupleDelete(depRel, &tup->t_self);
519  else
520  {
521  /* make a modifiable copy */
522  tup = heap_copytuple(tup);
523  depform = (Form_pg_depend) GETSTRUCT(tup);
524 
525  depform->refobjid = newRefObjectId;
526 
527  CatalogTupleUpdate(depRel, &tup->t_self, tup);
528 
529  heap_freetuple(tup);
530  }
531 
532  count++;
533  }
534 
535  systable_endscan(scan);
536 
537  table_close(depRel, RowExclusiveLock);
538 
539  return count;
540 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependReferenceIndexId
Definition: indexing.h:151
int errcode(int sqlerrcode)
Definition: elog.c:610
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:552
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define ereport(elevel,...)
Definition: elog.h:144
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependencyFor()

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

Definition at line 297 of file pg_depend.c.

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

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

300 {
301  long count = 0;
302  Relation depRel;
303  ScanKeyData key[2];
304  SysScanDesc scan;
305  HeapTuple tup;
306  ObjectAddress objAddr;
307  ObjectAddress depAddr;
308  bool oldIsPinned;
309  bool newIsPinned;
310 
311  depRel = table_open(DependRelationId, RowExclusiveLock);
312 
313  /*
314  * Check to see if either oldRefObjectId or newRefObjectId is pinned.
315  * Pinned objects should not have any dependency entries pointing to them,
316  * so in these cases we should add or remove a pg_depend entry, or do
317  * nothing at all, rather than update an entry as in the normal case.
318  */
319  objAddr.classId = refClassId;
320  objAddr.objectId = oldRefObjectId;
321  objAddr.objectSubId = 0;
322 
323  oldIsPinned = isObjectPinned(&objAddr, depRel);
324 
325  objAddr.objectId = newRefObjectId;
326 
327  newIsPinned = isObjectPinned(&objAddr, depRel);
328 
329  if (oldIsPinned)
330  {
331  table_close(depRel, RowExclusiveLock);
332 
333  /*
334  * If both are pinned, we need do nothing. However, return 1 not 0,
335  * else callers will think this is an error case.
336  */
337  if (newIsPinned)
338  return 1;
339 
340  /*
341  * There is no old dependency record, but we should insert a new one.
342  * Assume a normal dependency is wanted.
343  */
344  depAddr.classId = classId;
345  depAddr.objectId = objectId;
346  depAddr.objectSubId = 0;
347  recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL);
348 
349  return 1;
350  }
351 
352  /* There should be existing dependency record(s), so search. */
353  ScanKeyInit(&key[0],
354  Anum_pg_depend_classid,
355  BTEqualStrategyNumber, F_OIDEQ,
356  ObjectIdGetDatum(classId));
357  ScanKeyInit(&key[1],
358  Anum_pg_depend_objid,
359  BTEqualStrategyNumber, F_OIDEQ,
360  ObjectIdGetDatum(objectId));
361 
362  scan = systable_beginscan(depRel, DependDependerIndexId, true,
363  NULL, 2, key);
364 
365  while (HeapTupleIsValid((tup = systable_getnext(scan))))
366  {
367  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
368 
369  if (depform->refclassid == refClassId &&
370  depform->refobjid == oldRefObjectId)
371  {
372  if (newIsPinned)
373  CatalogTupleDelete(depRel, &tup->t_self);
374  else
375  {
376  /* make a modifiable copy */
377  tup = heap_copytuple(tup);
378  depform = (Form_pg_depend) GETSTRUCT(tup);
379 
380  depform->refobjid = newRefObjectId;
381 
382  CatalogTupleUpdate(depRel, &tup->t_self, tup);
383 
384  heap_freetuple(tup);
385  }
386 
387  count++;
388  }
389  }
390 
391  systable_endscan(scan);
392 
393  table_close(depRel, RowExclusiveLock);
394 
395  return count;
396 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:552
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ changeDependencyOnOwner()

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

Definition at line 309 of file pg_shdepend.c.

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

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

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

◆ checkSharedDependencies()

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

Definition at line 577 of file pg_shdepend.c.

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

Referenced by DropRole().

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

◆ copyTemplateDependencies()

void copyTemplateDependencies ( Oid  templateDbId,
Oid  newDbId 
)

Definition at line 795 of file pg_shdepend.c.

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

Referenced by createdb().

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

◆ deleteDependencyRecordsFor()

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

Definition at line 190 of file pg_depend.c.

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

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

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

◆ deleteDependencyRecordsForClass()

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

Definition at line 240 of file pg_depend.c.

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

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

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

◆ deleteSharedDependencyRecordsFor()

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

Definition at line 907 of file pg_shdepend.c.

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

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

908 {
909  Relation sdepRel;
910 
911  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
912 
913  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
914  (objectSubId == 0),
917 
918  table_close(sdepRel, RowExclusiveLock);
919 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvalidOid
Definition: postgres_ext.h:36
static void shdepDropDependency(Relation sdepRel, Oid classId, Oid objectId, int32 objsubId, bool drop_subobjects, Oid refclassId, Oid refobjId, SharedDependencyType deptype)
Definition: pg_shdepend.c:984
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

Definition at line 859 of file pg_shdepend.c.

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

Referenced by dropdb().

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

◆ free_object_addresses()

void free_object_addresses ( ObjectAddresses addrs)

◆ get_constraint_index()

Oid get_constraint_index ( Oid  constraintId)

Definition at line 849 of file pg_depend.c.

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

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

850 {
851  Oid indexId = InvalidOid;
852  Relation depRel;
853  ScanKeyData key[3];
854  SysScanDesc scan;
855  HeapTuple tup;
856 
857  /* Search the dependency table for the dependent index */
858  depRel = table_open(DependRelationId, AccessShareLock);
859 
860  ScanKeyInit(&key[0],
861  Anum_pg_depend_refclassid,
862  BTEqualStrategyNumber, F_OIDEQ,
863  ObjectIdGetDatum(ConstraintRelationId));
864  ScanKeyInit(&key[1],
865  Anum_pg_depend_refobjid,
866  BTEqualStrategyNumber, F_OIDEQ,
867  ObjectIdGetDatum(constraintId));
868  ScanKeyInit(&key[2],
869  Anum_pg_depend_refobjsubid,
870  BTEqualStrategyNumber, F_INT4EQ,
871  Int32GetDatum(0));
872 
873  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
874  NULL, 3, key);
875 
876  while (HeapTupleIsValid(tup = systable_getnext(scan)))
877  {
878  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
879 
880  /*
881  * We assume any internal dependency of an index on the constraint
882  * must be what we are looking for.
883  */
884  if (deprec->classid == RelationRelationId &&
885  deprec->objsubid == 0 &&
886  deprec->deptype == DEPENDENCY_INTERNAL)
887  {
888  char relkind = get_rel_relkind(deprec->objid);
889 
890  /*
891  * This is pure paranoia; there shouldn't be any other relkinds
892  * dependent on a constraint.
893  */
894  if (relkind != RELKIND_INDEX &&
895  relkind != RELKIND_PARTITIONED_INDEX)
896  continue;
897 
898  indexId = deprec->objid;
899  break;
900  }
901  }
902 
903  systable_endscan(scan);
904  table_close(depRel, AccessShareLock);
905 
906  return indexId;
907 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1866
#define DependReferenceIndexId
Definition: indexing.h:151
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 916 of file pg_depend.c.

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

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

917 {
918  Oid constraintId = InvalidOid;
919  Relation depRel;
920  ScanKeyData key[3];
921  SysScanDesc scan;
922  HeapTuple tup;
923 
924  /* Search the dependency table for the index */
925  depRel = table_open(DependRelationId, AccessShareLock);
926 
927  ScanKeyInit(&key[0],
928  Anum_pg_depend_classid,
929  BTEqualStrategyNumber, F_OIDEQ,
930  ObjectIdGetDatum(RelationRelationId));
931  ScanKeyInit(&key[1],
932  Anum_pg_depend_objid,
933  BTEqualStrategyNumber, F_OIDEQ,
934  ObjectIdGetDatum(indexId));
935  ScanKeyInit(&key[2],
936  Anum_pg_depend_objsubid,
937  BTEqualStrategyNumber, F_INT4EQ,
938  Int32GetDatum(0));
939 
940  scan = systable_beginscan(depRel, DependDependerIndexId, true,
941  NULL, 3, key);
942 
943  while (HeapTupleIsValid(tup = systable_getnext(scan)))
944  {
945  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
946 
947  /*
948  * We assume any internal dependency on a constraint must be what we
949  * are looking for.
950  */
951  if (deprec->refclassid == ConstraintRelationId &&
952  deprec->refobjsubid == 0 &&
953  deprec->deptype == DEPENDENCY_INTERNAL)
954  {
955  constraintId = deprec->refobjid;
956  break;
957  }
958  }
959 
960  systable_endscan(scan);
961  table_close(depRel, AccessShareLock);
962 
963  return constraintId;
964 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_index_ref_constraints()

List* get_index_ref_constraints ( Oid  indexId)

Definition at line 972 of file pg_depend.c.

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

Referenced by index_concurrently_swap().

973 {
974  List *result = NIL;
975  Relation depRel;
976  ScanKeyData key[3];
977  SysScanDesc scan;
978  HeapTuple tup;
979 
980  /* Search the dependency table for the index */
981  depRel = table_open(DependRelationId, AccessShareLock);
982 
983  ScanKeyInit(&key[0],
984  Anum_pg_depend_refclassid,
985  BTEqualStrategyNumber, F_OIDEQ,
986  ObjectIdGetDatum(RelationRelationId));
987  ScanKeyInit(&key[1],
988  Anum_pg_depend_refobjid,
989  BTEqualStrategyNumber, F_OIDEQ,
990  ObjectIdGetDatum(indexId));
991  ScanKeyInit(&key[2],
992  Anum_pg_depend_refobjsubid,
993  BTEqualStrategyNumber, F_INT4EQ,
994  Int32GetDatum(0));
995 
996  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
997  NULL, 3, key);
998 
999  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1000  {
1001  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1002 
1003  /*
1004  * We assume any normal dependency from a constraint must be what we
1005  * are looking for.
1006  */
1007  if (deprec->classid == ConstraintRelationId &&
1008  deprec->objsubid == 0 &&
1009  deprec->deptype == DEPENDENCY_NORMAL)
1010  {
1011  result = lappend_oid(result, deprec->objid);
1012  }
1013  }
1014 
1015  systable_endscan(scan);
1016  table_close(depRel, AccessShareLock);
1017 
1018  return result;
1019 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependReferenceIndexId
Definition: indexing.h:151
#define AccessShareLock
Definition: lockdefs.h:36
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:479
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getAutoExtensionsOfObject()

List* getAutoExtensionsOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 656 of file pg_depend.c.

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

Referenced by ExecAlterObjectDependsStmt().

657 {
658  List *result = NIL;
659  Relation depRel;
660  ScanKeyData key[2];
661  SysScanDesc scan;
662  HeapTuple tup;
663 
664  depRel = table_open(DependRelationId, AccessShareLock);
665 
666  ScanKeyInit(&key[0],
667  Anum_pg_depend_classid,
668  BTEqualStrategyNumber, F_OIDEQ,
669  ObjectIdGetDatum(classId));
670  ScanKeyInit(&key[1],
671  Anum_pg_depend_objid,
672  BTEqualStrategyNumber, F_OIDEQ,
673  ObjectIdGetDatum(objectId));
674 
675  scan = systable_beginscan(depRel, DependDependerIndexId, true,
676  NULL, 2, key);
677 
678  while (HeapTupleIsValid((tup = systable_getnext(scan))))
679  {
680  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
681 
682  if (depform->refclassid == ExtensionRelationId &&
683  depform->deptype == DEPENDENCY_AUTO_EXTENSION)
684  result = lappend_oid(result, depform->refobjid);
685  }
686 
687  systable_endscan(scan);
688 
689  table_close(depRel, AccessShareLock);
690 
691  return result;
692 }
#define NIL
Definition: pg_list.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
Definition: pg_list.h:50
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getExtensionOfObject()

Oid getExtensionOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 610 of file pg_depend.c.

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

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

611 {
612  Oid result = InvalidOid;
613  Relation depRel;
614  ScanKeyData key[2];
615  SysScanDesc scan;
616  HeapTuple tup;
617 
618  depRel = table_open(DependRelationId, AccessShareLock);
619 
620  ScanKeyInit(&key[0],
621  Anum_pg_depend_classid,
622  BTEqualStrategyNumber, F_OIDEQ,
623  ObjectIdGetDatum(classId));
624  ScanKeyInit(&key[1],
625  Anum_pg_depend_objid,
626  BTEqualStrategyNumber, F_OIDEQ,
627  ObjectIdGetDatum(objectId));
628 
629  scan = systable_beginscan(depRel, DependDependerIndexId, true,
630  NULL, 2, key);
631 
632  while (HeapTupleIsValid((tup = systable_getnext(scan))))
633  {
634  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
635 
636  if (depform->refclassid == ExtensionRelationId &&
637  depform->deptype == DEPENDENCY_EXTENSION)
638  {
639  result = depform->refobjid;
640  break; /* no need to keep scanning */
641  }
642  }
643 
644  systable_endscan(scan);
645 
646  table_close(depRel, AccessShareLock);
647 
648  return result;
649 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependDependerIndexId
Definition: indexing.h:149
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getIdentitySequence()

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

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

824 {
826 
827  if (list_length(seqlist) > 1)
828  elog(ERROR, "more than one owned sequence found");
829  else if (list_length(seqlist) < 1)
830  {
831  if (missing_ok)
832  return InvalidOid;
833  else
834  elog(ERROR, "no owned sequence found");
835  }
836 
837  return linitial_oid(seqlist);
838 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:755
#define ERROR
Definition: elog.h:43
#define InvalidOid
Definition: postgres_ext.h:36
int16 attnum
Definition: pg_attribute.h:79
#define linitial_oid(l)
Definition: pg_list.h:197
static int list_length(const List *l)
Definition: pg_list.h:169
#define elog(elevel,...)
Definition: elog.h:214
Definition: pg_list.h:50

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

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

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

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 814 of file pg_depend.c.

References getOwnedSequences_internal().

Referenced by ExecuteTruncateGuts().

815 {
816  return getOwnedSequences_internal(relid, 0, 0);
817 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:755

◆ new_object_addresses()

ObjectAddresses* new_object_addresses ( void  )

◆ object_address_present()

bool object_address_present ( const ObjectAddress object,
const ObjectAddresses addrs 
)

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

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

◆ performDeletion()

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

Definition at line 316 of file dependency.c.

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

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

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

◆ performMultipleDeletions()

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

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

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

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

Referenced by makeConfigurationDependencies().

2682 {
2684  recordMultipleDependencies(depender,
2685  referenced->refs, referenced->numrefs,
2686  behavior);
2687 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2311
ObjectAddress * refs
Definition: dependency.c:113
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:55

◆ recordDependencyOn()

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

Definition at line 43 of file pg_depend.c.

References recordMultipleDependencies().

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

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

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

Definition at line 138 of file pg_depend.c.

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

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

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

◆ recordDependencyOnExpr()

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

Definition at line 1587 of file dependency.c.

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

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

1590 {
1592 
1593  context.addrs = new_object_addresses();
1594 
1595  /* Set up interpretation for Vars at varlevelsup = 0 */
1596  context.rtables = list_make1(rtable);
1597 
1598  /* Scan the expression tree for referenceable objects */
1599  find_expr_references_walker(expr, &context);
1600 
1601  /* Remove any duplicates */
1603 
1604  /* And record 'em */
1605  recordMultipleDependencies(depender,
1606  context.addrs->refs, context.addrs->numrefs,
1607  behavior);
1608 
1609  free_object_addresses(context.addrs);
1610 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1733
ObjectAddresses * addrs
Definition: dependency.c:139
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2415
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2710
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2311
#define list_make1(x1)
Definition: pg_list.h:227
ObjectAddress * refs
Definition: dependency.c:113
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition: pg_depend.c:55

◆ recordDependencyOnOwner()

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

Definition at line 164 of file pg_shdepend.c.

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

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

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

◆ recordDependencyOnSingleRelExpr()

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

Definition at line 1630 of file dependency.c.

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

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

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

◆ recordMultipleDependencies()

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

Definition at line 55 of file pg_depend.c.

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

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

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

◆ recordSharedDependencyOn()

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

Definition at line 120 of file pg_shdepend.c.

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

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

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

◆ sequenceIsOwned()

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

Definition at line 706 of file pg_depend.c.

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

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

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

◆ shdepDropOwned()

void shdepDropOwned ( List relids,
DropBehavior  behavior 
)

Definition at line 1247 of file pg_shdepend.c.

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

Referenced by DropOwnedObjects().

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

◆ shdepLockAndCheckObject()

void shdepLockAndCheckObject ( Oid  classId,
Oid  objectId 
)

Definition at line 1071 of file pg_shdepend.c.

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

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

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

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

Definition at line 1377 of file pg_shdepend.c.

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

Referenced by ReassignOwnedObjects().

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

◆ sort_object_addresses()

void sort_object_addresses ( ObjectAddresses addrs)

Definition at line 2698 of file dependency.c.

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

Referenced by shdepDropOwned().

2699 {
2700  if (addrs->numrefs > 1)
2701  qsort((void *) addrs->refs, addrs->numrefs,
2702  sizeof(ObjectAddress),
2704 }
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2371
ObjectAddress * refs
Definition: dependency.c:113
#define qsort(a, b, c, d)
Definition: port.h:479

◆ updateAclDependencies()

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

Definition at line 426 of file pg_shdepend.c.

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

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

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