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 "catalog/partition.h"
#include "commands/extension.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/syscache.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)
 
void checkMembershipInCurrentExtension (const ObjectAddress *object)
 
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 (Relation rel, 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 566 of file pg_depend.c.

568 {
569  long count = 0;
570  Relation depRel;
571  ScanKeyData key[2];
572  SysScanDesc scan;
573  HeapTuple tup;
574 
575  depRel = table_open(DependRelationId, RowExclusiveLock);
576 
577  ScanKeyInit(&key[0],
578  Anum_pg_depend_classid,
579  BTEqualStrategyNumber, F_OIDEQ,
580  ObjectIdGetDatum(classId));
581  ScanKeyInit(&key[1],
582  Anum_pg_depend_objid,
583  BTEqualStrategyNumber, F_OIDEQ,
584  ObjectIdGetDatum(oldObjectId));
585 
586  scan = systable_beginscan(depRel, DependDependerIndexId, true,
587  NULL, 2, key);
588 
589  while (HeapTupleIsValid((tup = systable_getnext(scan))))
590  {
591  Form_pg_depend depform;
592 
593  /* make a modifiable copy */
594  tup = heap_copytuple(tup);
595  depform = (Form_pg_depend) GETSTRUCT(tup);
596 
597  depform->objid = newObjectId;
598 
599  CatalogTupleUpdate(depRel, &tup->t_self, tup);
600 
601  heap_freetuple(tup);
602 
603  count++;
604  }
605 
606  systable_endscan(scan);
607 
608  table_close(depRel, RowExclusiveLock);
609 
610  return count;
611 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
#define RowExclusiveLock
Definition: lockdefs.h:38
FormData_pg_depend * Form_pg_depend
Definition: pg_depend.h:72
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
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:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

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 622 of file pg_depend.c.

624 {
625  long count = 0;
626  Relation depRel;
627  ScanKeyData key[2];
628  SysScanDesc scan;
629  HeapTuple tup;
630  ObjectAddress objAddr;
631  bool newIsPinned;
632 
633  depRel = table_open(DependRelationId, RowExclusiveLock);
634 
635  /*
636  * If oldRefObjectId is pinned, there won't be any dependency entries on
637  * it --- we can't cope in that case. (This isn't really worth expending
638  * code to fix, in current usage; it just means you can't rename stuff out
639  * of pg_catalog, which would likely be a bad move anyway.)
640  */
641  objAddr.classId = refClassId;
642  objAddr.objectId = oldRefObjectId;
643  objAddr.objectSubId = 0;
644 
645  if (isObjectPinned(&objAddr))
646  ereport(ERROR,
647  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
648  errmsg("cannot remove dependency on %s because it is a system object",
649  getObjectDescription(&objAddr, false))));
650 
651  /*
652  * We can handle adding a dependency on something pinned, though, since
653  * that just means deleting the dependency entry.
654  */
655  objAddr.objectId = newRefObjectId;
656 
657  newIsPinned = isObjectPinned(&objAddr);
658 
659  /* Now search for dependency records */
660  ScanKeyInit(&key[0],
661  Anum_pg_depend_refclassid,
662  BTEqualStrategyNumber, F_OIDEQ,
663  ObjectIdGetDatum(refClassId));
664  ScanKeyInit(&key[1],
665  Anum_pg_depend_refobjid,
666  BTEqualStrategyNumber, F_OIDEQ,
667  ObjectIdGetDatum(oldRefObjectId));
668 
669  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
670  NULL, 2, key);
671 
672  while (HeapTupleIsValid((tup = systable_getnext(scan))))
673  {
674  if (newIsPinned)
675  CatalogTupleDelete(depRel, &tup->t_self);
676  else
677  {
678  Form_pg_depend depform;
679 
680  /* make a modifiable copy */
681  tup = heap_copytuple(tup);
682  depform = (Form_pg_depend) GETSTRUCT(tup);
683 
684  depform->refobjid = newRefObjectId;
685 
686  CatalogTupleUpdate(depRel, &tup->t_self, tup);
687 
688  heap_freetuple(tup);
689  }
690 
691  count++;
692  }
693 
694  systable_endscan(scan);
695 
696  table_close(depRel, RowExclusiveLock);
697 
698  return count;
699 }
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:365
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
static bool isObjectPinned(const ObjectAddress *object)
Definition: pg_depend.c:710

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 458 of file pg_depend.c.

