PostgreSQL Source Code  git master
pg_depend.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/table.h"
#include "catalog/catalog.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 dependency graph for pg_depend.c:

Go to the source code of this file.

Functions

static bool isObjectPinned (const ObjectAddress *object)
 
void recordDependencyOn (const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
 
void recordMultipleDependencies (const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
 
void recordDependencyOnCurrentExtension (const ObjectAddress *object, bool isReplace)
 
long deleteDependencyRecordsFor (Oid classId, Oid objectId, bool skipExtensionDeps)
 
long deleteDependencyRecordsForClass (Oid classId, Oid objectId, Oid refclassId, char deptype)
 
long deleteDependencyRecordsForSpecific (Oid classId, Oid objectId, char deptype, Oid refclassId, Oid refobjectId)
 
long changeDependencyFor (Oid classId, Oid objectId, Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
long changeDependenciesOf (Oid classId, Oid oldObjectId, Oid newObjectId)
 
long changeDependenciesOn (Oid refClassId, Oid oldRefObjectId, Oid newRefObjectId)
 
Oid getExtensionOfObject (Oid classId, Oid objectId)
 
ListgetAutoExtensionsOfObject (Oid classId, Oid objectId)
 
bool sequenceIsOwned (Oid seqId, char deptype, Oid *tableId, int32 *colId)
 
static ListgetOwnedSequences_internal (Oid relid, AttrNumber attnum, char deptype)
 
ListgetOwnedSequences (Oid relid)
 
Oid getIdentitySequence (Oid relid, AttrNumber attnum, bool missing_ok)
 
Oid get_index_constraint (Oid indexId)
 
Listget_index_ref_constraints (Oid indexId)
 

Function Documentation

◆ changeDependenciesOf()

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

Definition at line 507 of file pg_depend.c.

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

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

Referenced by index_concurrently_swap().

◆ changeDependenciesOn()

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

Definition at line 563 of file pg_depend.c.

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

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

Referenced by index_concurrently_swap().

◆ changeDependencyFor()

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

Definition at line 399 of file pg_depend.c.

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

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

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

◆ deleteDependencyRecordsFor()

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

Definition at line 243 of file pg_depend.c.

245 {
246  long count = 0;
247  Relation depRel;
248  ScanKeyData key[2];
249  SysScanDesc scan;
250  HeapTuple tup;
251 
252  depRel = table_open(DependRelationId, RowExclusiveLock);
253 
254  ScanKeyInit(&key[0],
255  Anum_pg_depend_classid,
256  BTEqualStrategyNumber, F_OIDEQ,
257  ObjectIdGetDatum(classId));
258  ScanKeyInit(&key[1],
259  Anum_pg_depend_objid,
260  BTEqualStrategyNumber, F_OIDEQ,
261  ObjectIdGetDatum(objectId));
262 
263  scan = systable_beginscan(depRel, DependDependerIndexId, true,
264  NULL, 2, key);
265 
266  while (HeapTupleIsValid(tup = systable_getnext(scan)))
267  {
268  if (skipExtensionDeps &&
269  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
270  continue;
271 
272  CatalogTupleDelete(depRel, &tup->t_self);
273  count++;
274  }
275 
276  systable_endscan(scan);
277 
278  table_close(depRel, RowExclusiveLock);
279 
280  return count;
281 }
@ DEPENDENCY_EXTENSION
Definition: dependency.h:38

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

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

◆ deleteDependencyRecordsForClass()

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

Definition at line 293 of file pg_depend.c.

295 {
296  long count = 0;
297  Relation depRel;
298  ScanKeyData key[2];
299  SysScanDesc scan;
300  HeapTuple tup;
301 
302  depRel = table_open(DependRelationId, RowExclusiveLock);
303 
304  ScanKeyInit(&key[0],
305  Anum_pg_depend_classid,
306  BTEqualStrategyNumber, F_OIDEQ,
307  ObjectIdGetDatum(classId));
308  ScanKeyInit(&key[1],
309  Anum_pg_depend_objid,
310  BTEqualStrategyNumber, F_OIDEQ,
311  ObjectIdGetDatum(objectId));
312 
313  scan = systable_beginscan(depRel, DependDependerIndexId, true,
314  NULL, 2, key);
315 
316  while (HeapTupleIsValid(tup = systable_getnext(scan)))
317  {
318  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
319 
320  if (depform->refclassid == refclassId && depform->deptype == deptype)
321  {
322  CatalogTupleDelete(depRel, &tup->t_self);
323  count++;
324  }
325  }
326 
327  systable_endscan(scan);
328 
329  table_close(depRel, RowExclusiveLock);
330 
331  return count;
332 }

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

Referenced by AlterForeignDataWrapper(), ApplyExtensionUpdates(), ATExecDropIdentity(), ConstraintSetParentConstraint(), DetachPartitionFinalize(), DropClonedTriggersFromPartition(), ExecAlterExtensionContentsStmt(), index_constraint_create(), IndexSetParentIndex(), process_owned_by(), and TriggerSetParentTrigger().

◆ deleteDependencyRecordsForSpecific()

long deleteDependencyRecordsForSpecific ( Oid  classId,
Oid  objectId,
char  deptype,
Oid  refclassId,
Oid  refobjectId 
)

Definition at line 340 of file pg_depend.c.

342 {
343  long count = 0;
344  Relation depRel;
345  ScanKeyData key[2];
346  SysScanDesc scan;
347  HeapTuple tup;
348 
349  depRel = table_open(DependRelationId, RowExclusiveLock);
350 
351  ScanKeyInit(&key[0],
352  Anum_pg_depend_classid,
353  BTEqualStrategyNumber, F_OIDEQ,
354  ObjectIdGetDatum(classId));
355  ScanKeyInit(&key[1],
356  Anum_pg_depend_objid,
357  BTEqualStrategyNumber, F_OIDEQ,
358  ObjectIdGetDatum(objectId));
359 
360  scan = systable_beginscan(depRel, DependDependerIndexId, true,
361  NULL, 2, key);
362 
363  while (HeapTupleIsValid(tup = systable_getnext(scan)))
364  {
365  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
366 
367  if (depform->refclassid == refclassId &&
368  depform->refobjid == refobjectId &&
369  depform->deptype == deptype)
370  {
371  CatalogTupleDelete(depRel, &tup->t_self);
372  count++;
373  }
374  }
375 
376  systable_endscan(scan);
377 
378  table_close(depRel, RowExclusiveLock);
379 
380  return count;
381 }

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

Referenced by ExecAlterObjectDependsStmt().

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 911 of file pg_depend.c.

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

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

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

◆ get_index_ref_constraints()

List* get_index_ref_constraints ( Oid  indexId)

Definition at line 967 of file pg_depend.c.

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

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

Referenced by index_concurrently_swap().

◆ getAutoExtensionsOfObject()

List* getAutoExtensionsOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 720 of file pg_depend.c.

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

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

Referenced by ExecAlterObjectDependsStmt().

◆ getExtensionOfObject()

Oid getExtensionOfObject ( Oid  classId,
Oid  objectId 
)

Definition at line 674 of file pg_depend.c.

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

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

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

◆ getIdentitySequence()

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

Definition at line 887 of file pg_depend.c.

888 {
890 
891  if (list_length(seqlist) > 1)
892  elog(ERROR, "more than one owned sequence found");
893  else if (list_length(seqlist) < 1)
894  {
895  if (missing_ok)
896  return InvalidOid;
897  else
898  elog(ERROR, "no owned sequence found");
899  }
900 
901  return linitial_oid(seqlist);
902 }
#define elog(elevel,...)
Definition: elog.h:218
int16 attnum
Definition: pg_attribute.h:83
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:819
static int list_length(const List *l)
Definition: pg_list.h:149
#define linitial_oid(l)
Definition: pg_list.h:176

References attnum, DEPENDENCY_INTERNAL, elog, ERROR, getOwnedSequences_internal(), InvalidOid, linitial_oid, and list_length().

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

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 878 of file pg_depend.c.

879 {
880  return getOwnedSequences_internal(relid, 0, 0);
881 }

References getOwnedSequences_internal().

Referenced by ATRewriteTables(), and ExecuteTruncateGuts().

◆ getOwnedSequences_internal()

static List* getOwnedSequences_internal ( Oid  relid,
AttrNumber  attnum,
char  deptype 
)
static

Definition at line 819 of file pg_depend.c.

820 {
821  List *result = NIL;
822  Relation depRel;
823  ScanKeyData key[3];
824  SysScanDesc scan;
825  HeapTuple tup;
826 
827  depRel = table_open(DependRelationId, AccessShareLock);
828 
829  ScanKeyInit(&key[0],
830  Anum_pg_depend_refclassid,
831  BTEqualStrategyNumber, F_OIDEQ,
832  ObjectIdGetDatum(RelationRelationId));
833  ScanKeyInit(&key[1],
834  Anum_pg_depend_refobjid,
835  BTEqualStrategyNumber, F_OIDEQ,
836  ObjectIdGetDatum(relid));
837  if (attnum)
838  ScanKeyInit(&key[2],
839  Anum_pg_depend_refobjsubid,
840  BTEqualStrategyNumber, F_INT4EQ,
842 
843  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
844  NULL, attnum ? 3 : 2, key);
845 
846  while (HeapTupleIsValid(tup = systable_getnext(scan)))
847  {
848  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
849 
850  /*
851  * We assume any auto or internal dependency of a sequence on a column
852  * must be what we are looking for. (We need the relkind test because
853  * indexes can also have auto dependencies on columns.)
854  */
855  if (deprec->classid == RelationRelationId &&
856  deprec->objsubid == 0 &&
857  deprec->refobjsubid != 0 &&
858  (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
859  get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
860  {
861  if (!deptype || deprec->deptype == deptype)
862  result = lappend_oid(result, deprec->objid);
863  }
864  }
865 
866  systable_endscan(scan);
867 
868  table_close(depRel, AccessShareLock);
869 
870  return result;
871 }
@ DEPENDENCY_AUTO
Definition: dependency.h:34
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1984

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

Referenced by getIdentitySequence(), and getOwnedSequences().

◆ isObjectPinned()

static bool isObjectPinned ( const ObjectAddress object)
static

Definition at line 651 of file pg_depend.c.

652 {
653  return IsPinnedObject(object->classId, object->objectId);
654 }
bool IsPinnedObject(Oid classId, Oid objectId)
Definition: catalog.c:313

References ObjectAddress::classId, IsPinnedObject(), and ObjectAddress::objectId.

Referenced by changeDependenciesOn(), changeDependencyFor(), and recordMultipleDependencies().

◆ recordDependencyOn()

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

Definition at line 44 of file pg_depend.c.

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

References recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), addFkRecurseReferenced(), addFkRecurseReferencing(), AddNewAttributeTuples(), AlterForeignDataWrapper(), AlterFunction(), AlterPolicy(), ApplyExtensionUpdates(), ATExecAddOf(), changeDependencyFor(), CloneFkReferencing(), CollationCreate(), ConstraintSetParentConstraint(), ConversionCreate(), create_toast_table(), CreateAccessMethod(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreateStatistics(), CreateTriggerFiringOn(), CreateUserMapping(), DefineOpClass(), ExecAlterExtensionContentsStmt(), ExecAlterObjectDependsStmt(), GenerateTypeDependencies(), index_constraint_create(), index_create(), IndexSetParentIndex(), insert_event_trigger_tuple(), InsertRule(), makeMultirangeConstructors(), makeRangeConstructors(), process_owned_by(), publication_add_relation(), publication_add_schema(), RangeCreate(), recordDependencyOnCurrentExtension(), recordDependencyOnSingleRelExpr(), SetDefaultACL(), StoreAttrDefault(), StoreCatalogInheritance1(), storeOperators(), StorePartitionKey(), storeProcedures(), swap_relation_files(), and TriggerSetParentTrigger().

◆ recordDependencyOnCurrentExtension()

void recordDependencyOnCurrentExtension ( const ObjectAddress object,
bool  isReplace 
)

Definition at line 191 of file pg_depend.c.

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

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

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

◆ recordMultipleDependencies()

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

Definition at line 56 of file pg_depend.c.

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

References CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTuplesMultiInsertWithInfo(), CharGetDatum, ObjectAddress::classId, ExecClearTuple(), ExecDropSingleTupleTableSlot(), ExecStoreVirtualTuple(), FormData_pg_depend, i, Int32GetDatum, IsBootstrapProcessingMode, isObjectPinned(), MakeSingleTupleTableSlot(), MAX_CATALOG_MULTI_INSERT_BYTES, Min, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, palloc(), pfree(), RelationGetDescr, RowExclusiveLock, table_close(), table_open(), TupleTableSlot::tts_values, and TTSOpsHeapTuple.

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

◆ sequenceIsOwned()

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

Definition at line 770 of file pg_depend.c.

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

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

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