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/partition.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)
 
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 565 of file pg_depend.c.

567{
568 long count = 0;
570 ScanKeyData key[2];
571 SysScanDesc scan;
573
575
576 ScanKeyInit(&key[0],
579 ObjectIdGetDatum(classId));
580 ScanKeyInit(&key[1],
584
586 NULL, 2, key);
587
588 while (HeapTupleIsValid((tup = systable_getnext(scan))))
589 {
591
592 /* make a modifiable copy */
595
596 depform->objid = newObjectId;
597
598 CatalogTupleUpdate(depRel, &tup->t_self, tup);
599
601
602 count++;
603 }
604
605 systable_endscan(scan);
606
608
609 return count;
610}
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 621 of file pg_depend.c.

623{
624 long count = 0;
626 ScanKeyData key[2];
627 SysScanDesc scan;
630 bool newIsPinned;
631
633
634 /*
635 * If oldRefObjectId is pinned, there won't be any dependency entries on
636 * it --- we can't cope in that case. (This isn't really worth expending
637 * code to fix, in current usage; it just means you can't rename stuff out
638 * of pg_catalog, which would likely be a bad move anyway.)
639 */
640 objAddr.classId = refClassId;
641 objAddr.objectId = oldRefObjectId;
642 objAddr.objectSubId = 0;
643
647 errmsg("cannot remove dependency on %s because it is a system object",
648 getObjectDescription(&objAddr, false))));
649
650 /*
651 * We can handle adding a dependency on something pinned, though, since
652 * that just means deleting the dependency entry.
653 */
654 objAddr.objectId = newRefObjectId;
655
657
658 /* Now search for dependency records */
659 ScanKeyInit(&key[0],
663 ScanKeyInit(&key[1],
667
669 NULL, 2, key);
670
671 while (HeapTupleIsValid((tup = systable_getnext(scan))))
672 {
673 if (newIsPinned)
674 CatalogTupleDelete(depRel, &tup->t_self);
675 else
676 {
678
679 /* make a modifiable copy */
682
683 depform->refobjid = newRefObjectId;
684
685 CatalogTupleUpdate(depRel, &tup->t_self, tup);
686
688 }
689
690 count++;
691 }
692
693 systable_endscan(scan);
694
696
697 return count;
698}
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#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:709

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

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

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

259{
260 /*
261 * This is actually the same condition tested in
262 * recordDependencyOnCurrentExtension; but we want to issue a
263 * differently-worded error, and anyway it would be pretty confusing to
264 * call recordDependencyOnCurrentExtension in these circumstances.
265 */
266
267 /* Only whole objects can be extension members */
268 Assert(object->objectSubId == 0);
269
271 {
272 Oid oldext;
273
274 oldext = getExtensionOfObject(object->classId, object->objectId);
275 /* If already a member of this extension, OK */
277 return;
278 /* Else complain */
281 errmsg("%s is not a member of extension \"%s\"",
282 getObjectDescription(object, false),
284 errdetail("An extension may only use CREATE ... IF NOT EXISTS to skip object creation if the conflicting object is one that it already owns.")));
285 }
286}
#define Assert(condition)
Definition c.h:873
int errdetail(const char *fmt,...)
Definition elog.c:1216
bool creating_extension
Definition extension.c:77
Oid CurrentExtensionObject
Definition extension.c:78
char * get_extension_name(Oid ext_oid)
Definition extension.c:228
Oid getExtensionOfObject(Oid classId, Oid objectId)
Definition pg_depend.c:732
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 301 of file pg_depend.c.

303{
304 long count = 0;
306 ScanKeyData key[2];
307 SysScanDesc scan;
309
311
312 ScanKeyInit(&key[0],
315 ObjectIdGetDatum(classId));
316 ScanKeyInit(&key[1],
319 ObjectIdGetDatum(objectId));
320
322 NULL, 2, key);
323
324 while (HeapTupleIsValid(tup = systable_getnext(scan)))
325 {
326 if (skipExtensionDeps &&
328 continue;
329
330 CatalogTupleDelete(depRel, &tup->t_self);
331 count++;
332 }
333
334 systable_endscan(scan);
335
337
338 return count;
339}
@ 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 351 of file pg_depend.c.

353{
354 long count = 0;
356 ScanKeyData key[2];
357 SysScanDesc scan;
359
361
362 ScanKeyInit(&key[0],
365 ObjectIdGetDatum(classId));
366 ScanKeyInit(&key[1],
369 ObjectIdGetDatum(objectId));
370
372 NULL, 2, key);
373
374 while (HeapTupleIsValid(tup = systable_getnext(scan)))
375 {
377
378 if (depform->refclassid == refclassId && depform->deptype == deptype)
379 {
380 CatalogTupleDelete(depRel, &tup->t_self);
381 count++;
382 }
383 }
384
385 systable_endscan(scan);
386
388
389 return count;
390}

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