461 {
462  long count = 0;
463  Relation depRel;
464  ScanKeyData key[2];
465  SysScanDesc scan;
466  HeapTuple tup;
467  ObjectAddress objAddr;
468  ObjectAddress depAddr;
469  bool oldIsPinned;
470  bool newIsPinned;
471 
472  /*
473  * Check to see if either oldRefObjectId or newRefObjectId is pinned.
474  * Pinned objects should not have any dependency entries pointing to them,
475  * so in these cases we should add or remove a pg_depend entry, or do
476  * nothing at all, rather than update an entry as in the normal case.
477  */
478  objAddr.classId = refClassId;
479  objAddr.objectId = oldRefObjectId;
480  objAddr.objectSubId = 0;
481 
482  oldIsPinned = isObjectPinned(&objAddr);
483 
484  objAddr.objectId = newRefObjectId;
485 
486  newIsPinned = isObjectPinned(&objAddr);
487 
488  if (oldIsPinned)
489  {
490  /*
491  * If both are pinned, we need do nothing. However, return 1 not 0,
492  * else callers will think this is an error case.
493  */
494  if (newIsPinned)
495  return 1;
496 
497  /*
498  * There is no old dependency record, but we should insert a new one.
499  * Assume a normal dependency is wanted.
500  */
501  depAddr.classId = classId;
502  depAddr.objectId = objectId;
503  depAddr.objectSubId = 0;
504  recordDependencyOn(&depAddr, &objAddr, DEPENDENCY_NORMAL);
505 
506  return 1;
507  }
508 
509  depRel = table_open(DependRelationId, RowExclusiveLock);
510 
511  /* There should be existing dependency record(s), so search. */
512  ScanKeyInit(&key[0],
513  Anum_pg_depend_classid,
514  BTEqualStrategyNumber, F_OIDEQ,
515  ObjectIdGetDatum(classId));
516  ScanKeyInit(&key[1],
517  Anum_pg_depend_objid,
518  BTEqualStrategyNumber, F_OIDEQ,
519  ObjectIdGetDatum(objectId));
520 
521  scan = systable_beginscan(depRel, DependDependerIndexId, true,
522  NULL, 2, key);
523 
524  while (HeapTupleIsValid((tup = systable_getnext(scan))))
525  {
526  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
527 
528  if (depform->refclassid == refClassId &&
529  depform->refobjid == oldRefObjectId)
530  {
531  if (newIsPinned)
532  CatalogTupleDelete(depRel, &tup->t_self);
533  else
534  {
535  /* make a modifiable copy */
536  tup = heap_copytuple(tup);
537  depform = (Form_pg_depend) GETSTRUCT(tup);
538 
539  depform->refobjid = newRefObjectId;
540 
541  CatalogTupleUpdate(depRel, &tup->t_self, tup);
542 
543  heap_freetuple(tup);
544  }
545 
546  count++;
547  }
548  }
549 
550  systable_endscan(scan);
551 
552  table_close(depRel, RowExclusiveLock);
553 
554  return count;
555 }
@ DEPENDENCY_NORMAL
Definition: dependency.h:33
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46

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(), AlterTypeNamespaceInternal(), ATExecSetAccessMethodNoStorage(), and swap_relation_files().

◆ checkMembershipInCurrentExtension()

void checkMembershipInCurrentExtension ( const ObjectAddress object)

Definition at line 259 of file pg_depend.c.

