PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/pg_type.h"
#include "catalog/partition.h"
#include "commands/extension.h"
#include "miscadmin.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.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)
 
Oid getExtensionType (Oid extensionOid, const char *typname)
 
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 567 of file pg_depend.c.

569{
570 long count = 0;
572 ScanKeyData key[2];
573 SysScanDesc scan;
575
577
578 ScanKeyInit(&key[0],
581 ObjectIdGetDatum(classId));
582 ScanKeyInit(&key[1],
586
588 NULL, 2, key);
589
590 while (HeapTupleIsValid((tup = systable_getnext(scan))))
591 {
593
594 /* make a modifiable copy */
597
598 depform->objid = newObjectId;
599
600 CatalogTupleUpdate(depRel, &tup->t_self, tup);
601
603
604 count++;
605 }
606
607 systable_endscan(scan);
608
610
611 return count;
612}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:778
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *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:262
static int fb(int x)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
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(), fb(), GETSTRUCT(), heap_copytuple(), heap_freetuple(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by index_concurrently_swap().

◆ changeDependenciesOn()

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

Definition at line 623 of file pg_depend.c.

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

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ereport, errcode(), errmsg(), ERROR, fb(), getObjectDescription(), GETSTRUCT(), heap_copytuple(), heap_freetuple(), HeapTupleIsValid, isObjectPinned(), ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), 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 459 of file pg_depend.c.

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

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleUpdate(), ObjectAddress::classId, DEPENDENCY_NORMAL, fb(), GETSTRUCT(), heap_copytuple(), heap_freetuple(), HeapTupleIsValid, isObjectPinned(), ObjectIdGetDatum(), recordDependencyOn(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), 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 260 of file pg_depend.c.

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

References Assert, ObjectAddress::classId, creating_extension, CurrentExtensionObject, ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), 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 303 of file pg_depend.c.

305{
306 long count = 0;
308 ScanKeyData key[2];
309 SysScanDesc scan;
311
313
314 ScanKeyInit(&key[0],
317 ObjectIdGetDatum(classId));
318 ScanKeyInit(&key[1],
321 ObjectIdGetDatum(objectId));
322
324 NULL, 2, key);
325
326 while (HeapTupleIsValid(tup = systable_getnext(scan)))
327 {
328 if (skipExtensionDeps &&
330 continue;
331
332 CatalogTupleDelete(depRel, &tup->t_self);
333 count++;
334 }
335
336 systable_endscan(scan);
337
339
340 return count;
341}
@ DEPENDENCY_EXTENSION
Definition dependency.h:38

References BTEqualStrategyNumber, CatalogTupleDelete(), DEPENDENCY_EXTENSION, fb(), GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

◆ deleteDependencyRecordsForClass()

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

Definition at line 353 of file pg_depend.c.

355{
356 long count = 0;
358 ScanKeyData key[2];
359 SysScanDesc scan;
361
363
364 ScanKeyInit(&key[0],
367 ObjectIdGetDatum(classId));
368 ScanKeyInit(&key[1],
371 ObjectIdGetDatum(objectId));
372
374 NULL, 2, key);
375
376 while (HeapTupleIsValid(tup = systable_getnext(scan)))
377 {
379
380 if (depform->refclassid == refclassId && depform->deptype == deptype)
381 {
382 CatalogTupleDelete(depRel, &tup->t_self);
383 count++;
384 }
385 }
386
387 systable_endscan(scan);
388
390
391 return count;
392}

References BTEqualStrategyNumber, CatalogTupleDelete(), fb(), GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), 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 400 of file pg_depend.c.

402{
403 long count = 0;
405 ScanKeyData key[2];
406 SysScanDesc scan;
408
410
411 ScanKeyInit(&key[0],
414 ObjectIdGetDatum(classId));
415 ScanKeyInit(&key[1],
418 ObjectIdGetDatum(objectId));
419
421 NULL, 2, key);
422
423 while (HeapTupleIsValid(tup = systable_getnext(scan)))
424 {
426
427 if (depform->refclassid == refclassId &&
428 depform->refobjid == refobjectId &&
429 depform->deptype == deptype)
430 {
431 CatalogTupleDelete(depRel, &tup->t_self);
432 count++;
433 }
434 }
435
436 systable_endscan(scan);
437
439
440 return count;
441}