400{
401 long count = 0;
403 ScanKeyData key[2];
404 SysScanDesc scan;
406
408
409 ScanKeyInit(&key[0],
412 ObjectIdGetDatum(classId));
413 ScanKeyInit(&key[1],
416 ObjectIdGetDatum(objectId));
417
419 NULL, 2, key);
420
421 while (HeapTupleIsValid(tup = systable_getnext(scan)))
422 {
424
425 if (depform->refclassid == refclassId &&
426 depform->refobjid == refobjectId &&
427 depform->deptype == deptype)
428 {
429 CatalogTupleDelete(depRel, &tup->t_self);
430 count++;
431 }
432 }
433
434 systable_endscan(scan);
435
437
438 return count;
439}

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

989{
992 ScanKeyData key[3];
993 SysScanDesc scan;
995
996 /* Search the dependency table for the index */
998
999 ScanKeyInit(&key[0],
1003 ScanKeyInit(&key[1],
1007 ScanKeyInit(&key[2],
1010 Int32GetDatum(0));
1011
1013 NULL, 3, key);
1014
1015 while (HeapTupleIsValid(tup = systable_getnext(scan)))
1016 {
1018
1019 /*
1020 * We assume any internal dependency on a constraint must be what we
1021 * are looking for.
1022 */
1023 if (deprec->refclassid == ConstraintRelationId &&
1024 deprec->refobjsubid == 0 &&
1025 deprec->deptype == DEPENDENCY_INTERNAL)
1026 {
1027 constraintId = deprec->refobjid;
1028 break;
1029 }
1030 }
1031
1032 systable_endscan(scan);
1034
1035 return constraintId;
1036}
@ 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 1044 of file pg_depend.c.

1045{
1046 List *result = NIL;
1048 ScanKeyData key[3];
1049 SysScanDesc scan;
1050 HeapTuple tup;
1051
1052 /* Search the dependency table for the index */
1054
1055 ScanKeyInit(&key[0],
1059 ScanKeyInit(&key[1],
1063 ScanKeyInit(&key[2],
1066 Int32GetDatum(0));
1067
1069 NULL, 3, key);
1070
1071 while (HeapTupleIsValid(tup = systable_getnext(scan)))
1072 {
1074
1075 /*
1076 * We assume any normal dependency from a constraint must be what we
1077 * are looking for.
1078 */
1079 if (deprec->classid == ConstraintRelationId &&
1080 deprec->objsubid == 0 &&
1081 deprec->deptype == DEPENDENCY_NORMAL)
1082 {
1083 result = lappend_oid(result, deprec->objid);
1084 }
1085 }
1086
1087 systable_endscan(scan);
1089
1090 return result;
1091}
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 
)

◆ getIdentitySequence()

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

Definition at line 945 of file pg_depend.c.

946{
947 Oid relid = RelationGetRelid(rel);
948 List *seqlist;
949
950 /*
951 * The identity sequence is associated with the topmost partitioned table,
952 * which might have column order different than the given partition.
953 */
955 {
956 List *ancestors = get_partition_ancestors(relid);
957 const char *attname = get_attname(relid, attnum, false);
958
959 relid = llast_oid(ancestors);
960 attnum = get_attnum(relid, attname);
962 elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
963 attname, relid);
964 list_free(ancestors);
965 }
966
968 if (list_length(seqlist) > 1)
969 elog(ERROR, "more than one owned sequence found");
970 else if (seqlist == NIL)
971 {
972 if (missing_ok)
973 return InvalidOid;
974 else
975 elog(ERROR, "no owned sequence found");
976 }
977
978 return linitial_oid(seqlist);
979}
#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:877
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 936 of file pg_depend.c.

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

References getOwnedSequences_internal().

Referenced by ATRewriteTables(), and ExecuteTruncateGuts().

◆ getOwnedSequences_internal()

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

Definition at line 877 of file pg_depend.c.