260 {
261  /*
262  * This is actually the same condition tested in
263  * recordDependencyOnCurrentExtension; but we want to issue a
264  * differently-worded error, and anyway it would be pretty confusing to
265  * call recordDependencyOnCurrentExtension in these circumstances.
266  */
267 
268  /* Only whole objects can be extension members */
269  Assert(object->objectSubId == 0);
270 
271  if (creating_extension)
272  {
273  Oid oldext;
274 
275  oldext = getExtensionOfObject(object->classId, object->objectId);
276  /* If already a member of this extension, OK */
277  if (oldext == CurrentExtensionObject)
278  return;
279  /* Else complain */
280  ereport(ERROR,
281  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
282  errmsg("%s is not a member of extension \"%s\"",
283  getObjectDescription(object, false),
285  errdetail("An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.")));
286  }
287 }
#define Assert(condition)
Definition: c.h:858
int errdetail(const char *fmt,...)
Definition: elog.c:1203
bool creating_extension
Definition: extension.c:71
Oid CurrentExtensionObject
Definition: extension.c:72
char * get_extension_name(Oid ext_oid)
Definition: extension.c:190
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition: pg_depend.c:733
unsigned int Oid
Definition: postgres_ext.h:31

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

Referenced by CollationCreate(), CreateForeignServer(), CreateSchemaCommand(), CreateTableAsRelExists(), DefineSequence(), and transformCreateStmt().

◆ deleteDependencyRecordsFor()

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

Definition at line 302 of file pg_depend.c.

304 {
305  long count = 0;
306  Relation depRel;
307  ScanKeyData key[2];
308  SysScanDesc scan;
309  HeapTuple tup;
310 
311  depRel = table_open(DependRelationId, RowExclusiveLock);
312 
313  ScanKeyInit(&key[0],
314  Anum_pg_depend_classid,
315  BTEqualStrategyNumber, F_OIDEQ,
316  ObjectIdGetDatum(classId));
317  ScanKeyInit(&key[1],
318  Anum_pg_depend_objid,
319  BTEqualStrategyNumber, F_OIDEQ,
320  ObjectIdGetDatum(objectId));
321 
322  scan = systable_beginscan(depRel, DependDependerIndexId, true,
323  NULL, 2, key);
324 
325  while (HeapTupleIsValid(tup = systable_getnext(scan)))
326  {
327  if (skipExtensionDeps &&
328  ((Form_pg_depend) GETSTRUCT(tup))->deptype == DEPENDENCY_EXTENSION)
329  continue;
330 
331  CatalogTupleDelete(depRel, &tup->t_self);
332  count++;
333  }
334 
335  systable_endscan(scan);
336 
337  table_close(depRel, RowExclusiveLock);
338 
339  return count;
340 }
@ 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(), ATExecSetExpression(), CreateProceduralLanguage(), CreateTransform(), CreateTriggerFiringOn(), GenerateTypeDependencies(), InsertRule(), makeConfigurationDependencies(), makeOperatorDependencies(), ProcedureCreate(), swap_relation_files(), and tryAttachPartitionForeignKey().

◆ deleteDependencyRecordsForClass()

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

Definition at line 352 of file pg_depend.c.

354 {
355  long count = 0;
356  Relation depRel;
357  ScanKeyData key[2];
358  SysScanDesc scan;
359  HeapTuple tup;
360 
361  depRel = table_open(DependRelationId, RowExclusiveLock);
362 
363  ScanKeyInit(&key[0],
364  Anum_pg_depend_classid,
365  BTEqualStrategyNumber, F_OIDEQ,
366  ObjectIdGetDatum(classId));
367  ScanKeyInit(&key[1],
368  Anum_pg_depend_objid,
369  BTEqualStrategyNumber, F_OIDEQ,
370  ObjectIdGetDatum(objectId));
371 
372  scan = systable_beginscan(depRel, DependDependerIndexId, true,
373  NULL, 2, key);
374 
375  while (HeapTupleIsValid(tup = systable_getnext(scan)))
376  {
377  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
378 
379  if (depform->refclassid == refclassId && depform->deptype == deptype)
380  {
381  CatalogTupleDelete(depRel, &tup->t_self);
382  count++;
383  }
384  }
385 
386  systable_endscan(scan);
387 
388  table_close(depRel, RowExclusiveLock);
389 
390  return count;
391 }

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(), ATExecSetAccessMethodNoStorage(), ConstraintSetParentConstraint(), DetachPartitionFinalize(), DropClonedTriggersFromPartition(), ExecAlterExtensionContentsRecurse(), 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 399 of file pg_depend.c.

