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

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

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

2442 {
2443  ObjectAddress *item;
2444 
2445  /* enlarge array if needed */
2446  if (addrs->numrefs >= addrs->maxrefs)
2447  {
2448  addrs->maxrefs *= 2;
2449  addrs->refs = (ObjectAddress *)
2450  repalloc(addrs->refs, addrs->maxrefs * sizeof(ObjectAddress));
2451  Assert(!addrs->extras);
2452  }
2453  /* record this item */
2454  item = addrs->refs + addrs->numrefs;
2455  *item = *object;
2456  addrs->numrefs++;
2457 }
ObjectAddress * refs
Definition: dependency.c:112
#define Assert(condition)
Definition: c.h:732
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1044
ObjectAddressExtra * extras
Definition: dependency.c:113

◆ 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:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define DependReferenceIndexId
Definition: indexing.h:151
int errcode(int sqlerrcode)
Definition: elog.c:570
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:352
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
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, rest)
Definition: elog.h:141
#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:784
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:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
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 310 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().

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

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

◆ copyTemplateDependencies()

void copyTemplateDependencies ( Oid  templateDbId,
Oid  newDbId 
)

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

797 {
798  Relation sdepRel;
799  TupleDesc sdepDesc;
800  ScanKeyData key[1];
801  SysScanDesc scan;
802  HeapTuple tup;
803  CatalogIndexState indstate;
804  Datum values[Natts_pg_shdepend];
805  bool nulls[Natts_pg_shdepend];
806  bool replace[Natts_pg_shdepend];
807 
808  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
809  sdepDesc = RelationGetDescr(sdepRel);
810 
811  indstate = CatalogOpenIndexes(sdepRel);
812 
813  /* Scan all entries with dbid = templateDbId */
814  ScanKeyInit(&key[0],
815  Anum_pg_shdepend_dbid,
816  BTEqualStrategyNumber, F_OIDEQ,
817  ObjectIdGetDatum(templateDbId));
818 
819  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
820  NULL, 1, key);
821 
822  /* Set up to copy the tuples except for inserting newDbId */
823  memset(values, 0, sizeof(values));
824  memset(nulls, false, sizeof(nulls));
825  memset(replace, false, sizeof(replace));
826 
827  replace[Anum_pg_shdepend_dbid - 1] = true;
828  values[Anum_pg_shdepend_dbid - 1] = ObjectIdGetDatum(newDbId);
829 
830  /*
831  * Copy the entries of the original database, changing the database Id to
832  * that of the new database. Note that because we are not copying rows
833  * with dbId == 0 (ie, rows describing dependent shared objects) we won't
834  * copy the ownership dependency of the template database itself; this is
835  * what we want.
836  */
837  while (HeapTupleIsValid(tup = systable_getnext(scan)))
838  {
839  HeapTuple newtup;
840 
841  newtup = heap_modify_tuple(tup, sdepDesc, values, nulls, replace);
842  CatalogTupleInsertWithInfo(sdepRel, newtup, indstate);
843 
844  heap_freetuple(newtup);
845  }
846 
847  systable_endscan(scan);
848 
849  CatalogCloseIndexes(indstate);
850  table_close(sdepRel, RowExclusiveLock);
851 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define SharedDependDependerIndexId
Definition: indexing.h:226
#define RelationGetDescr(relation)
Definition: rel.h:442
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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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(), create_proc_lang(), 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:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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 908 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().