References BTEqualStrategyNumber, CatalogTupleDelete(), fb(), GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ExecAlterObjectDependsStmt(), and RemoveInheritedConstraint().

◆ get_index_constraint()

Oid get_index_constraint ( Oid  indexId)

Definition at line 1061 of file pg_depend.c.

1062{
1065 ScanKeyData key[3];
1066 SysScanDesc scan;
1067 HeapTuple tup;
1068
1069 /* Search the dependency table for the index */
1071
1072 ScanKeyInit(&key[0],
1076 ScanKeyInit(&key[1],
1080 ScanKeyInit(&key[2],
1083 Int32GetDatum(0));
1084
1086 NULL, 3, key);
1087
1088 while (HeapTupleIsValid(tup = systable_getnext(scan)))
1089 {
1091
1092 /*
1093 * We assume any internal dependency on a constraint must be what we
1094 * are looking for.
1095 */
1096 if (deprec->refclassid == ConstraintRelationId &&
1097 deprec->refobjsubid == 0 &&
1098 deprec->deptype == DEPENDENCY_INTERNAL)
1099 {
1100 constraintId = deprec->refobjid;
1101 break;
1102 }
1103 }
1104
1105 systable_endscan(scan);
1107
1108 return constraintId;
1109}
@ DEPENDENCY_INTERNAL
Definition dependency.h:35
#define AccessShareLock
Definition lockdefs.h:36
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define InvalidOid

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_INTERNAL, fb(), GETSTRUCT(), HeapTupleIsValid, Int32GetDatum(), InvalidOid, 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 1117 of file pg_depend.c.

1118{
1119 List *result = NIL;
1121 ScanKeyData key[3];
1122 SysScanDesc scan;
1123 HeapTuple tup;
1124
1125 /* Search the dependency table for the index */
1127
1128 ScanKeyInit(&key[0],
1132 ScanKeyInit(&key[1],
1136 ScanKeyInit(&key[2],
1139 Int32GetDatum(0));
1140
1142 NULL, 3, key);
1143
1144 while (HeapTupleIsValid(tup = systable_getnext(scan)))
1145 {
1147
1148 /*
1149 * We assume any normal dependency from a constraint must be what we
1150 * are looking for.
1151 */
1152 if (deprec->classid == ConstraintRelationId &&
1153 deprec->objsubid == 0 &&
1154 deprec->deptype == DEPENDENCY_NORMAL)
1155 {
1156 result = lappend_oid(result, deprec->objid);
1157 }
1158 }
1159
1160 systable_endscan(scan);
1162
1163 return result;
1164}
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, fb(), GETSTRUCT(), HeapTupleIsValid, Int32GetDatum(), 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 
)

◆ getExtensionOfObject()

Oid getExtensionOfObject ( Oid  classId,
Oid  objectId 
)

◆ getExtensionType()

Oid getExtensionType ( Oid  extensionOid,
const char typname 
)

Definition at line 832 of file pg_depend.c.

833{
834 Oid result = InvalidOid;
836 ScanKeyData key[3];
837 SysScanDesc scan;
839
841
842 ScanKeyInit(&key[0],
846 ScanKeyInit(&key[1],
850 ScanKeyInit(&key[2],
853 Int32GetDatum(0));
854
856 NULL, 3, key);
857
858 while (HeapTupleIsValid(tup = systable_getnext(scan)))
859 {
861
862 if (depform->classid == TypeRelationId &&
863 depform->deptype == DEPENDENCY_EXTENSION)
864 {
865 Oid typoid = depform->objid;
867
870 continue; /* should we throw an error? */
872 typname) == 0)
873 {
874 result = typoid;
876 break; /* no need to keep searching */
877 }
879 }
880 }
881
882 systable_endscan(scan);
883
885
886 return result;
887}
#define NameStr(name)
Definition c.h:765
FormData_pg_type * Form_pg_type
Definition pg_type.h:261
NameData typname
Definition pg_type.h:41
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220