401 {
402  long count = 0;
403  Relation depRel;
404  ScanKeyData key[2];
405  SysScanDesc scan;
406  HeapTuple tup;
407 
408  depRel = table_open(DependRelationId, RowExclusiveLock);
409 
410  ScanKeyInit(&key[0],
411  Anum_pg_depend_classid,
412  BTEqualStrategyNumber, F_OIDEQ,
413  ObjectIdGetDatum(classId));
414  ScanKeyInit(&key[1],
415  Anum_pg_depend_objid,
416  BTEqualStrategyNumber, F_OIDEQ,
417  ObjectIdGetDatum(objectId));
418 
419  scan = systable_beginscan(depRel, DependDependerIndexId, true,
420  NULL, 2, key);
421 
422  while (HeapTupleIsValid(tup = systable_getnext(scan)))
423  {
424  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
425 
426  if (depform->refclassid == refclassId &&
427  depform->refobjid == refobjectId &&
428  depform->deptype == deptype)
429  {
430  CatalogTupleDelete(depRel, &tup->t_self);
431  count++;
432  }
433  }
434 
435  systable_endscan(scan);
436 
437  table_close(depRel, RowExclusiveLock);
438 
439  return count;
440 }

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 989 of file pg_depend.c.

990 {
991  Oid constraintId = InvalidOid;
992  Relation depRel;
993  ScanKeyData key[3];
994  SysScanDesc scan;
995  HeapTuple tup;
996 
997  /* Search the dependency table for the index */
998  depRel = table_open(DependRelationId, AccessShareLock);
999 
1000  ScanKeyInit(&key[0],
1001  Anum_pg_depend_classid,
1002  BTEqualStrategyNumber, F_OIDEQ,
1003  ObjectIdGetDatum(RelationRelationId));
1004  ScanKeyInit(&key[1],
1005  Anum_pg_depend_objid,
1006  BTEqualStrategyNumber, F_OIDEQ,
1007  ObjectIdGetDatum(indexId));
1008  ScanKeyInit(&key[2],
1009  Anum_pg_depend_objsubid,
1010  BTEqualStrategyNumber, F_INT4EQ,
1011  Int32GetDatum(0));
1012 
1013  scan = systable_beginscan(depRel, DependDependerIndexId, true,
1014  NULL, 3, key);
1015 
1016  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1017  {
1018  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1019 
1020  /*
1021  * We assume any internal dependency on a constraint must be what we
1022  * are looking for.
1023  */
1024  if (deprec->refclassid == ConstraintRelationId &&
1025  deprec->refobjsubid == 0 &&
1026  deprec->deptype == DEPENDENCY_INTERNAL)
1027  {
1028  constraintId = deprec->refobjid;
1029  break;
1030  }
1031  }
1032 
1033  systable_endscan(scan);
1034  table_close(depRel, AccessShareLock);
1035 
1036  return constraintId;
1037 }
@ DEPENDENCY_INTERNAL
Definition: dependency.h:35
#define AccessShareLock
Definition: lockdefs.h:36
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:212
#define InvalidOid
Definition: postgres_ext.h:36

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 1045 of file pg_depend.c.

1046 {
1047  List *result = NIL;
1048  Relation depRel;
1049  ScanKeyData key[3];
1050  SysScanDesc scan;
1051  HeapTuple tup;
1052 
1053  /* Search the dependency table for the index */
1054  depRel = table_open(DependRelationId, AccessShareLock);
1055 
1056  ScanKeyInit(&key[0],
1057  Anum_pg_depend_refclassid,
1058  BTEqualStrategyNumber, F_OIDEQ,
1059  ObjectIdGetDatum(RelationRelationId));
1060  ScanKeyInit(&key[1],
1061  Anum_pg_depend_refobjid,
1062  BTEqualStrategyNumber, F_OIDEQ,
1063  ObjectIdGetDatum(indexId));
1064  ScanKeyInit(&key[2],
1065  Anum_pg_depend_refobjsubid,
1066  BTEqualStrategyNumber, F_INT4EQ,
1067  Int32GetDatum(0));
1068 
1069  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
1070  NULL, 3, key);
1071 
1072  while (HeapTupleIsValid(tup = systable_getnext(scan)))
1073  {
1074  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
1075 
1076  /*
1077  * We assume any normal dependency from a constraint must be what we
1078  * are looking for.
1079  */
1080  if (deprec->classid == ConstraintRelationId &&
1081  deprec->objsubid == 0 &&
1082  deprec->deptype == DEPENDENCY_NORMAL)
1083  {
1084  result = lappend_oid(result, deprec->objid);
1085  }
1086  }
1087 
1088  systable_endscan(scan);
1089  table_close(depRel, AccessShareLock);
1090 
1091  return result;
1092 }
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
#define NIL
Definition: pg_list.h:68
Definition: pg_list.h:54

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 779 of file pg_depend.c.

