PostgreSQL Source Code  git master
pg_depend.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_depend.h"
#include "catalog/pg_extension.h"
#include "commands/extension.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/tqual.h"
Include dependency graph for pg_depend.c:

Go to the source code of this file.

Functions

static bool isObjectPinned (const ObjectAddress *object, Relation rel)
 
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)
 
Oid getExtensionOfObject (Oid classId, Oid objectId)
 
bool sequenceIsOwned (Oid seqId, char deptype, Oid *tableId, int32 *colId)
 
ListgetOwnedSequences (Oid relid, AttrNumber attnum)
 
Oid getOwnedSequence (Oid relid, AttrNumber attnum)
 
Oid get_constraint_index (Oid constraintId)
 
Oid get_index_constraint (Oid indexId)
 

Function Documentation

◆ changeDependencyFor()

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

Definition at line 295 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, DependDependerIndexId, ereport, errcode(), errmsg(), ERROR, getObjectDescription(), GETSTRUCT, heap_close, heap_copytuple(), heap_freetuple(), heap_open(), HeapTupleIsValid, isObjectPinned(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

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

298 {
299  long count = 0;
300  Relation depRel;
301  ScanKeyData key[2];
302  SysScanDesc scan;
303  HeapTuple tup;
304  ObjectAddress objAddr;
305  bool newIsPinned;
306 
307  depRel = heap_open(DependRelationId, RowExclusiveLock);
308 
309  /*
310  * If oldRefObjectId is pinned, there won't be any dependency entries on
311  * it --- we can't cope in that case. (This isn't really worth expending
312  * code to fix, in current usage; it just means you can't rename stuff out
313  * of pg_catalog, which would likely be a bad move anyway.)
314  */
315  objAddr.classId = refClassId;
316  objAddr.objectId = oldRefObjectId;
317  objAddr.objectSubId = 0;
318 
319  if (isObjectPinned(&objAddr, depRel))
320  ereport(ERROR,
321  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
322  errmsg("cannot remove dependency on %s because it is a system object",
323  getObjectDescription(&objAddr))));
324 
325  /*
326  * We can handle adding a dependency on something pinned, though, since
327  * that just means deleting the dependency entry.
328  */
329  objAddr.objectId = newRefObjectId;
330 
331  newIsPinned = isObjectPinned(&objAddr, depRel);
332 
333  /* Now search for dependency records */
334  ScanKeyInit(&key[0],
335  Anum_pg_depend_classid,
336  BTEqualStrategyNumber, F_OIDEQ,
337  ObjectIdGetDatum(classId));
338  ScanKeyInit(&key[1],
339  Anum_pg_depend_objid,
340  BTEqualStrategyNumber, F_OIDEQ,
341  ObjectIdGetDatum(objectId));
342 
343  scan = systable_beginscan(depRel, DependDependerIndexId, true,
344  NULL, 2, key);
345 
346  while (HeapTupleIsValid((tup = systable_getnext(scan))))
347  {
348  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
349 
350  if (depform->refclassid == refClassId &&
351  depform->refobjid == oldRefObjectId)
352  {
353  if (newIsPinned)
354  CatalogTupleDelete(depRel, &tup->t_self);
355  else
356  {
357  /* make a modifiable copy */
358  tup = heap_copytuple(tup);
359  depform = (Form_pg_depend) GETSTRUCT(tup);
360 
361  depform->refobjid = newRefObjectId;
362 
363  CatalogTupleUpdate(depRel, &tup->t_self, tup);
364 
365  heap_freetuple(tup);
366  }
367 
368  count++;
369  }
370  }
371 
372  systable_endscan(scan);
373 
374  heap_close(depRel, RowExclusiveLock);
375 
376  return count;
377 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:722
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define DependDependerIndexId
Definition: indexing.h:146
int errcode(int sqlerrcode)
Definition: elog.c:575
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * getObjectDescription(const ObjectAddress *object)
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
static bool isObjectPinned(const ObjectAddress *object, Relation rel)
Definition: pg_depend.c:389
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
#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:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
int errmsg(const char *fmt,...)
Definition: elog.c:797
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ deleteDependencyRecordsFor()

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

Definition at line 191 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, DEPENDENCY_EXTENSION, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

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

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

◆ deleteDependencyRecordsForClass()

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

Definition at line 241 of file pg_depend.c.

References BTEqualStrategyNumber, CatalogTupleDelete(), DependDependerIndexId, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

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

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

◆ get_constraint_index()

Oid get_constraint_index ( Oid  constraintId)

Definition at line 626 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_INTERNAL, DependReferenceIndexId, get_rel_relkind(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, InvalidOid, ObjectIdGetDatum, relkind, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

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

627 {
628  Oid indexId = InvalidOid;
629  Relation depRel;
630  ScanKeyData key[3];
631  SysScanDesc scan;
632  HeapTuple tup;
633 
634  /* Search the dependency table for the dependent index */
635  depRel = heap_open(DependRelationId, AccessShareLock);
636 
637  ScanKeyInit(&key[0],
638  Anum_pg_depend_refclassid,
639  BTEqualStrategyNumber, F_OIDEQ,
640  ObjectIdGetDatum(ConstraintRelationId));
641  ScanKeyInit(&key[1],
642  Anum_pg_depend_refobjid,
643  BTEqualStrategyNumber, F_OIDEQ,
644  ObjectIdGetDatum(constraintId));
645  ScanKeyInit(&key[2],
646  Anum_pg_depend_refobjsubid,
647  BTEqualStrategyNumber, F_INT4EQ,
648  Int32GetDatum(0));
649 
650  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
651  NULL, 3, key);
652 
653  while (HeapTupleIsValid(tup = systable_getnext(scan)))
654  {
655  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
656 
657  /*
658  * We assume any internal dependency of an index on the constraint
659  * must be what we are looking for.
660  */
661  if (deprec->classid == RelationRelationId &&
662  deprec->objsubid == 0 &&
663  deprec->deptype == DEPENDENCY_INTERNAL)
664  {
665  char relkind = get_rel_relkind(deprec->objid);
666 
667  /* This is pure paranoia; there shouldn't be any such */
668  if (relkind != RELKIND_INDEX &&
669  relkind != RELKIND_PARTITIONED_INDEX)
670  break;
671 
672  indexId = deprec->objid;
673  break;
674  }
675  }
676 
677  systable_endscan(scan);
678  heap_close(depRel, AccessShareLock);
679 
680  return indexId;
681 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
#define DependReferenceIndexId
Definition: indexing.h:148
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
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:331
char relkind
Definition: pg_class.h:51
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:464
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 689 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_INTERNAL, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, InvalidOid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

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

690 {
691  Oid constraintId = InvalidOid;
692  Relation depRel;
693  ScanKeyData key[3];
694  SysScanDesc scan;
695  HeapTuple tup;
696 
697  /* Search the dependency table for the index */
698  depRel = heap_open(DependRelationId, AccessShareLock);
699 
700  ScanKeyInit(&key[0],
701  Anum_pg_depend_classid,
702  BTEqualStrategyNumber, F_OIDEQ,
703  ObjectIdGetDatum(RelationRelationId));
704  ScanKeyInit(&key[1],
705  Anum_pg_depend_objid,
706  BTEqualStrategyNumber, F_OIDEQ,
707  ObjectIdGetDatum(indexId));
708  ScanKeyInit(&key[2],
709  Anum_pg_depend_objsubid,
710  BTEqualStrategyNumber, F_INT4EQ,
711  Int32GetDatum(0));
712 
713  scan = systable_beginscan(depRel, DependDependerIndexId, true,
714  NULL, 3, key);
715 
716  while (HeapTupleIsValid(tup = systable_getnext(scan)))
717  {
718  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
719 
720  /*
721  * We assume any internal dependency on a constraint must be what we
722  * are looking for.
723  */
724  if (deprec->refclassid == ConstraintRelationId &&
725  deprec->refobjsubid == 0 &&
726  deprec->deptype == DEPENDENCY_INTERNAL)
727  {
728  constraintId = deprec->refobjid;
729  break;
730  }
731  }
732 
733  systable_endscan(scan);
734  heap_close(depRel, AccessShareLock);
735 
736  return constraintId;
737 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define DependDependerIndexId
Definition: indexing.h:146
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
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:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:464
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getExtensionOfObject()

Oid getExtensionOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 447 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, DEPENDENCY_EXTENSION, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

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

448 {
449  Oid result = InvalidOid;
450  Relation depRel;
451  ScanKeyData key[2];
452  SysScanDesc scan;
453  HeapTuple tup;
454 
455  depRel = heap_open(DependRelationId, AccessShareLock);
456 
457  ScanKeyInit(&key[0],
458  Anum_pg_depend_classid,
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(classId));
461  ScanKeyInit(&key[1],
462  Anum_pg_depend_objid,
463  BTEqualStrategyNumber, F_OIDEQ,
464  ObjectIdGetDatum(objectId));
465 
466  scan = systable_beginscan(depRel, DependDependerIndexId, true,
467  NULL, 2, key);
468 
469  while (HeapTupleIsValid((tup = systable_getnext(scan))))
470  {
471  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
472 
473  if (depform->refclassid == ExtensionRelationId &&
474  depform->deptype == DEPENDENCY_EXTENSION)
475  {
476  result = depform->refobjid;
477  break; /* no need to keep scanning */
478  }
479  }
480 
481  systable_endscan(scan);
482 
483  heap_close(depRel, AccessShareLock);
484 
485  return result;
486 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define DependDependerIndexId
Definition: indexing.h:146
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
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:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#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
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ getOwnedSequence()

Oid getOwnedSequence ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 605 of file pg_depend.c.

References elog, ERROR, getOwnedSequences(), linitial_oid, and list_length().

Referenced by ATExecDropIdentity(), build_column_default(), transformAlterTableStmt(), and transformTableLikeClause().

606 {
607  List *seqlist = getOwnedSequences(relid, attnum);
608 
609  if (list_length(seqlist) > 1)
610  elog(ERROR, "more than one owned sequence found");
611  else if (list_length(seqlist) < 1)
612  elog(ERROR, "no owned sequence found");
613 
614  return linitial_oid(seqlist);
615 }
#define ERROR
Definition: elog.h:43
List * getOwnedSequences(Oid relid, AttrNumber attnum)
Definition: pg_depend.c:548
int16 attnum
Definition: pg_attribute.h:79
#define linitial_oid(l)
Definition: pg_list.h:113
static int list_length(const List *l)
Definition: pg_list.h:89
#define elog
Definition: elog.h:219
Definition: pg_list.h:45

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid,
AttrNumber  attnum 
)

Definition at line 548 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_AUTO, DEPENDENCY_INTERNAL, DependReferenceIndexId, get_rel_relkind(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, lappend_oid(), NIL, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ExecuteTruncateGuts(), getOwnedSequence(), and transformAlterTableStmt().

549 {
550  List *result = NIL;
551  Relation depRel;
552  ScanKeyData key[3];
553  SysScanDesc scan;
554  HeapTuple tup;
555 
556  depRel = heap_open(DependRelationId, AccessShareLock);
557 
558  ScanKeyInit(&key[0],
559  Anum_pg_depend_refclassid,
560  BTEqualStrategyNumber, F_OIDEQ,
561  ObjectIdGetDatum(RelationRelationId));
562  ScanKeyInit(&key[1],
563  Anum_pg_depend_refobjid,
564  BTEqualStrategyNumber, F_OIDEQ,
565  ObjectIdGetDatum(relid));
566  if (attnum)
567  ScanKeyInit(&key[2],
568  Anum_pg_depend_refobjsubid,
569  BTEqualStrategyNumber, F_INT4EQ,
571 
572  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
573  NULL, attnum ? 3 : 2, key);
574 
575  while (HeapTupleIsValid(tup = systable_getnext(scan)))
576  {
577  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
578 
579  /*
580  * We assume any auto or internal dependency of a sequence on a column
581  * must be what we are looking for. (We need the relkind test because
582  * indexes can also have auto dependencies on columns.)
583  */
584  if (deprec->classid == RelationRelationId &&
585  deprec->objsubid == 0 &&
586  deprec->refobjsubid != 0 &&
587  (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
588  get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
589  {
590  result = lappend_oid(result, deprec->objid);
591  }
592  }
593 
594  systable_endscan(scan);
595 
596  heap_close(depRel, AccessShareLock);
597 
598  return result;
599 }
#define NIL
Definition: pg_list.h:69
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
#define DependReferenceIndexId
Definition: indexing.h:148
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
int16 attnum
Definition: pg_attribute.h:79
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Int32GetDatum(X)
Definition: postgres.h:464
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Definition: pg_list.h:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ isObjectPinned()

static bool isObjectPinned ( const ObjectAddress object,
Relation  rel 
)
static

Definition at line 389 of file pg_depend.c.

References BTEqualStrategyNumber, ObjectAddress::classId, DEPENDENCY_PIN, DependReferenceIndexId, GETSTRUCT, HeapTupleIsValid, ObjectAddress::objectId, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by changeDependencyFor(), and recordMultipleDependencies().

390 {
391  bool ret = false;
392  SysScanDesc scan;
393  HeapTuple tup;
394  ScanKeyData key[2];
395 
396  ScanKeyInit(&key[0],
397  Anum_pg_depend_refclassid,
398  BTEqualStrategyNumber, F_OIDEQ,
399  ObjectIdGetDatum(object->classId));
400 
401  ScanKeyInit(&key[1],
402  Anum_pg_depend_refobjid,
403  BTEqualStrategyNumber, F_OIDEQ,
404  ObjectIdGetDatum(object->objectId));
405 
406  scan = systable_beginscan(rel, DependReferenceIndexId, true,
407  NULL, 2, key);
408 
409  /*
410  * Since we won't generate additional pg_depend entries for pinned
411  * objects, there can be at most one entry referencing a pinned object.
412  * Hence, it's sufficient to look at the first returned tuple; we don't
413  * need to loop.
414  */
415  tup = systable_getnext(scan);
416  if (HeapTupleIsValid(tup))
417  {
418  Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);
419 
420  if (foundDep->deptype == DEPENDENCY_PIN)
421  ret = true;
422  }
423 
424  systable_endscan(scan);
425 
426  return ret;
427 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define DependReferenceIndexId
Definition: indexing.h:148
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
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
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ recordDependencyOn()

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

Definition at line 44 of file pg_depend.c.

References recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), AddNewAttributeTuples(), AggregateCreate(), AlterForeignDataWrapper(), AlterPolicy(), ApplyExtensionUpdates(), ATAddForeignKeyConstraint(), ATExecAddOf(), CloneForeignKeyConstraints(), 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(), RemoveRoleFromObjectPolicy(), SetDefaultACL(), SetFunctionArgType(), SetFunctionReturnType(), StoreAttrDefault(), StoreCatalogInheritance1(), storeOperators(), StorePartitionKey(), storeProcedures(), and swap_relation_files().

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

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

Definition at line 139 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(), CreateUserMapping(), DefineOpClass(), GenerateTypeDependencies(), heap_create_with_catalog(), insert_event_trigger_tuple(), makeConfigurationDependencies(), makeDictionaryDependencies(), makeOperatorDependencies(), makeParserDependencies(), makeTSTemplateDependencies(), NamespaceCreate(), and ProcedureCreate().

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

◆ recordMultipleDependencies()

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

Definition at line 56 of file pg_depend.c.

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

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

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

◆ sequenceIsOwned()

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

Definition at line 500 of file pg_depend.c.

References AccessShareLock, BTEqualStrategyNumber, DependDependerIndexId, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

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

501 {
502  bool ret = false;
503  Relation depRel;
504  ScanKeyData key[2];
505  SysScanDesc scan;
506  HeapTuple tup;
507 
508  depRel = heap_open(DependRelationId, AccessShareLock);
509 
510  ScanKeyInit(&key[0],
511  Anum_pg_depend_classid,
512  BTEqualStrategyNumber, F_OIDEQ,
513  ObjectIdGetDatum(RelationRelationId));
514  ScanKeyInit(&key[1],
515  Anum_pg_depend_objid,
516  BTEqualStrategyNumber, F_OIDEQ,
517  ObjectIdGetDatum(seqId));
518 
519  scan = systable_beginscan(depRel, DependDependerIndexId, true,
520  NULL, 2, key);
521 
522  while (HeapTupleIsValid((tup = systable_getnext(scan))))
523  {
524  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
525 
526  if (depform->refclassid == RelationRelationId &&
527  depform->deptype == deptype)
528  {
529  *tableId = depform->refobjid;
530  *colId = depform->refobjsubid;
531  ret = true;
532  break; /* no need to keep scanning */
533  }
534  }
535 
536  systable_endscan(scan);
537 
538  heap_close(depRel, AccessShareLock);
539 
540  return ret;
541 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
#define DependDependerIndexId
Definition: indexing.h:146
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:492
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:71
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31