References AccessShareLock, BTEqualStrategyNumber, DEPENDENCY_EXTENSION, fb(), GETSTRUCT(), HeapTupleIsValid, Int32GetDatum(), InvalidOid, NameStr, ObjectIdGetDatum(), ReleaseSysCache(), ScanKeyInit(), SearchSysCache1(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and typname.

Referenced by get_function_sibling_type().

◆ getIdentitySequence()

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

Definition at line 1018 of file pg_depend.c.

1019{
1020 Oid relid = RelationGetRelid(rel);
1021 List *seqlist;
1022
1023 /*
1024 * The identity sequence is associated with the topmost partitioned table,
1025 * which might have column order different than the given partition.
1026 */
1028 {
1029 List *ancestors = get_partition_ancestors(relid);
1030 const char *attname = get_attname(relid, attnum, false);
1031
1032 relid = llast_oid(ancestors);
1033 attnum = get_attnum(relid, attname);
1035 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
1036 attname, relid);
1037 list_free(ancestors);
1038 }
1039
1041 if (list_length(seqlist) > 1)
1042 elog(ERROR, "more than one owned sequence found");
1043 else if (seqlist == NIL)
1044 {
1045 if (missing_ok)
1046 return InvalidOid;
1047 else
1048 elog(ERROR, "no owned sequence found");
1049 }
1050
1051 return linitial_oid(seqlist);
1052}
#define InvalidAttrNumber
Definition attnum.h:23
#define elog(elevel,...)
Definition elog.h:226
void list_free(List *list)
Definition list.c:1546
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:934
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:903
List * get_partition_ancestors(Oid relid)
Definition partition.c:134
NameData attname
int16 attnum
static List * getOwnedSequences_internal(Oid relid, AttrNumber attnum, char deptype)
Definition pg_depend.c:950
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:508
#define RelationGetRelid(relation)
Definition rel.h:514

References attname, attnum, DEPENDENCY_INTERNAL, elog, ERROR, fb(), 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 1009 of file pg_depend.c.

1010{
1011 return getOwnedSequences_internal(relid, 0, 0);
1012}

References getOwnedSequences_internal().

Referenced by ATRewriteTables(), and ExecuteTruncateGuts().

◆ getOwnedSequences_internal()

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

Definition at line 950 of file pg_depend.c.