780 {
781  List *result = NIL;
782  Relation depRel;
783  ScanKeyData key[2];
784  SysScanDesc scan;
785  HeapTuple tup;
786 
787  depRel = table_open(DependRelationId, AccessShareLock);
788 
789  ScanKeyInit(&key[0],
790  Anum_pg_depend_classid,
791  BTEqualStrategyNumber, F_OIDEQ,
792  ObjectIdGetDatum(classId));
793  ScanKeyInit(&key[1],
794  Anum_pg_depend_objid,
795  BTEqualStrategyNumber, F_OIDEQ,
796  ObjectIdGetDatum(objectId));
797 
798  scan = systable_beginscan(depRel, DependDependerIndexId, true,
799  NULL, 2, key);
800 
801  while (HeapTupleIsValid((tup = systable_getnext(scan))))
802  {
803  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
804 
805  if (depform->refclassid == ExtensionRelationId &&
806  depform->deptype == DEPENDENCY_AUTO_EXTENSION)
807  result = lappend_oid(result, depform->refobjid);
808  }
809 
810  systable_endscan(scan);
811 
812  table_close(depRel, AccessShareLock);
813 
814  return result;
815 }
@ 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 733 of file pg_depend.c.

734 {
735  Oid result = InvalidOid;
736  Relation depRel;
737  ScanKeyData key[2];
738  SysScanDesc scan;
739  HeapTuple tup;
740 
741  depRel = table_open(DependRelationId, AccessShareLock);
742 
743  ScanKeyInit(&key[0],
744  Anum_pg_depend_classid,
745  BTEqualStrategyNumber, F_OIDEQ,
746  ObjectIdGetDatum(classId));
747  ScanKeyInit(&key[1],
748  Anum_pg_depend_objid,
749  BTEqualStrategyNumber, F_OIDEQ,
750  ObjectIdGetDatum(objectId));
751 
752  scan = systable_beginscan(depRel, DependDependerIndexId, true,
753  NULL, 2, key);
754 
755  while (HeapTupleIsValid((tup = systable_getnext(scan))))
756  {
757  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
758 
759  if (depform->refclassid == ExtensionRelationId &&
760  depform->deptype == DEPENDENCY_EXTENSION)
761  {
762  result = depform->refobjid;
763  break; /* no need to keep scanning */
764  }
765  }
766 
767  systable_endscan(scan);
768 
769  table_close(depRel, AccessShareLock);
770 
771  return result;
772 }

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(), checkMembershipInCurrentExtension(), ExecAlterExtensionContentsRecurse(), lookup_shippable(), pg_extension_config_dump(), and recordDependencyOnCurrentExtension().

◆ getIdentitySequence()

Oid getIdentitySequence ( Relation  rel,
AttrNumber  attnum,
bool  missing_ok 
)

Definition at line 946 of file pg_depend.c.