878{
879 List *result = NIL;
881 ScanKeyData key[3];
882 SysScanDesc scan;
884
886
887 ScanKeyInit(&key[0],
891 ScanKeyInit(&key[1],
894 ObjectIdGetDatum(relid));
895 if (attnum)
896 ScanKeyInit(&key[2],
900
902 NULL, attnum ? 3 : 2, key);
903
904 while (HeapTupleIsValid(tup = systable_getnext(scan)))
905 {
907
908 /*
909 * We assume any auto or internal dependency of a sequence on a column
910 * must be what we are looking for. (We need the relkind test because
911 * indexes can also have auto dependencies on columns.)
912 */
913 if (deprec->classid == RelationRelationId &&
914 deprec->objsubid == 0 &&
915 deprec->refobjsubid != 0 &&
916 (deprec->deptype == DEPENDENCY_AUTO || deprec->deptype == DEPENDENCY_INTERNAL) &&
918 {
919 if (!deptype || deprec->deptype == deptype)
920 result = lappend_oid(result, deprec->objid);
921 }
922 }
923
924 systable_endscan(scan);
925
927
928 return result;
929}
@ 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 709 of file pg_depend.c.

710{
711 return IsPinnedObject(object->classId, object->objectId);
712}
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 45 of file pg_depend.c.

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

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

195{
196 /* Only whole objects can be extension members */
197 Assert(object->objectSubId == 0);
198
200 {
202
203 /* Only need to check for existing membership if isReplace */
204 if (isReplace)
205 {
206 Oid oldext;
207
208 /*
209 * Side note: these catalog lookups are safe only because the
210 * object is a pre-existing one. In the not-isReplace case, the
211 * caller has most likely not yet done a CommandCounterIncrement
212 * that would make the new object visible.
213 */
214 oldext = getExtensionOfObject(object->classId, object->objectId);
215 if (OidIsValid(oldext))
216 {
217 /* If already a member of this extension, nothing to do */
219 return;
220 /* Already a member of some other extension, so reject */
223 errmsg("%s is already a member of extension \"%s\"",
224 getObjectDescription(object, false),
226 }
227 /* It's a free-standing object, so reject */
230 errmsg("%s is not a member of extension \"%s\"",
231 getObjectDescription(object, false),
233 errdetail("An extension is not allowed to replace an object that it does not own.")));
234 }
235
236 /* OK, record it as a member of CurrentExtensionObject */
239 extension.objectSubId = 0;
240
242 }
243}
#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 57 of file pg_depend.c.

61{
64 TupleTableSlot **slot;
65 int i,
69
70 if (nreferenced <= 0)
71 return; /* nothing to do */
72
73 /*
74 * During bootstrap, do nothing since pg_depend may not exist yet.
75 *
76 * Objects created during bootstrap are most likely pinned, and the few
77 * that are not do not have dependencies on each other, so that there
78 * would be no need to make a pg_depend entry anyway.
79 */
81 return;
82
84
85 /*
86 * Allocate the slots to use, but delay costly initialization until we
87 * know that they will be used.
88 */
92
93 /* Don't open indexes unless we need to make an update */
94 indstate = NULL;
95
96 /* number of slots currently storing tuples */
98 /* number of slots currently initialized */
100 for (i = 0; i < nreferenced; i++, referenced++)
101 {
102 /*
103 * If the referenced object is pinned by the system, there's no real
104 * need to record dependencies on it. This saves lots of space in
105 * pg_depend, so it's worth the time taken to check.
106 */
108 continue;
109
111 {
115 }
116
118
119 /*
120 * Record the dependency. Note we don't bother to check for duplicate
121 * dependencies; there's no harm in them.
122 */
130
131 memset(slot[slot_stored_count]->tts_isnull, false,
132 slot[slot_stored_count]->tts_tupleDescriptor->natts * sizeof(bool));
133
136
137 /* If slots are full, insert a batch of tuples */
139 {
140 /* fetch index info only when we know we need it */
141 if (indstate == NULL)
143
145 indstate);
147 }
148 }
149
150 /* Insert any tuples left in the buffer */
151 if (slot_stored_count > 0)
152 {
153 /* fetch index info only when we know we need it */
154 if (indstate == NULL)
156
158 indstate);
159 }
160
161 if (indstate != NULL)
163
165
166 /* Drop only the number of slots used */
167 for (i = 0; i < slot_init_count; i++)
169 pfree(slot);
170}
#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 828 of file pg_depend.c.

829{
830 bool ret = false;
832 ScanKeyData key[2];
833 SysScanDesc scan;
835
837
838 ScanKeyInit(&key[0],
842 ScanKeyInit(&key[1],
846
848 NULL, 2, key);
849
850 while (HeapTupleIsValid((tup = systable_getnext(scan))))
851 {
853
854 if (depform->refclassid == RelationRelationId &&
855 depform->deptype == deptype)
856 {
857 *tableId = depform->refobjid;
858 *colId = depform->refobjsubid;
859 ret = true;
860 break; /* no need to keep scanning */
861 }
862 }
863
864 systable_endscan(scan);
865
867
868 return ret;
869}

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