951{
952 List *result = NIL;
954 ScanKeyData key[3];
955 SysScanDesc scan;
957
959
960 ScanKeyInit(&key[0],
964 ScanKeyInit(&key[1],
967 ObjectIdGetDatum(relid));
968 if (attnum)
969 ScanKeyInit(&key[2],
973
975 NULL, attnum ? 3 : 2, key);
976
977 while (HeapTupleIsValid(tup = systable_getnext(scan)))
978 {
980
981 /*
982 * We assume any auto or internal dependency of a sequence on a column
983 * must be what we are looking for. (We need the relkind test because
984 * indexes can also have auto dependencies on columns.)
985 */
986 if (deprec->classid == RelationRelationId &&
987 deprec->objsubid == 0 &&
988 deprec->refobjsubid != 0 &&
989 (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
991 {
992 if (!deptype || deprec->deptype == deptype)
993 result = lappend_oid(result, deprec->objid);
994 }
995 }
996
997 systable_endscan(scan);
998
1000
1001 return result;
1002}
@ DEPENDENCY_AUTO
Definition dependency.h:34
char get_rel_relkind(Oid relid)
Definition lsyscache.c:2153

References AccessShareLock, attnum, BTEqualStrategyNumber, DEPENDENCY_AUTO, DEPENDENCY_INTERNAL, fb(), get_rel_relkind(), GETSTRUCT(), HeapTupleIsValid, Int32GetDatum(), 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 711 of file pg_depend.c.

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

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

50{
52}
void recordMultipleDependencies(const ObjectAddress *depender, const ObjectAddress *referenced, int nreferenced, DependencyType behavior)
Definition pg_depend.c:59

References fb(), and recordMultipleDependencies().

Referenced by add_column_collation_dependency(), add_column_datatype_dependency(), addFkConstraint(), AddNewAttributeTuples(), AlterForeignDataWrapper(), AlterFunction(), AlterPolicy(), ApplyExtensionUpdates(), ATExecAddOf(), ATExecSetAccessMethodNoStorage(), changeDependencyFor(), 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 195 of file pg_depend.c.

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

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

63{
66 TupleTableSlot **slot;
67 int i,
71
72 if (nreferenced <= 0)
73 return; /* nothing to do */
74
75 /*
76 * During bootstrap, do nothing since pg_depend may not exist yet.
77 *
78 * Objects created during bootstrap are most likely pinned, and the few
79 * that are not do not have dependencies on each other, so that there
80 * would be no need to make a pg_depend entry anyway.
81 */
83 return;
84
86
87 /*
88 * Allocate the slots to use, but delay costly initialization until we
89 * know that they will be used.
90 */
94
95 /* Don't open indexes unless we need to make an update */
96 indstate = NULL;
97
98 /* number of slots currently storing tuples */
100 /* number of slots currently initialized */
101 slot_init_count = 0;
102 for (i = 0; i < nreferenced; i++, referenced++)
103 {
104 /*
105 * If the referenced object is pinned by the system, there's no real
106 * need to record dependencies on it. This saves lots of space in
107 * pg_depend, so it's worth the time taken to check.
108 */
110 continue;
111
113 {
117 }
118
120
121 /*
122 * Record the dependency. Note we don't bother to check for duplicate
123 * dependencies; there's no harm in them.
124 */
132
133 memset(slot[slot_stored_count]->tts_isnull, false,
134 slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
135
138
139 /* If slots are full, insert a batch of tuples */
141 {
142 /* fetch index info only when we know we need it */
143 if (indstate == NULL)
145
147 indstate);
149 }
150 }
151
152 /* Insert any tuples left in the buffer */
153 if (slot_stored_count > 0)
154 {
155 /* fetch index info only when we know we need it */
156 if (indstate == NULL)
158
160 indstate);
161 }
162
163 if (indstate != NULL)
165
167
168 /* Drop only the number of slots used */
169 for (i = 0; i < slot_init_count; i++)
171 pfree(slot);
172}
#define Min(x, y)
Definition c.h:997
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
const TupleTableSlotOps TTSOpsHeapTuple
Definition execTuples.c:85
#define palloc_array(type, count)
Definition fe_memutils.h:76
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:77
void pfree(void *pointer)
Definition mcxt.c:1616
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
FormData_pg_depend
Definition pg_depend.h:65
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define RelationGetDescr(relation)
Definition rel.h:540
Datum * tts_values
Definition tuptable.h:124
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:457

References CatalogCloseIndexes(), CatalogOpenIndexes(), CatalogTuplesMultiInsertWithInfo(), CharGetDatum(), ExecClearTuple(), ExecDropSingleTupleTableSlot(), ExecStoreVirtualTuple(), fb(), FormData_pg_depend, i, Int32GetDatum(), IsBootstrapProcessingMode, isObjectPinned(), MakeSingleTupleTableSlot(), MAX_CATALOG_MULTI_INSERT_BYTES, Min, ObjectIdGetDatum(), palloc_array, 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 901 of file pg_depend.c.

902{
903 bool ret = false;
905 ScanKeyData key[2];
906 SysScanDesc scan;
908
910
911 ScanKeyInit(&key[0],
915 ScanKeyInit(&key[1],
919
921 NULL, 2, key);
922
923 while (HeapTupleIsValid((tup = systable_getnext(scan))))
924 {
926
927 if (depform->refclassid == RelationRelationId &&
928 depform->deptype == deptype)
929 {
930 *tableId = depform->refobjid;
931 *colId = depform->refobjsubid;
932 ret = true;
933 break; /* no need to keep scanning */
934 }
935 }
936
937 systable_endscan(scan);
938
940
941 return ret;
942}

References AccessShareLock, BTEqualStrategyNumber, fb(), GETSTRUCT(), HeapTupleIsValid, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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