947 {
948  Oid relid = RelationGetRelid(rel);
949  List *seqlist;
950 
951  /*
952  * The identity sequence is associated with the topmost partitioned table,
953  * which might have column order different than the given partition.
954  */
955  if (RelationGetForm(rel)->relispartition)
956  {
957  List *ancestors = get_partition_ancestors(relid);
958  const char *attname = get_attname(relid, attnum, false);
959 
960  relid = llast_oid(ancestors);
961  attnum = get_attnum(relid, attname);
962  if (attnum == InvalidAttrNumber)
963  elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
964  attname, relid);
965  list_free(ancestors);
966  }
967 
969  if (list_length(seqlist) > 1)
970  elog(ERROR, "more than one owned sequence found");
971  else if (seqlist == NIL)
972  {
973  if (missing_ok)
974  return InvalidOid;
975  else
976  elog(ERROR, "no owned sequence found");
977  }
978 
979  return linitial_oid(seqlist);
980 }
#define InvalidAttrNumber
Definition: attnum.h:23
#define elog(elevel,...)
Definition: elog.h:224
void list_free(List *list)
Definition: list.c:1546
AttrNumber get_attnum(Oid relid, const char *attname)
Definition: lsyscache.c:858
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition: lsyscache.c:827
List * get_partition_ancestors(Oid relid)
Definition: partition.c:134
NameData attname
Definition: pg_attribute.h:41
int16 attnum
Definition: pg_attribute.h:74
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition: pg_depend.c:878
static int list_length(const List *l)
Definition: pg_list.h:152
#define llast_oid(l)
Definition: pg_list.h:200
#define linitial_oid(l)
Definition: pg_list.h:180
#define RelationGetForm(relation)
Definition: rel.h:499
#define RelationGetRelid(relation)
Definition: rel.h:505

References attname, attnum, DEPENDENCY_INTERNAL, elog, ERROR, get_attname(), get_attnum(), get_partition_ancestors(), getOwnedSequences_internal(), InvalidAttrNumber, InvalidOid, linitial_oid, list_free(), list_length(), llast_oid, NIL, RelationGetForm, and RelationGetRelid.

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

◆ getOwnedSequences()

List* getOwnedSequences ( Oid  relid)

Definition at line 937 of file pg_depend.c.

938 {
939  return getOwnedSequences_internal(relid, 0, 0);
940 }

References getOwnedSequences_internal().

Referenced by ATRewriteTables(), and ExecuteTruncateGuts().

◆ getOwnedSequences_internal()

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

Definition at line 878 of file pg_depend.c.