909 {
910  Relation sdepRel;
911 
912  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
913 
914  shdepDropDependency(sdepRel, classId, objectId, objectSubId,
915  (objectSubId == 0),
918 
919  table_close(sdepRel, RowExclusiveLock);
920 }
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:985
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ dropDatabaseDependencies()

void dropDatabaseDependencies ( Oid  databaseId)

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

861 {
862  Relation sdepRel;
863  ScanKeyData key[1];
864  SysScanDesc scan;
865  HeapTuple tup;
866 
867  sdepRel = table_open(SharedDependRelationId, RowExclusiveLock);
868 
869  /*
870  * First, delete all the entries that have the database Oid in the dbid
871  * field.
872  */
873  ScanKeyInit(&key[0],
874  Anum_pg_shdepend_dbid,
875  BTEqualStrategyNumber, F_OIDEQ,
876  ObjectIdGetDatum(databaseId));
877  /* We leave the other index fields unspecified */
878 
879  scan = systable_beginscan(sdepRel, SharedDependDependerIndexId, true,
880  NULL, 1, key);
881 
882  while (HeapTupleIsValid(tup = systable_getnext(scan)))
883  {
884  CatalogTupleDelete(sdepRel, &tup->t_self);
885  }
886 
887  systable_endscan(scan);
888 
889  /* Now delete all entries corresponding to the database itself */
890  shdepDropDependency(sdepRel, DatabaseRelationId, databaseId, 0, true,
893 
894  table_close(sdepRel, RowExclusiveLock);
895 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define SharedDependDependerIndexId
Definition: indexing.h:226
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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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:985
#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)

Definition at line 2680 of file dependency.c.

References ObjectAddresses::extras, pfree(), and ObjectAddresses::refs.

Referenced by AlterTableNamespace(), AlterTypeNamespace(), ATPostAlterTypeCleanup(), makeConfigurationDependencies(), performDeletion(), performMultipleDeletions(), recordDependencyOnExpr(), recordDependencyOnSingleRelExpr(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

2681 {
2682  pfree(addrs->refs);
2683  if (addrs->extras)
2684  pfree(addrs->extras);
2685  pfree(addrs);
2686 }
void pfree(void *pointer)
Definition: mcxt.c:1031
ObjectAddress * refs
Definition: dependency.c:112
ObjectAddressExtra * extras
Definition: dependency.c:113

◆ get_constraint_index()

Oid get_constraint_index ( Oid  constraintId)

Definition at line 806 of file pg_depend.c.

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

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

807 {
808  Oid indexId = InvalidOid;
809  Relation depRel;
810  ScanKeyData key[3];
811  SysScanDesc scan;
812  HeapTuple tup;
813 
814  /* Search the dependency table for the dependent index */
815  depRel = table_open(DependRelationId, AccessShareLock);
816 
817  ScanKeyInit(&key[0],
818  Anum_pg_depend_refclassid,
819  BTEqualStrategyNumber, F_OIDEQ,
820  ObjectIdGetDatum(ConstraintRelationId));
821  ScanKeyInit(&key[1],
822  Anum_pg_depend_refobjid,
823  BTEqualStrategyNumber, F_OIDEQ,
824  ObjectIdGetDatum(constraintId));
825  ScanKeyInit(&key[2],
826  Anum_pg_depend_refobjsubid,
827  BTEqualStrategyNumber, F_INT4EQ,
828  Int32GetDatum(0));
829 
830  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
831  NULL, 3, key);
832 
833  while (HeapTupleIsValid(tup = systable_getnext(scan)))
834  {
835  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
836 
837  /*
838  * We assume any internal dependency of an index on the constraint
839  * must be what we are looking for.
840  */
841  if (deprec->classid == RelationRelationId &&
842  deprec->objsubid == 0 &&
843  deprec->deptype == DEPENDENCY_INTERNAL)
844  {
845  char relkind = get_rel_relkind(deprec->objid);
846 
847  /*
848  * This is pure paranoia; there shouldn't be any other relkinds
849  * dependent on a constraint.
850  */
851  if (relkind != RELKIND_INDEX &&
852  relkind != RELKIND_PARTITIONED_INDEX)
853  continue;
854 
855  indexId = deprec->objid;
856  break;
857  }
858  }
859 
860  systable_endscan(scan);
861  table_close(depRel, AccessShareLock);
862 
863  return indexId;
864 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
#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:352
char relkind
Definition: pg_class.h:81
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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 873 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().

874 {
875  Oid constraintId = InvalidOid;
876  Relation depRel;
877  ScanKeyData key[3];
878  SysScanDesc scan;
879  HeapTuple tup;
880 
881  /* Search the dependency table for the index */
882  depRel = table_open(DependRelationId, AccessShareLock);
883 
884  ScanKeyInit(&key[0],
885  Anum_pg_depend_classid,
886  BTEqualStrategyNumber, F_OIDEQ,
887  ObjectIdGetDatum(RelationRelationId));
888  ScanKeyInit(&key[1],
889  Anum_pg_depend_objid,
890  BTEqualStrategyNumber, F_OIDEQ,
891  ObjectIdGetDatum(indexId));
892  ScanKeyInit(&key[2],
893  Anum_pg_depend_objsubid,
894  BTEqualStrategyNumber, F_INT4EQ,
895  Int32GetDatum(0));
896 
897  scan = systable_beginscan(depRel, DependDependerIndexId, true,
898  NULL, 3, key);
899 
900  while (HeapTupleIsValid(tup = systable_getnext(scan)))
901  {
902  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
903 
904  /*
905  * We assume any internal dependency on a constraint must be what we
906  * are looking for.
907  */
908  if (deprec->refclassid == ConstraintRelationId &&
909  deprec->refobjsubid == 0 &&
910  deprec->deptype == DEPENDENCY_INTERNAL)
911  {
912  constraintId = deprec->refobjid;
913  break;
914  }
915  }
916 
917  systable_endscan(scan);
918  table_close(depRel, AccessShareLock);
919 
920  return constraintId;
921 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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 929 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().

930 {
931  List *result = NIL;
932  Relation depRel;
933  ScanKeyData key[3];
934  SysScanDesc scan;
935  HeapTuple tup;
936 
937  /* Search the dependency table for the index */
938  depRel = table_open(DependRelationId, AccessShareLock);
939 
940  ScanKeyInit(&key[0],
941  Anum_pg_depend_refclassid,
942  BTEqualStrategyNumber, F_OIDEQ,
943  ObjectIdGetDatum(RelationRelationId));
944  ScanKeyInit(&key[1],
945  Anum_pg_depend_refobjid,
946  BTEqualStrategyNumber, F_OIDEQ,
947  ObjectIdGetDatum(indexId));
948  ScanKeyInit(&key[2],
949  Anum_pg_depend_refobjsubid,
950  BTEqualStrategyNumber, F_INT4EQ,
951  Int32GetDatum(0));
952 
953  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
954  NULL, 3, key);
955 
956  while (HeapTupleIsValid(tup = systable_getnext(scan)))
957  {
958  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
959 
960  /*
961  * We assume any normal dependency from a constraint must be what we
962  * are looking for.
963  */
964  if (deprec->classid == ConstraintRelationId &&
965  deprec->objsubid == 0 &&
966  deprec->deptype == DEPENDENCY_NORMAL)
967  {
968  result = lappend_oid(result, deprec->objid);
969  }
970  }
971 
972  systable_endscan(scan);
973  table_close(depRel, AccessShareLock);
974 
975  return result;
976 }
#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:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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

◆ 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:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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 780 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().

781 {
783 
784  if (list_length(seqlist) > 1)
785  elog(ERROR, "more than one owned sequence found");
786  else if (list_length(seqlist) < 1)
787  {
788  if (missing_ok)
789  return InvalidOid;
790  else
791  elog(ERROR, "no owned sequence found");
792  }
793 
794  return linitial_oid(seqlist);
795 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:712
#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:226
Definition: pg_list.h:50

◆ getObjectClass()

ObjectClass getObjectClass ( const ObjectAddress object)

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

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

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 771 of file pg_depend.c.

References getOwnedSequences_internal().

Referenced by ExecuteTruncateGuts().

772 {
773  return getOwnedSequences_internal(relid, 0, 0);
774 }
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:712

◆ new_object_addresses()

ObjectAddresses* new_object_addresses ( void  )

Definition at line 2385 of file dependency.c.

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

Referenced by AlterExtensionNamespace(), AlterTableNamespace(), AlterTypeNamespace(), ATPostAlterTypeCleanup(), makeConfigurationDependencies(), performDeletion(), performMultipleDeletions(), PreCommit_on_commit_actions(), recordDependencyOnExpr(), recordDependencyOnSingleRelExpr(), ReindexRelationConcurrently(), RemoveObjects(), RemoveRelations(), and shdepDropOwned().

2386 {
2387  ObjectAddresses *addrs;
2388 
2389  addrs = palloc(sizeof(ObjectAddresses));
2390 
2391  addrs->numrefs = 0;
2392  addrs->maxrefs = 32;
2393  addrs->refs = (ObjectAddress *)
2394  palloc(addrs->maxrefs * sizeof(ObjectAddress));
2395  addrs->extras = NULL; /* until/unless needed */
2396 
2397  return addrs;
2398 }
ObjectAddress * refs
Definition: dependency.c:112
ObjectAddressExtra * extras
Definition: dependency.c:113
void * palloc(Size size)
Definition: mcxt.c:924

◆ object_address_present()

bool object_address_present ( const ObjectAddress object,
const ObjectAddresses addrs 
)

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

2502 {
2503  int i;
2504 
2505  for (i = addrs->numrefs - 1; i >= 0; i--)
2506  {
2507  const ObjectAddress *thisobj = addrs->refs + i;
2508 
2509  if (object->classId == thisobj->classId &&
2510  object->objectId == thisobj->objectId)
2511  {
2512  if (object->objectSubId == thisobj->objectSubId ||
2513  thisobj->objectSubId == 0)
2514  return true;
2515  }
2516  }
2517 
2518  return false;
2519 }
ObjectAddress * refs
Definition: dependency.c:112
int i

◆ performDeletion()

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

Definition at line 315 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(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropIdentity(), DefineQueryRewrite(), do_autovacuum(), dropOperators(), dropProcedures(), finish_heap_swap(), inv_drop(), PublicationDropTables(), RemoveAttrDefault(), RemoveTempRelations(), RemoveUserMapping(), SetDefaultACL(), and tryAttachPartitionForeignKey().

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

◆ performMultipleDeletions()

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

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

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

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

Referenced by makeConfigurationDependencies().

2652 {
2654  recordMultipleDependencies(depender,
2655  referenced->refs, referenced->numrefs,
2656  behavior);
2657 }
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2281
ObjectAddress * refs
Definition: dependency.c:112
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(), changeDependencyFor(), CloneFkReferencing(), CollationCreate(), ConstraintSetParentConstraint(), ConversionCreate(), create_proc_lang(), create_toast_table(), CreateAccessMethod(), CreateCast(), CreateConstraintEntry(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), 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(), SetFunctionArgType(), SetFunctionReturnType(), 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 CollationCreate(), ConversionCreate(), create_proc_lang(), CreateAccessMethod(), CreateCast(), CreateForeignDataWrapper(), CreateForeignServer(), CreateOpFamily(), 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:71
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:610
char * get_extension_name(Oid ext_oid)
Definition: extension.c:183
int errcode(int sqlerrcode)
Definition: elog.c:570
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:638
char * getObjectDescription(const ObjectAddress *object)
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool creating_extension
Definition: extension.c:70
#define Assert(condition)
Definition: c.h:732
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ recordDependencyOnExpr()

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

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

1589 {
1591 
1592  context.addrs = new_object_addresses();
1593 
1594  /* Set up interpretation for Vars at varlevelsup = 0 */
1595  context.rtables = list_make1(rtable);
1596 
1597  /* Scan the expression tree for referenceable objects */
1598  find_expr_references_walker(expr, &context);
1599 
1600  /* Remove any duplicates */
1602 
1603  /* And record 'em */
1604  recordMultipleDependencies(depender,
1605  context.addrs->refs, context.addrs->numrefs,
1606  behavior);
1607 
1608  free_object_addresses(context.addrs);
1609 }
static bool find_expr_references_walker(Node *node, find_expr_references_context *context)
Definition: dependency.c:1738
ObjectAddresses * addrs
Definition: dependency.c:138
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2385
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2680
static void eliminate_duplicate_dependencies(ObjectAddresses *addrs)
Definition: dependency.c:2281
#define list_make1(x1)
Definition: pg_list.h:227
ObjectAddress * refs
Definition: dependency.c:112
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 165 of file pg_shdepend.c.

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

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

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

◆ recordDependencyOnSingleRelExpr()

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

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

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

◆ 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:84
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:374
#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 121 of file pg_shdepend.c.

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

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

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

664 {
665  bool ret = false;
666  Relation depRel;
667  ScanKeyData key[2];
668  SysScanDesc scan;
669  HeapTuple tup;
670 
671  depRel = table_open(DependRelationId, AccessShareLock);
672 
673  ScanKeyInit(&key[0],
674  Anum_pg_depend_classid,
675  BTEqualStrategyNumber, F_OIDEQ,
676  ObjectIdGetDatum(RelationRelationId));
677  ScanKeyInit(&key[1],
678  Anum_pg_depend_objid,
679  BTEqualStrategyNumber, F_OIDEQ,
680  ObjectIdGetDatum(seqId));
681 
682  scan = systable_beginscan(depRel, DependDependerIndexId, true,
683  NULL, 2, key);
684 
685  while (HeapTupleIsValid((tup = systable_getnext(scan))))
686  {
687  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
688 
689  if (depform->refclassid == RelationRelationId &&
690  depform->deptype == deptype)
691  {
692  *tableId = depform->refobjid;
693  *colId = depform->refobjsubid;
694  ret = true;
695  break; /* no need to keep scanning */
696  }
697  }
698 
699  systable_endscan(scan);
700 
701  table_close(depRel, AccessShareLock);
702 
703  return ret;
704 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#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:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#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 1248 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().

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

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

◆ shdepReassignOwned()

void shdepReassignOwned ( List relids,
Oid  newrole 
)

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

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

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

Referenced by shdepDropOwned().

2669 {
2670  if (addrs->numrefs > 1)
2671  qsort((void *) addrs->refs, addrs->numrefs,
2672  sizeof(ObjectAddress),
2674 }
static int object_address_comparator(const void *a, const void *b)
Definition: dependency.c:2341
ObjectAddress * refs
Definition: dependency.c:112
#define qsort(a, b, c, d)
Definition: port.h:492

◆ updateAclDependencies()

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

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

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