879 {
880  List *result = NIL;
881  Relation depRel;
882  ScanKeyData key[3];
883  SysScanDesc scan;
884  HeapTuple tup;
885 
886  depRel = table_open(DependRelationId, AccessShareLock);
887 
888  ScanKeyInit(&key[0],
889  Anum_pg_depend_refclassid,
890  BTEqualStrategyNumber, F_OIDEQ,
891  ObjectIdGetDatum(RelationRelationId));
892  ScanKeyInit(&key[1],
893  Anum_pg_depend_refobjid,
894  BTEqualStrategyNumber, F_OIDEQ,
895  ObjectIdGetDatum(relid));
896  if (attnum)
897  ScanKeyInit(&key[2],
898  Anum_pg_depend_refobjsubid,
899  BTEqualStrategyNumber, F_INT4EQ,
901 
902  scan = systable_beginscan(depRel, DependReferenceIndexId, true,
903  NULL, attnum ? 3 : 2, key);
904 
905  while (HeapTupleIsValid(tup = systable_getnext(scan)))
906  {
907  Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
908 
909  /*
910  * We assume any auto or internal dependency of a sequence on a column
911  * must be what we are looking for. (We need the relkind test because
912  * indexes can also have auto dependencies on columns.)
913  */
914  if (deprec->classid == RelationRelationId &&
915  deprec->objsubid == 0 &&
916  deprec->refobjsubid != 0 &&
917  (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
918  get_rel_relkind(deprec->objid) == RELKIND_SEQUENCE)
919  {
920  if (!deptype || deprec->deptype == deptype)
921  result = lappend_oid(result, deprec->objid);
922  }
923  }
924 
925  systable_endscan(scan);
926 
927  table_close(depRel, AccessShareLock);
928 
929  return result;
930 }
@ DEPENDENCY_AUTO
Definition: dependency.h:34
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:2003

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 710 of file pg_depend.c.

711 {
712  return IsPinnedObject(object->classId, object->objectId);
713 }
bool IsPinnedObject(Oid classId, Oid objectId)
Definition: catalog.c:334

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 46 of file pg_depend.c.

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

References recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), addFkRecurseReferenced(), addFkRecurseReferencing(), AddNewAttributeTuples(), AlterForeignDataWrapper(), AlterFunction(), AlterPolicy(), ApplyExtensionUpdates(), ATExecAddOf(), ATExecSetAccessMethodNoStorage(), changeDependencyFor(), CloneFkReferencing(), CollationCreate(), ConstraintSetParentConstraint(), ConversionCreate(), create_toast_table(), CreateAccessMethod(), CreateForeignDataWrapper(), CreateForeignServer(), CreateForeignTable(), CreateOpFamily(), CreatePolicy(), CreateStatistics(), CreateTriggerFiringOn(), CreateUserMapping(), DefineOpClass(), ExecAlterExtensionContentsRecurse(), 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 194 of file pg_depend.c.

196 {
197  /* Only whole objects can be extension members */
198  Assert(object->objectSubId == 0);
199 
200  if (creating_extension)
201  {
202  ObjectAddress extension;
203 
204  /* Only need to check for existing membership if isReplace */
205  if (isReplace)
206  {
207  Oid oldext;
208 
209  /*
210  * Side note: these catalog lookups are safe only because the
211  * object is a pre-existing one. In the not-isReplace case, the
212  * caller has most likely not yet done a CommandCounterIncrement
213  * that would make the new object visible.
214  */
215  oldext = getExtensionOfObject(object->classId, object->objectId);
216  if (OidIsValid(oldext))
217  {
218  /* If already a member of this extension, nothing to do */
219  if (oldext == CurrentExtensionObject)
220  return;
221  /* Already a member of some other extension, so reject */
222  ereport(ERROR,
223  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
224  errmsg("%s is already a member of extension \"%s\"",
225  getObjectDescription(object, false),
226  get_extension_name(oldext))));
227  }
228  /* It's a free-standing object, so reject */
229  ereport(ERROR,
230  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
231  errmsg("%s is not a member of extension \"%s\"",
232  getObjectDescription(object, false),
234  errdetail("An extension is not allowed to replace an object that it does not own.")));
235  }
236 
237  /* OK, record it as a member of CurrentExtensionObject */
238  extension.classId = ExtensionRelationId;
239  extension.objectId = CurrentExtensionObject;
240  extension.objectSubId = 0;
241 
242  recordDependencyOn(object, &extension, DEPENDENCY_EXTENSION);
243  }
244 }
#define OidIsValid(objectId)
Definition: c.h:775

References Assert, ObjectAddress::classId, creating_extension, CurrentExtensionObject, DEPENDENCY_EXTENSION, ereport, errcode(), errdetail(), 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(), DefineVirtualRelation(), 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 58 of file pg_depend.c.

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

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 829 of file pg_depend.c.

830 {
831  bool ret = false;
832  Relation depRel;
833  ScanKeyData key[2];
834  SysScanDesc scan;
835  HeapTuple tup;
836 
837  depRel = table_open(DependRelationId, AccessShareLock);
838 
839  ScanKeyInit(&key[0],
840  Anum_pg_depend_classid,
841  BTEqualStrategyNumber, F_OIDEQ,
842  ObjectIdGetDatum(RelationRelationId));
843  ScanKeyInit(&key[1],
844  Anum_pg_depend_objid,
845  BTEqualStrategyNumber, F_OIDEQ,
846  ObjectIdGetDatum(seqId));
847 
848  scan = systable_beginscan(depRel, DependDependerIndexId, true,
849  NULL, 2, key);
850 
851  while (HeapTupleIsValid((tup = systable_getnext(scan))))
852  {
853  Form_pg_depend depform = (Form_pg_depend) GETSTRUCT(tup);
854 
855  if (depform->refclassid == RelationRelationId &&
856  depform->deptype == deptype)
857  {
858  *tableId = depform->refobjid;
859  *colId = depform->refobjsubid;
860  ret = true;
861  break; /* no need to keep scanning */
862  }
863  }
864 
865  systable_endscan(scan);
866 
867  table_close(depRel, AccessShareLock);
868 
869  return ret;
870 }

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().