PostgreSQL Source Code git master
Loading...
Searching...
No Matches
pg_constraint.h File Reference
#include "catalog/dependency.h"
#include "catalog/genbki.h"
#include "catalog/pg_constraint_d.h"
#include "nodes/pg_list.h"
Include dependency graph for pg_constraint.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef FormData_pg_constraintForm_pg_constraint
 
typedef enum ConstraintCategory ConstraintCategory
 

Enumerations

enum  ConstraintCategory { CONSTRAINT_RELATION , CONSTRAINT_DOMAIN , CONSTRAINT_ASSERTION }
 

Functions

 CATALOG (pg_constraint, 2606, ConstraintRelationId)
 
 DECLARE_TOAST (pg_constraint, 2832, 2833)
 
 DECLARE_INDEX (pg_constraint_conname_nsp_index, 2664, ConstraintNameNspIndexId, pg_constraint, btree(conname name_ops, connamespace oid_ops))
 
 DECLARE_UNIQUE_INDEX (pg_constraint_conrelid_contypid_conname_index, 2665, ConstraintRelidTypidNameIndexId, pg_constraint, btree(conrelid oid_ops, contypid oid_ops, conname name_ops))
 
 DECLARE_INDEX (pg_constraint_contypid_index, 2666, ConstraintTypidIndexId, pg_constraint, btree(contypid oid_ops))
 
 DECLARE_UNIQUE_INDEX_PKEY (pg_constraint_oid_index, 2667, ConstraintOidIndexId, pg_constraint, btree(oid oid_ops))
 
 DECLARE_INDEX (pg_constraint_conparentid_index, 2579, ConstraintParentIndexId, pg_constraint, btree(conparentid oid_ops))
 
 MAKE_SYSCACHE (CONSTROID, pg_constraint_oid_index, 16)
 
 DECLARE_ARRAY_FOREIGN_KEY_OPT ((conrelid, conkey), pg_attribute,(attrelid, attnum))
 
 DECLARE_ARRAY_FOREIGN_KEY ((confrelid, confkey), pg_attribute,(attrelid, attnum))
 
Oid CreateConstraintEntry (const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isEnforced, bool isValidated, Oid parentConstrId, Oid relId, const int16 *constraintKey, int constraintNKeys, int constraintNTotalKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, const int16 *fkDeleteSetCols, int numFkDeleteSetCols, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int16 conInhCount, bool conNoInherit, bool conPeriod, bool is_internal)
 
bool ConstraintNameIsUsed (ConstraintCategory conCat, Oid objId, const char *conname)
 
bool ConstraintNameExists (const char *conname, Oid namespaceid)
 
charChooseConstraintName (const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)
 
HeapTuple findNotNullConstraintAttnum (Oid relid, AttrNumber attnum)
 
HeapTuple findNotNullConstraint (Oid relid, const char *colname)
 
HeapTuple findDomainNotNullConstraint (Oid typid)
 
AttrNumber extractNotNullColumn (HeapTuple constrTup)
 
bool AdjustNotNullInheritance (Oid relid, AttrNumber attnum, const char *new_conname, bool is_local, bool is_no_inherit, bool is_notvalid)
 
ListRelationGetNotNullConstraints (Oid relid, bool cooked, bool include_noinh)
 
void RemoveConstraintById (Oid conId)
 
void RenameConstraintById (Oid conId, const char *newname)
 
void AlterConstraintNamespaces (Oid ownerId, Oid oldNspId, Oid newNspId, bool isType, ObjectAddresses *objsMoved)
 
void ConstraintSetParentConstraint (Oid childConstrId, Oid parentConstrId, Oid childTableId)
 
Oid get_relation_constraint_oid (Oid relid, const char *conname, bool missing_ok)
 
Bitmapsetget_relation_constraint_attnos (Oid relid, const char *conname, bool missing_ok, Oid *constraintOid)
 
Oid get_domain_constraint_oid (Oid typid, const char *conname, bool missing_ok)
 
Oid get_relation_idx_constraint_oid (Oid relationId, Oid indexId)
 
Bitmapsetget_primary_key_attnos (Oid relid, bool deferrableOk, Oid *constraintOid)
 
void DeconstructFkConstraintRow (HeapTuple tuple, int *numfks, AttrNumber *conkey, AttrNumber *confkey, Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs, int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)
 
void FindFKPeriodOpers (Oid opclass, Oid *containedbyoperoid, Oid *aggedcontainedbyoperoid, Oid *intersectoperoid)
 
bool check_functional_grouping (Oid relid, Index varno, Index varlevelsup, List *grouping_columns, List **constraintDeps)
 

Variables

 FormData_pg_constraint
 

Typedef Documentation

◆ ConstraintCategory

◆ Form_pg_constraint

Enumeration Type Documentation

◆ ConstraintCategory

Enumerator
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 213 of file pg_constraint.h.

214{
217 CONSTRAINT_ASSERTION, /* for future expansion */
ConstraintCategory
@ CONSTRAINT_DOMAIN
@ CONSTRAINT_RELATION
@ CONSTRAINT_ASSERTION

Function Documentation

◆ AdjustNotNullInheritance()

bool AdjustNotNullInheritance ( Oid  relid,
AttrNumber  attnum,
const char new_conname,
bool  is_local,
bool  is_no_inherit,
bool  is_notvalid 
)
extern

Definition at line 742 of file pg_constraint.c.

744{
746
749 {
752 bool changed = false;
753
756
757 /*
758 * If the NO INHERIT flag we're asked for doesn't match what the
759 * existing constraint has, throw an error.
760 */
761 if (is_no_inherit != conform->connoinherit)
764 errmsg("cannot change NO INHERIT status of NOT NULL constraint \"%s\" on relation \"%s\"",
765 NameStr(conform->conname), get_rel_name(relid)),
766 errhint("You might need to make the existing constraint inheritable using %s.",
767 "ALTER TABLE ... ALTER CONSTRAINT ... INHERIT"));
768
769 /*
770 * Throw an error if the existing constraint is NOT VALID and caller
771 * wants a valid one.
772 */
773 if (!is_notvalid && !conform->convalidated)
776 errmsg("incompatible NOT VALID constraint \"%s\" on relation \"%s\"",
777 NameStr(conform->conname), get_rel_name(relid)),
778 errhint("You might need to validate it using %s.",
779 "ALTER TABLE ... VALIDATE CONSTRAINT"));
780
781 /*
782 * If, for a new constraint that is being defined locally (i.e., not
783 * being passed down via inheritance), a name was specified, then
784 * verify that the existing constraint has the same name. Otherwise
785 * throw an error. Names of inherited constraints are ignored because
786 * they are not directly user-specified, so matching is not important.
787 */
788 if (is_local && new_conname &&
789 strcmp(new_conname, NameStr(conform->conname)) != 0)
792 errmsg("cannot create not-null constraint \"%s\" on column \"%s\" of table \"%s\"",
793 new_conname, get_attname(relid, attnum, false), get_rel_name(relid)),
794 errdetail("A not-null constraint named \"%s\" already exists for this column.",
795 NameStr(conform->conname)));
796
797 if (!is_local)
798 {
799 if (pg_add_s16_overflow(conform->coninhcount, 1,
800 &conform->coninhcount))
803 errmsg("too many inheritance parents"));
804 changed = true;
805 }
806 else if (!conform->conislocal)
807 {
808 conform->conislocal = true;
809 changed = true;
810 }
811
812 if (changed)
814
816
817 return true;
818 }
819
820 return false;
821}
#define NameStr(name)
Definition c.h:765
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errhint(const char *fmt,...)
Definition elog.c:1330
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
#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
static bool pg_add_s16_overflow(int16 a, int16 b, int16 *result)
Definition int.h:67
#define RowExclusiveLock
Definition lockdefs.h:38
char * get_rel_name(Oid relid)
Definition lsyscache.c:2078
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:903
int16 attnum
HeapTuple findNotNullConstraintAttnum(Oid relid, AttrNumber attnum)
FormData_pg_constraint * Form_pg_constraint
static int fb(int x)
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References attnum, CatalogTupleUpdate(), ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, fb(), findNotNullConstraintAttnum(), get_attname(), get_rel_name(), GETSTRUCT(), HeapTupleIsValid, NameStr, pg_add_s16_overflow(), RowExclusiveLock, table_close(), and table_open().

Referenced by AddRelationNewConstraints().

◆ AlterConstraintNamespaces()

void AlterConstraintNamespaces ( Oid  ownerId,
Oid  oldNspId,
Oid  newNspId,
bool  isType,
ObjectAddresses objsMoved 
)
extern

Definition at line 1057 of file pg_constraint.c.

1059{
1061 ScanKeyData key[2];
1062 SysScanDesc scan;
1063 HeapTuple tup;
1064
1066
1067 ScanKeyInit(&key[0],
1070 ObjectIdGetDatum(isType ? InvalidOid : ownerId));
1071 ScanKeyInit(&key[1],
1074 ObjectIdGetDatum(isType ? ownerId : InvalidOid));
1075
1077 NULL, 2, key);
1078
1079 while (HeapTupleIsValid((tup = systable_getnext(scan))))
1080 {
1083
1085
1087 continue;
1088
1089 /* Don't update if the object is already part of the namespace */
1090 if (conform->connamespace == oldNspId && oldNspId != newNspId)
1091 {
1094
1095 conform->connamespace = newNspId;
1096
1097 CatalogTupleUpdate(conRel, &tup->t_self, tup);
1098
1099 /*
1100 * Note: currently, the constraint will not have its own
1101 * dependency on the namespace, so we don't need to do
1102 * changeDependencyFor().
1103 */
1104 }
1105
1107
1109 }
1110
1111 systable_endscan(scan);
1112
1114}
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
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
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
#define InvalidOid
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31

References add_exact_object_address(), BTEqualStrategyNumber, CatalogTupleUpdate(), fb(), GETSTRUCT(), heap_copytuple(), HeapTupleIsValid, InvalidOid, InvokeObjectPostAlterHook, object_address_present(), ObjectAddressSet, ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterTableNamespaceInternal(), and AlterTypeNamespaceInternal().

◆ CATALOG()

CATALOG ( pg_constraint  ,
2606  ,
ConstraintRelationId   
)

Definition at line 31 of file pg_constraint.h.

32{
33 Oid oid; /* oid */
34
35 /*
36 * conname + connamespace is deliberately not unique; we allow, for
37 * example, the same name to be used for constraints of different
38 * relations. This is partly for backwards compatibility with past
39 * Postgres practice, and partly because we don't want to have to obtain a
40 * global lock to generate a globally unique name for a nameless
41 * constraint. We associate a namespace with constraint names only for
42 * SQL-spec compatibility.
43 *
44 * However, we do require conname to be unique among the constraints of a
45 * single relation or domain. This is enforced by a unique index on
46 * conrelid + contypid + conname.
47 */
48 NameData conname; /* name of this constraint */
49 Oid connamespace BKI_LOOKUP(pg_namespace); /* OID of namespace
50 * containing constraint */
51 char contype; /* constraint type; see codes below */
52 bool condeferrable; /* deferrable constraint? */
53 bool condeferred; /* deferred by default? */
54 bool conenforced; /* enforced constraint? */
55 bool convalidated; /* constraint has been validated? */
56
57 /*
58 * conrelid and conkey are only meaningful if the constraint applies to a
59 * specific relation (this excludes domain constraints and assertions).
60 * Otherwise conrelid is 0 and conkey is NULL.
61 */
62 Oid conrelid BKI_LOOKUP_OPT(pg_class); /* relation this
63 * constraint constrains */
64
65 /*
66 * contypid links to the pg_type row for a domain if this is a domain
67 * constraint. Otherwise it's 0.
68 *
69 * For SQL-style global ASSERTIONs, both conrelid and contypid would be
70 * zero. This is not presently supported, however.
71 */
72 Oid contypid BKI_LOOKUP_OPT(pg_type); /* domain this constraint
73 * constrains */
74
75 /*
76 * conindid links to the index supporting the constraint, if any;
77 * otherwise it's 0. This is used for unique, primary-key, and exclusion
78 * constraints, and less obviously for foreign-key constraints (where the
79 * index is a unique index on the referenced relation's referenced
80 * columns). Notice that the index is on conrelid in the first case but
81 * confrelid in the second.
82 */
83 Oid conindid BKI_LOOKUP_OPT(pg_class); /* index supporting this
84 * constraint */
85
86 /*
87 * If this constraint is on a partition inherited from a partitioned
88 * table, this is the OID of the corresponding constraint in the parent.
89 */
91
92 /*
93 * These fields, plus confkey, are only meaningful for a foreign-key
94 * constraint. Otherwise confrelid is 0 and the char fields are spaces.
95 */
96 Oid confrelid BKI_LOOKUP_OPT(pg_class); /* relation referenced by
97 * foreign key */
98 char confupdtype; /* foreign key's ON UPDATE action */
99 char confdeltype; /* foreign key's ON DELETE action */
100 char confmatchtype; /* foreign key's match type */
101
102 /* Has a local definition (hence, do not drop when coninhcount is 0) */
103 bool conislocal;
104
105 /* Number of times inherited from direct parent relation(s) */
107
108 /* Has a local definition and cannot be inherited */
109 bool connoinherit;
110
111 /*
112 * For primary keys, unique constraints, and foreign keys, signifies the
113 * last column uses overlaps instead of equals.
114 */
115 bool conperiod;
116
117#ifdef CATALOG_VARLEN /* variable-length fields start here */
118
119 /*
120 * Columns of conrelid that the constraint applies to, if known (this is
121 * NULL for trigger constraints)
122 */
123 int16 conkey[1];
124
125 /*
126 * If a foreign key, the referenced columns of confrelid
127 */
128 int16 confkey[1];
129
130 /*
131 * If a foreign key, the OIDs of the PK = FK equality/overlap operators
132 * for each column of the constraint
133 */
135
136 /*
137 * If a foreign key, the OIDs of the PK = PK equality/overlap operators
138 * for each column of the constraint (i.e., equality for the referenced
139 * columns)
140 */
142
143 /*
144 * If a foreign key, the OIDs of the FK = FK equality/overlap operators
145 * for each column of the constraint (i.e., equality for the referencing
146 * columns)
147 */
149
150 /*
151 * If a foreign key with an ON DELETE SET NULL/DEFAULT action, the subset
152 * of conkey to updated. If null, all columns are updated.
153 */
154 int16 confdelsetcols[1];
155
156 /*
157 * If an exclusion constraint, the OIDs of the exclusion operators for
158 * each column of the constraint. Also set for unique constraints/primary
159 * keys using WITHOUT OVERLAPS.
160 */
162
163 /*
164 * If a check constraint, nodeToString representation of expression
165 */
167#endif
int16_t int16
Definition c.h:541
#define BKI_LOOKUP(catalog)
Definition genbki.h:46
#define BKI_LOOKUP_OPT(catalog)
Definition genbki.h:47
FormData_pg_constraint
unsigned int Oid
Definition c.h:760

References BKI_LOOKUP, BKI_LOOKUP_OPT, and fb().

◆ check_functional_grouping()

bool check_functional_grouping ( Oid  relid,
Index  varno,
Index  varlevelsup,
List grouping_columns,
List **  constraintDeps 
)
extern

Definition at line 1742 of file pg_constraint.c.

1746{
1750 ListCell *gl;
1751
1752 /* If the rel has no PK, then we can't prove functional dependency */
1754 if (pkattnos == NULL)
1755 return false;
1756
1757 /* Identify all the rel's columns that appear in grouping_columns */
1759 foreach(gl, grouping_columns)
1760 {
1761 Var *gvar = (Var *) lfirst(gl);
1762
1763 if (IsA(gvar, Var) &&
1764 gvar->varno == varno &&
1765 gvar->varlevelsup == varlevelsup)
1768 }
1769
1771 {
1772 /* The PK is a subset of grouping_columns, so we win */
1774 return true;
1775 }
1776
1777 return false;
1778}
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:412
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:814
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
#define IsA(nodeptr, _type_)
Definition nodes.h:164
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define lfirst(lc)
Definition pg_list.h:172
#define FirstLowInvalidHeapAttributeNumber
Definition sysattr.h:27

References bms_add_member(), bms_is_subset(), fb(), FirstLowInvalidHeapAttributeNumber, get_primary_key_attnos(), IsA, lappend_oid(), and lfirst.

Referenced by init_grouping_targets(), and substitute_grouped_columns_mutator().

◆ ChooseConstraintName()

char * ChooseConstraintName ( const char name1,
const char name2,
const char label,
Oid  namespaceid,
List others 
)
extern

Definition at line 513 of file pg_constraint.c.

516{
517 int pass = 0;
518 char *conname = NULL;
519 char modlabel[NAMEDATALEN];
522 ScanKeyData skey[2];
523 bool found;
524 ListCell *l;
525
527
528 /* try the unmodified label first, unless it's empty */
529 if (label[0] != '\0')
530 strlcpy(modlabel, label, sizeof(modlabel));
531 else
532 snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
533
534 for (;;)
535 {
536 conname = makeObjectName(name1, name2, modlabel);
537
538 found = false;
539
540 foreach(l, others)
541 {
542 if (strcmp((char *) lfirst(l), conname) == 0)
543 {
544 found = true;
545 break;
546 }
547 }
548
549 if (!found)
550 {
551 ScanKeyInit(&skey[0],
554 CStringGetDatum(conname));
555
556 ScanKeyInit(&skey[1],
560
562 NULL, 2, skey);
563
565
567 }
568
569 if (!found)
570 break;
571
572 /* found a conflict, so try a new name component */
573 pfree(conname);
574 snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
575 }
576
578
579 return conname;
580}
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition indexcmds.c:2543
#define AccessShareLock
Definition lockdefs.h:36
void pfree(void *pointer)
Definition mcxt.c:1616
static char * label
#define NAMEDATALEN
#define snprintf
Definition port.h:260
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380

References AccessShareLock, BTEqualStrategyNumber, CStringGetDatum(), fb(), HeapTupleIsValid, label, lfirst, makeObjectName(), NAMEDATALEN, ObjectIdGetDatum(), pfree(), ScanKeyInit(), snprintf, strlcpy(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by addFkConstraint(), AddRelationNewConstraints(), AddRelationNotNullConstraints(), ATExecAddConstraint(), ATExecSetNotNull(), domainAddCheckConstraint(), and domainAddNotNullConstraint().

◆ ConstraintNameExists()

◆ ConstraintNameIsUsed()

bool ConstraintNameIsUsed ( ConstraintCategory  conCat,
Oid  objId,
const char conname 
)
extern

◆ ConstraintSetParentConstraint()

void ConstraintSetParentConstraint ( Oid  childConstrId,
Oid  parentConstrId,
Oid  childTableId 
)
extern

Definition at line 1126 of file pg_constraint.c.

1129{
1132 HeapTuple tuple,
1133 newtup;
1136
1139 if (!HeapTupleIsValid(tuple))
1140 elog(ERROR, "cache lookup failed for constraint %u", childConstrId);
1141 newtup = heap_copytuple(tuple);
1144 {
1145 /* don't allow setting parent for a constraint that already has one */
1146 Assert(constrForm->coninhcount == 0);
1147 if (constrForm->conparentid != InvalidOid)
1148 elog(ERROR, "constraint %u already has a parent constraint",
1150
1151 constrForm->conislocal = false;
1152 if (pg_add_s16_overflow(constrForm->coninhcount, 1,
1153 &constrForm->coninhcount))
1154 ereport(ERROR,
1156 errmsg("too many inheritance parents"));
1157
1158 constrForm->conparentid = parentConstrId;
1159
1161
1163
1166
1169 }
1170 else
1171 {
1172 constrForm->coninhcount--;
1173 constrForm->conislocal = true;
1174 constrForm->conparentid = InvalidOid;
1175
1176 /* Make sure there's no further inheritance. */
1177 Assert(constrForm->coninhcount == 0);
1178
1180
1187 }
1188
1189 ReleaseSysCache(tuple);
1191}
#define Assert(condition)
Definition c.h:873
#define OidIsValid(objectId)
Definition c.h:788
@ DEPENDENCY_PARTITION_PRI
Definition dependency.h:36
@ DEPENDENCY_PARTITION_SEC
Definition dependency.h:37
#define elog(elevel,...)
Definition elog.h:226
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition pg_depend.c:45
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition pg_depend.c:351
ItemPointerData t_self
Definition htup.h:65
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220

References Assert, CatalogTupleUpdate(), deleteDependencyRecordsForClass(), DEPENDENCY_PARTITION_PRI, DEPENDENCY_PARTITION_SEC, elog, ereport, errcode(), errmsg(), ERROR, fb(), GETSTRUCT(), heap_copytuple(), HeapTupleIsValid, InvalidOid, ObjectAddressSet, ObjectIdGetDatum(), OidIsValid, pg_add_s16_overflow(), recordDependencyOn(), ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by ATExecAttachPartitionIdx(), AttachPartitionEnsureIndexes(), AttachPartitionForeignKey(), DefineIndex(), and DetachPartitionFinalize().

◆ CreateConstraintEntry()

Oid CreateConstraintEntry ( const char constraintName,
Oid  constraintNamespace,
char  constraintType,
bool  isDeferrable,
bool  isDeferred,
bool  isEnforced,
bool  isValidated,
Oid  parentConstrId,
Oid  relId,
const int16 constraintKey,
int  constraintNKeys,
int  constraintNTotalKeys,
Oid  domainId,
Oid  indexRelId,
Oid  foreignRelId,
const int16 foreignKey,
const Oid pfEqOp,
const Oid ppEqOp,
const Oid ffEqOp,
int  foreignNKeys,
char  foreignUpdateType,
char  foreignDeleteType,
const int16 fkDeleteSetCols,
int  numFkDeleteSetCols,
char  foreignMatchType,
const Oid exclOp,
Node conExpr,
const char conBin,
bool  conIsLocal,
int16  conInhCount,
bool  conNoInherit,
bool  conPeriod,
bool  is_internal 
)
extern

Definition at line 51 of file pg_constraint.c.

84{
86 Oid conOid;
88 bool nulls[Natts_pg_constraint];
98 int i;
102
103 /* Only CHECK or FOREIGN KEY constraint can be not enforced */
106 /* NOT ENFORCED constraint must be NOT VALID */
108
110
113
114 /*
115 * Convert C arrays into Postgres arrays.
116 */
117 if (constraintNKeys > 0)
118 {
119 Datum *conkey;
120
121 conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));
122 for (i = 0; i < constraintNKeys; i++)
125 }
126 else
128
129 if (foreignNKeys > 0)
130 {
132 int nkeys = Max(foreignNKeys, numFkDeleteSetCols);
133
134 fkdatums = (Datum *) palloc(nkeys * sizeof(Datum));
135 for (i = 0; i < foreignNKeys; i++)
138 for (i = 0; i < foreignNKeys; i++)
141 for (i = 0; i < foreignNKeys; i++)
144 for (i = 0; i < foreignNKeys; i++)
147
148 if (numFkDeleteSetCols > 0)
149 {
150 for (i = 0; i < numFkDeleteSetCols; i++)
153 }
154 else
156 }
157 else
158 {
164 }
165
166 if (exclOp != NULL)
167 {
169
170 opdatums = (Datum *) palloc(constraintNKeys * sizeof(Datum));
171 for (i = 0; i < constraintNKeys; i++)
174 }
175 else
177
178 /* initialize nulls and values */
179 for (i = 0; i < Natts_pg_constraint; i++)
180 {
181 nulls[i] = false;
182 values[i] = (Datum) 0;
183 }
184
207
208 if (conkeyArray)
210 else
211 nulls[Anum_pg_constraint_conkey - 1] = true;
212
213 if (confkeyArray)
215 else
216 nulls[Anum_pg_constraint_confkey - 1] = true;
217
218 if (conpfeqopArray)
220 else
221 nulls[Anum_pg_constraint_conpfeqop - 1] = true;
222
223 if (conppeqopArray)
225 else
226 nulls[Anum_pg_constraint_conppeqop - 1] = true;
227
228 if (conffeqopArray)
230 else
231 nulls[Anum_pg_constraint_conffeqop - 1] = true;
232
235 else
236 nulls[Anum_pg_constraint_confdelsetcols - 1] = true;
237
238 if (conexclopArray)
240 else
241 nulls[Anum_pg_constraint_conexclop - 1] = true;
242
243 if (conBin)
245 else
246 nulls[Anum_pg_constraint_conbin - 1] = true;
247
249
251
253
255
256 /* Handle set of auto dependencies */
258
259 if (OidIsValid(relId))
260 {
261 /*
262 * Register auto dependency from constraint to owning relation, or to
263 * specific column(s) if any are mentioned.
264 */
266
267 if (constraintNTotalKeys > 0)
268 {
269 for (i = 0; i < constraintNTotalKeys; i++)
270 {
274 }
275 }
276 else
277 {
280 }
281 }
282
283 if (OidIsValid(domainId))
284 {
285 /*
286 * Register auto dependency from constraint to owning domain
287 */
289
292 }
293
297
298 /* Handle set of normal dependencies */
300
302 {
303 /*
304 * Register normal dependency from constraint to foreign relation, or
305 * to specific column(s) if any are mentioned.
306 */
308
309 if (foreignNKeys > 0)
310 {
311 for (i = 0; i < foreignNKeys; i++)
312 {
316 }
317 }
318 else
319 {
322 }
323 }
324
326 {
327 /*
328 * Register normal dependency on the unique index that supports a
329 * foreign-key constraint. (Note: for indexes associated with unique
330 * or primary-key constraints, the dependency runs the other way, and
331 * is not made here.)
332 */
334
337 }
338
339 if (foreignNKeys > 0)
340 {
341 /*
342 * Register normal dependencies on the equality operators that support
343 * a foreign-key constraint. If the PK and FK types are the same then
344 * all three operators for a column are the same; otherwise they are
345 * different.
346 */
348
350 oprobject.objectSubId = 0;
351
352 for (i = 0; i < foreignNKeys; i++)
353 {
354 oprobject.objectId = pfEqOp[i];
356 if (ppEqOp[i] != pfEqOp[i])
357 {
358 oprobject.objectId = ppEqOp[i];
360 }
361 if (ffEqOp[i] != pfEqOp[i])
362 {
363 oprobject.objectId = ffEqOp[i];
365 }
366 }
367 }
368
372
373 /*
374 * We don't bother to register dependencies on the exclusion operators of
375 * an exclusion constraint. We assume they are members of the opclass
376 * supporting the index, so there's an indirect dependency via that. (This
377 * would be pretty dicey for cross-type operators, but exclusion operators
378 * can never be cross-type.)
379 */
380
381 if (conExpr != NULL)
382 {
383 /*
384 * Register dependencies from constraint to objects mentioned in CHECK
385 * expression.
386 */
389 DEPENDENCY_NORMAL, false);
390 }
391
392 /* Post creation hook for new constraint */
394 is_internal);
395
396 return conOid;
397}
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
static Datum values[MAXATTR]
Definition bootstrap.c:155
#define CStringGetTextDatum(s)
Definition builtins.h:97
#define Max(x, y)
Definition c.h:991
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:448
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)
ObjectAddresses * new_object_addresses(void)
void free_object_addresses(ObjectAddresses *addrs)
@ DEPENDENCY_AUTO
Definition dependency.h:34
@ DEPENDENCY_NORMAL
Definition dependency.h:33
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1117
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
int i
Definition isn.c:77
void * palloc(Size size)
Definition mcxt.c:1387
void namestrcpy(Name name, const char *str)
Definition name.c:233
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
static Datum PointerGetDatum(const void *X)
Definition postgres.h:352
static Datum Int16GetDatum(int16 X)
Definition postgres.h:182
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:403
uint64_t Datum
Definition postgres.h:70
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define RelationGetDescr(relation)
Definition rel.h:540

References add_exact_object_address(), Assert, BoolGetDatum(), CatalogTupleInsert(), CharGetDatum(), ObjectAddress::classId, construct_array_builtin(), CStringGetTextDatum, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, fb(), free_object_addresses(), GetNewOidWithIndex(), heap_form_tuple(), i, Int16GetDatum(), InvokeObjectPostCreateHookArg, Max, NameGetDatum(), namestrcpy(), new_object_addresses(), ObjectAddressSet, ObjectAddressSubSet, ObjectIdGetDatum(), OidIsValid, palloc(), PointerGetDatum(), record_object_address_dependencies(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RowExclusiveLock, table_close(), table_open(), and values.

Referenced by addFkConstraint(), CreateTriggerFiringOn(), domainAddCheckConstraint(), domainAddNotNullConstraint(), index_constraint_create(), StoreRelCheck(), and StoreRelNotNull().

◆ DECLARE_ARRAY_FOREIGN_KEY()

DECLARE_ARRAY_FOREIGN_KEY ( (confrelid, confkey ,
pg_attribute  ,
(attrelid, attnum  
)

◆ DECLARE_ARRAY_FOREIGN_KEY_OPT()

DECLARE_ARRAY_FOREIGN_KEY_OPT ( (conrelid, conkey ,
pg_attribute  ,
(attrelid, attnum  
)

◆ DECLARE_INDEX() [1/3]

DECLARE_INDEX ( pg_constraint_conname_nsp_index  ,
2664  ,
ConstraintNameNspIndexId  ,
pg_constraint  ,
btree(conname name_ops, connamespace oid_ops  
)

◆ DECLARE_INDEX() [2/3]

DECLARE_INDEX ( pg_constraint_conparentid_index  ,
2579  ,
ConstraintParentIndexId  ,
pg_constraint  ,
btree(conparentid oid_ops  
)

◆ DECLARE_INDEX() [3/3]

DECLARE_INDEX ( pg_constraint_contypid_index  ,
2666  ,
ConstraintTypidIndexId  ,
pg_constraint  ,
btree(contypid oid_ops  
)

◆ DECLARE_TOAST()

DECLARE_TOAST ( pg_constraint  ,
2832  ,
2833   
)

◆ DECLARE_UNIQUE_INDEX()

DECLARE_UNIQUE_INDEX ( pg_constraint_conrelid_contypid_conname_index  ,
2665  ,
ConstraintRelidTypidNameIndexId  ,
pg_constraint  ,
btree(conrelid oid_ops, contypid oid_ops, conname name_ops  
)

◆ DECLARE_UNIQUE_INDEX_PKEY()

DECLARE_UNIQUE_INDEX_PKEY ( pg_constraint_oid_index  ,
2667  ,
ConstraintOidIndexId  ,
pg_constraint  ,
btree(oid oid_ops  
)

◆ DeconstructFkConstraintRow()

void DeconstructFkConstraintRow ( HeapTuple  tuple,
int numfks,
AttrNumber conkey,
AttrNumber confkey,
Oid pf_eq_oprs,
Oid pp_eq_oprs,
Oid ff_eq_oprs,
int num_fk_del_set_cols,
AttrNumber fk_del_set_cols 
)
extern

Definition at line 1538 of file pg_constraint.c.

1542{
1543 Datum adatum;
1544 bool isNull;
1545 ArrayType *arr;
1546 int numkeys;
1547
1548 /*
1549 * We expect the arrays to be 1-D arrays of the right types; verify that.
1550 * We don't need to use deconstruct_array() since the array data is just
1551 * going to look like a C array of values.
1552 */
1555 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1556 if (ARR_NDIM(arr) != 1 ||
1557 ARR_HASNULL(arr) ||
1558 ARR_ELEMTYPE(arr) != INT2OID)
1559 elog(ERROR, "conkey is not a 1-D smallint array");
1560 numkeys = ARR_DIMS(arr)[0];
1562 elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
1563 memcpy(conkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1564 if (arr != DatumGetPointer(adatum))
1565 pfree(arr); /* free de-toasted copy, if any */
1566
1569 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1570 if (ARR_NDIM(arr) != 1 ||
1571 ARR_DIMS(arr)[0] != numkeys ||
1572 ARR_HASNULL(arr) ||
1573 ARR_ELEMTYPE(arr) != INT2OID)
1574 elog(ERROR, "confkey is not a 1-D smallint array");
1575 memcpy(confkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1576 if (arr != DatumGetPointer(adatum))
1577 pfree(arr); /* free de-toasted copy, if any */
1578
1579 if (pf_eq_oprs)
1580 {
1583 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1584 /* see TryReuseForeignKey if you change the test below */
1585 if (ARR_NDIM(arr) != 1 ||
1586 ARR_DIMS(arr)[0] != numkeys ||
1587 ARR_HASNULL(arr) ||
1588 ARR_ELEMTYPE(arr) != OIDOID)
1589 elog(ERROR, "conpfeqop is not a 1-D Oid array");
1590 memcpy(pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1591 if (arr != DatumGetPointer(adatum))
1592 pfree(arr); /* free de-toasted copy, if any */
1593 }
1594
1595 if (pp_eq_oprs)
1596 {
1599 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1600 if (ARR_NDIM(arr) != 1 ||
1601 ARR_DIMS(arr)[0] != numkeys ||
1602 ARR_HASNULL(arr) ||
1603 ARR_ELEMTYPE(arr) != OIDOID)
1604 elog(ERROR, "conppeqop is not a 1-D Oid array");
1605 memcpy(pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1606 if (arr != DatumGetPointer(adatum))
1607 pfree(arr); /* free de-toasted copy, if any */
1608 }
1609
1610 if (ff_eq_oprs)
1611 {
1614 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1615 if (ARR_NDIM(arr) != 1 ||
1616 ARR_DIMS(arr)[0] != numkeys ||
1617 ARR_HASNULL(arr) ||
1618 ARR_ELEMTYPE(arr) != OIDOID)
1619 elog(ERROR, "conffeqop is not a 1-D Oid array");
1620 memcpy(ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1621 if (arr != DatumGetPointer(adatum))
1622 pfree(arr); /* free de-toasted copy, if any */
1623 }
1624
1625 if (fk_del_set_cols)
1626 {
1629 if (isNull)
1630 {
1632 }
1633 else
1634 {
1635 int num_delete_cols;
1636
1637 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1638 if (ARR_NDIM(arr) != 1 ||
1639 ARR_HASNULL(arr) ||
1640 ARR_ELEMTYPE(arr) != INT2OID)
1641 elog(ERROR, "confdelsetcols is not a 1-D smallint array");
1642 num_delete_cols = ARR_DIMS(arr)[0];
1643 memcpy(fk_del_set_cols, ARR_DATA_PTR(arr), num_delete_cols * sizeof(int16));
1644 if (arr != DatumGetPointer(adatum))
1645 pfree(arr); /* free de-toasted copy, if any */
1646
1648 }
1649 }
1650
1651 *numfks = numkeys;
1652}
#define ARR_NDIM(a)
Definition array.h:290
#define ARR_DATA_PTR(a)
Definition array.h:322
#define DatumGetArrayTypeP(X)
Definition array.h:261
#define ARR_ELEMTYPE(a)
Definition array.h:292
#define ARR_DIMS(a)
Definition array.h:294
#define ARR_HASNULL(a)
Definition array.h:291
#define INDEX_MAX_KEYS
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:342
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, DatumGetArrayTypeP, DatumGetPointer(), elog, ERROR, fb(), INDEX_MAX_KEYS, pfree(), SysCacheGetAttr(), and SysCacheGetAttrNotNull().

Referenced by CloneFkReferenced(), CloneFkReferencing(), DetachPartitionFinalize(), RelationGetFKeyList(), and ri_LoadConstraintInfo().

◆ extractNotNullColumn()

AttrNumber extractNotNullColumn ( HeapTuple  constrTup)
extern

Definition at line 702 of file pg_constraint.c.

703{
705 ArrayType *arr;
706
707 /* only tuples for not-null constraints should be given */
709
712 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
713 if (ARR_NDIM(arr) != 1 ||
714 ARR_HASNULL(arr) ||
715 ARR_ELEMTYPE(arr) != INT2OID ||
716 ARR_DIMS(arr)[0] != 1)
717 elog(ERROR, "conkey is not a 1-D smallint array");
718
719 /* We leak the detoasted datum, but we don't care */
720
721 return ((AttrNumber *) ARR_DATA_PTR(arr))[0];
722}
int16 AttrNumber
Definition attnum.h:21

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, Assert, DatumGetArrayTypeP, elog, ERROR, fb(), GETSTRUCT(), and SysCacheGetAttrNotNull().

Referenced by ATExecAlterConstrInheritability(), CheckNNConstraintFetch(), dropconstraint_internal(), findNotNullConstraintAttnum(), MergeConstraintsIntoExisting(), pg_get_constraintdef_worker(), QueueNNConstraintValidation(), RelationGetNotNullConstraints(), and RemoveInheritance().

◆ findDomainNotNullConstraint()

HeapTuple findDomainNotNullConstraint ( Oid  typid)
extern

Definition at line 658 of file pg_constraint.c.

659{
662 retval = NULL;
663 SysScanDesc scan;
665
667 ScanKeyInit(&key,
670 ObjectIdGetDatum(typid));
672 true, NULL, 1, &key);
673
675 {
677
678 /*
679 * We're looking for a NOTNULL constraint that's marked validated.
680 */
681 if (con->contype != CONSTRAINT_NOTNULL)
682 continue;
683 if (!con->convalidated)
684 continue;
685
686 /* Found it */
687 retval = heap_copytuple(conTup);
688 break;
689 }
690
691 systable_endscan(scan);
693
694 return retval;
695}

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

Referenced by AlterDomainNotNull().

◆ FindFKPeriodOpers()

void FindFKPeriodOpers ( Oid  opclass,
Oid containedbyoperoid,
Oid aggedcontainedbyoperoid,
Oid intersectoperoid 
)
extern

Definition at line 1668 of file pg_constraint.c.

1672{
1673 Oid opfamily = InvalidOid;
1674 Oid opcintype = InvalidOid;
1676
1677 /* Make sure we have a range or multirange. */
1678 if (get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype))
1679 {
1680 if (opcintype != ANYRANGEOID && opcintype != ANYMULTIRANGEOID)
1681 ereport(ERROR,
1683 errmsg("invalid type for PERIOD part of foreign key"),
1684 errdetail("Only range and multirange are supported."));
1685
1686 }
1687 else
1688 elog(ERROR, "cache lookup failed for opclass %u", opclass);
1689
1690 /*
1691 * Look up the ContainedBy operator whose lhs and rhs are the opclass's
1692 * type. We use this to optimize RI checks: if the new value includes all
1693 * of the old value, then we can treat the attribute as if it didn't
1694 * change, and skip the RI check.
1695 */
1697 InvalidOid,
1700 &strat);
1701
1702 /*
1703 * Now look up the ContainedBy operator. Its left arg must be the type of
1704 * the column (or rather of the opclass). Its right arg must match the
1705 * return type of the support proc.
1706 */
1711 &strat);
1712
1713 switch (opcintype)
1714 {
1715 case ANYRANGEOID:
1717 break;
1718 case ANYMULTIRANGEOID:
1720 break;
1721 default:
1722 elog(ERROR, "unexpected opcintype: %u", opcintype);
1723 }
1724}
@ COMPARE_CONTAINED_BY
Definition cmptype.h:41
void GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype, Oid *opid, StrategyNumber *strat)
Definition indexcmds.c:2470
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
Definition lsyscache.c:1337
uint16 StrategyNumber
Definition stratnum.h:22

References COMPARE_CONTAINED_BY, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), get_opclass_opfamily_and_input_type(), GetOperatorFromCompareType(), and InvalidOid.

Referenced by ATAddForeignKeyConstraint(), and ri_LoadConstraintInfo().

◆ findNotNullConstraint()

HeapTuple findNotNullConstraint ( Oid  relid,
const char colname 
)
extern

Definition at line 642 of file pg_constraint.c.

643{
645
646 attnum = get_attnum(relid, colname);
648 return NULL;
649
650 return findNotNullConstraintAttnum(relid, attnum);
651}
#define InvalidAttrNumber
Definition attnum.h:23
AttrNumber get_attnum(Oid relid, const char *attname)
Definition lsyscache.c:934

References attnum, fb(), findNotNullConstraintAttnum(), get_attnum(), and InvalidAttrNumber.

Referenced by ATExecAlterConstrInheritability(), ATPrepAddPrimaryKey(), dropconstraint_internal(), and QueueNNConstraintValidation().

◆ findNotNullConstraintAttnum()

HeapTuple findNotNullConstraintAttnum ( Oid  relid,
AttrNumber  attnum 
)
extern

Definition at line 592 of file pg_constraint.c.

593{
596 retval = NULL;
597 SysScanDesc scan;
599
601 ScanKeyInit(&key,
604 ObjectIdGetDatum(relid));
606 true, NULL, 1, &key);
607
609 {
612
613 /*
614 * We're looking for a NOTNULL constraint with the column we're
615 * looking for as the sole element in conkey.
616 */
617 if (con->contype != CONSTRAINT_NOTNULL)
618 continue;
619
621 if (conkey != attnum)
622 continue;
623
624 /* Found it */
625 retval = heap_copytuple(conTup);
626 break;
627 }
628
629 systable_endscan(scan);
631
632 return retval;
633}
AttrNumber extractNotNullColumn(HeapTuple constrTup)

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

Referenced by AdjustNotNullInheritance(), ATExecAddIdentity(), ATExecDropNotNull(), ATExecSetNotNull(), findNotNullConstraint(), and MergeAttributesIntoExisting().

◆ get_domain_constraint_oid()

Oid get_domain_constraint_oid ( Oid  typid,
const char conname,
bool  missing_ok 
)
extern

Definition at line 1393 of file pg_constraint.c.

1394{
1396 HeapTuple tuple;
1397 SysScanDesc scan;
1398 ScanKeyData skey[3];
1400
1402
1403 ScanKeyInit(&skey[0],
1407 ScanKeyInit(&skey[1],
1410 ObjectIdGetDatum(typid));
1411 ScanKeyInit(&skey[2],
1414 CStringGetDatum(conname));
1415
1417 NULL, 3, skey);
1418
1419 /* There can be at most one matching row */
1420 if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1421 conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1422
1423 systable_endscan(scan);
1424
1425 /* If no such constraint exists, complain */
1426 if (!OidIsValid(conOid) && !missing_ok)
1427 ereport(ERROR,
1429 errmsg("constraint \"%s\" for domain %s does not exist",
1430 conname, format_type_be(typid))));
1431
1433
1434 return conOid;
1435}
char * format_type_be(Oid type_oid)

References AccessShareLock, BTEqualStrategyNumber, CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, fb(), format_type_be(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by get_object_address(), and rename_constraint_internal().

◆ get_primary_key_attnos()

Bitmapset * get_primary_key_attnos ( Oid  relid,
bool  deferrableOk,
Oid constraintOid 
)
extern

Definition at line 1452 of file pg_constraint.c.

1453{
1456 HeapTuple tuple;
1457 SysScanDesc scan;
1458 ScanKeyData skey[1];
1459
1460 /* Set *constraintOid, to avoid complaints about uninitialized vars */
1462
1463 /* Scan pg_constraint for constraints of the target rel */
1465
1466 ScanKeyInit(&skey[0],
1469 ObjectIdGetDatum(relid));
1470
1472 NULL, 1, skey);
1473
1474 while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1475 {
1477 Datum adatum;
1478 bool isNull;
1479 ArrayType *arr;
1480 int16 *attnums;
1481 int numkeys;
1482 int i;
1483
1484 /* Skip constraints that are not PRIMARY KEYs */
1485 if (con->contype != CONSTRAINT_PRIMARY)
1486 continue;
1487
1488 /*
1489 * If the primary key is deferrable, but we've been instructed to
1490 * ignore deferrable constraints, then we might as well give up
1491 * searching, since there can only be a single primary key on a table.
1492 */
1493 if (con->condeferrable && !deferrableOk)
1494 break;
1495
1496 /* Extract the conkey array, ie, attnums of PK's columns */
1499 if (isNull)
1500 elog(ERROR, "null conkey for constraint %u",
1501 ((Form_pg_constraint) GETSTRUCT(tuple))->oid);
1502 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1503 numkeys = ARR_DIMS(arr)[0];
1504 if (ARR_NDIM(arr) != 1 ||
1505 numkeys < 0 ||
1506 ARR_HASNULL(arr) ||
1507 ARR_ELEMTYPE(arr) != INT2OID)
1508 elog(ERROR, "conkey is not a 1-D smallint array");
1509 attnums = (int16 *) ARR_DATA_PTR(arr);
1510
1511 /* Construct the result value */
1512 for (i = 0; i < numkeys; i++)
1513 {
1516 }
1517 *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1518
1519 /* No need to search further */
1520 break;
1521 }
1522
1523 systable_endscan(scan);
1524
1526
1527 return pkattnos;
1528}
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, DatumGetArrayTypeP, elog, ERROR, fb(), FirstLowInvalidHeapAttributeNumber, GETSTRUCT(), heap_getattr(), HeapTupleIsValid, i, InvalidOid, ObjectIdGetDatum(), RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by check_functional_grouping().

◆ get_relation_constraint_attnos()

Bitmapset * get_relation_constraint_attnos ( Oid  relid,
const char conname,
bool  missing_ok,
Oid constraintOid 
)
extern

Definition at line 1257 of file pg_constraint.c.

1259{
1262 HeapTuple tuple;
1263 SysScanDesc scan;
1264 ScanKeyData skey[3];
1265
1266 /* Set *constraintOid, to avoid complaints about uninitialized vars */
1268
1270
1271 ScanKeyInit(&skey[0],
1274 ObjectIdGetDatum(relid));
1275 ScanKeyInit(&skey[1],
1279 ScanKeyInit(&skey[2],
1282 CStringGetDatum(conname));
1283
1285 NULL, 3, skey);
1286
1287 /* There can be at most one matching row */
1288 if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1289 {
1290 Datum adatum;
1291 bool isNull;
1292
1293 *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1294
1295 /* Extract the conkey array, ie, attnums of constrained columns */
1298 if (!isNull)
1299 {
1300 ArrayType *arr;
1301 int numcols;
1302 int16 *attnums;
1303 int i;
1304
1305 arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1306 numcols = ARR_DIMS(arr)[0];
1307 if (ARR_NDIM(arr) != 1 ||
1308 numcols < 0 ||
1309 ARR_HASNULL(arr) ||
1310 ARR_ELEMTYPE(arr) != INT2OID)
1311 elog(ERROR, "conkey is not a 1-D smallint array");
1312 attnums = (int16 *) ARR_DATA_PTR(arr);
1313
1314 /* Construct the result value */
1315 for (i = 0; i < numcols; i++)
1316 {
1319 }
1320 }
1321 }
1322
1323 systable_endscan(scan);
1324
1325 /* If no such constraint exists, complain */
1326 if (!OidIsValid(*constraintOid) && !missing_ok)
1327 ereport(ERROR,
1329 errmsg("constraint \"%s\" for table \"%s\" does not exist",
1330 conname, get_rel_name(relid))));
1331
1333
1334 return conattnos;
1335}

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, CStringGetDatum(), DatumGetArrayTypeP, elog, ereport, errcode(), errmsg(), ERROR, fb(), FirstLowInvalidHeapAttributeNumber, get_rel_name(), GETSTRUCT(), heap_getattr(), HeapTupleIsValid, i, InvalidOid, ObjectIdGetDatum(), OidIsValid, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by transformOnConflictArbiter().

◆ get_relation_constraint_oid()

Oid get_relation_constraint_oid ( Oid  relid,
const char conname,
bool  missing_ok 
)
extern

Definition at line 1200 of file pg_constraint.c.

1201{
1203 HeapTuple tuple;
1204 SysScanDesc scan;
1205 ScanKeyData skey[3];
1207
1209
1210 ScanKeyInit(&skey[0],
1213 ObjectIdGetDatum(relid));
1214 ScanKeyInit(&skey[1],
1218 ScanKeyInit(&skey[2],
1221 CStringGetDatum(conname));
1222
1224 NULL, 3, skey);
1225
1226 /* There can be at most one matching row */
1227 if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1228 conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1229
1230 systable_endscan(scan);
1231
1232 /* If no such constraint exists, complain */
1233 if (!OidIsValid(conOid) && !missing_ok)
1234 ereport(ERROR,
1236 errmsg("constraint \"%s\" for table \"%s\" does not exist",
1237 conname, get_rel_name(relid))));
1238
1240
1241 return conOid;
1242}

References AccessShareLock, BTEqualStrategyNumber, CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, fb(), get_rel_name(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by expandTableLikeClause(), get_object_address_relobject(), rename_constraint_internal(), and transformTableLikeClause().

◆ get_relation_idx_constraint_oid()

Oid get_relation_idx_constraint_oid ( Oid  relationId,
Oid  indexId 
)
extern

◆ MAKE_SYSCACHE()

MAKE_SYSCACHE ( CONSTROID  ,
pg_constraint_oid_index  ,
16   
)

◆ RelationGetNotNullConstraints()

List * RelationGetNotNullConstraints ( Oid  relid,
bool  cooked,
bool  include_noinh 
)
extern

Definition at line 834 of file pg_constraint.c.

835{
836 List *notnulls = NIL;
838 HeapTuple htup;
841
846 ObjectIdGetDatum(relid));
848 NULL, 1, &skey);
849
851 {
853 AttrNumber colnum;
854
855 if (conForm->contype != CONSTRAINT_NOTNULL)
856 continue;
857 if (conForm->connoinherit && !include_noinh)
858 continue;
859
860 colnum = extractNotNullColumn(htup);
861
862 if (cooked)
863 {
865
867
868 cooked->contype = CONSTR_NOTNULL;
869 cooked->conoid = conForm->oid;
870 cooked->name = pstrdup(NameStr(conForm->conname));
871 cooked->attnum = colnum;
872 cooked->expr = NULL;
873 cooked->is_enforced = true;
874 cooked->skip_validation = !conForm->convalidated;
875 cooked->is_local = true;
876 cooked->inhcount = 0;
877 cooked->is_no_inherit = conForm->connoinherit;
878
879 notnulls = lappend(notnulls, cooked);
880 }
881 else
882 {
883 Constraint *constr;
884
885 constr = makeNode(Constraint);
886 constr->contype = CONSTR_NOTNULL;
887 constr->conname = pstrdup(NameStr(conForm->conname));
888 constr->deferrable = false;
889 constr->initdeferred = false;
890 constr->location = -1;
891 constr->keys = list_make1(makeString(get_attname(relid, colnum,
892 false)));
893 constr->is_enforced = true;
894 constr->skip_validation = !conForm->convalidated;
895 constr->initially_valid = conForm->convalidated;
896 constr->is_no_inherit = conForm->connoinherit;
897 notnulls = lappend(notnulls, constr);
898 }
899 }
900
903
904 return notnulls;
905}
#define palloc_object(type)
Definition fe_memutils.h:74
List * lappend(List *list, void *datum)
Definition list.c:339
char * pstrdup(const char *in)
Definition mcxt.c:1781
#define makeNode(_type_)
Definition nodes.h:161
@ CONSTR_NOTNULL
#define NIL
Definition pg_list.h:68
#define list_make1(x1)
Definition pg_list.h:212
bool initdeferred
ParseLoc location
List * keys
ConstrType contype
bool is_no_inherit
bool is_enforced
bool initially_valid
bool skip_validation
bool deferrable
char * conname
Definition pg_list.h:54
String * makeString(char *str)
Definition value.c:63

References AccessShareLock, BTEqualStrategyNumber, Constraint::conname, CONSTR_NOTNULL, Constraint::contype, Constraint::deferrable, extractNotNullColumn(), fb(), get_attname(), GETSTRUCT(), HeapTupleIsValid, Constraint::initdeferred, Constraint::initially_valid, Constraint::is_enforced, Constraint::is_no_inherit, Constraint::keys, lappend(), list_make1, Constraint::location, makeNode, makeString(), NameStr, NIL, ObjectIdGetDatum(), palloc_object, pstrdup(), ScanKeyInit(), Constraint::skip_validation, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by createTableConstraints(), MergeAttributes(), and transformTableLikeClause().

◆ RemoveConstraintById()

void RemoveConstraintById ( Oid  conId)
extern

Definition at line 912 of file pg_constraint.c.

913{
917
919
921 if (!HeapTupleIsValid(tup)) /* should not happen */
922 elog(ERROR, "cache lookup failed for constraint %u", conId);
924
925 /*
926 * Special processing depending on what the constraint is for.
927 */
928 if (OidIsValid(con->conrelid))
929 {
930 Relation rel;
931
932 /*
933 * If the constraint is for a relation, open and exclusive-lock the
934 * relation it's for.
935 */
936 rel = table_open(con->conrelid, AccessExclusiveLock);
937
938 /*
939 * We need to update the relchecks count if it is a check constraint
940 * being dropped. This update will force backends to rebuild relcache
941 * entries when we commit.
942 */
943 if (con->contype == CONSTRAINT_CHECK)
944 {
948
951 ObjectIdGetDatum(con->conrelid));
953 elog(ERROR, "cache lookup failed for relation %u",
954 con->conrelid);
956
957 if (classForm->relchecks > 0)
958 classForm->relchecks--;
959 else
960 /* should not happen */
961 elog(WARNING, "relation \"%s\" has relchecks = %d",
962 RelationGetRelationName(rel), classForm->relchecks);
963
965
967
969 }
970
971 /* Keep lock on constraint's rel until end of xact */
972 table_close(rel, NoLock);
973 }
974 else if (OidIsValid(con->contypid))
975 {
976 /*
977 * XXX for now, do nothing special when dropping a domain constraint
978 *
979 * Probably there should be some form of locking on the domain type,
980 * but we have no such concept at the moment.
981 */
982 }
983 else
984 elog(ERROR, "constraint %u is not of a known type", conId);
985
986 /* Fry the constraint itself */
987 CatalogTupleDelete(conDesc, &tup->t_self);
988
989 /* Clean up */
992}
#define WARNING
Definition elog.h:36
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
#define NoLock
Definition lockdefs.h:34
#define AccessExclusiveLock
Definition lockdefs.h:43
FormData_pg_class * Form_pg_class
Definition pg_class.h:156
#define RelationGetRelationName(relation)
Definition rel.h:548
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91

References AccessExclusiveLock, CatalogTupleDelete(), CatalogTupleUpdate(), elog, ERROR, fb(), GETSTRUCT(), heap_freetuple(), HeapTupleIsValid, NoLock, ObjectIdGetDatum(), OidIsValid, RelationGetRelationName, ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), SearchSysCacheCopy1, table_close(), table_open(), and WARNING.

Referenced by doDeletion().

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char newname 
)
extern

Definition at line 1005 of file pg_constraint.c.

1006{
1008 HeapTuple tuple;
1010
1012
1014 if (!HeapTupleIsValid(tuple))
1015 elog(ERROR, "cache lookup failed for constraint %u", conId);
1016 con = (Form_pg_constraint) GETSTRUCT(tuple);
1017
1018 /*
1019 * For user-friendliness, check whether the name is already in use.
1020 */
1021 if (OidIsValid(con->conrelid) &&
1023 con->conrelid,
1024 newname))
1025 ereport(ERROR,
1027 errmsg("constraint \"%s\" for relation \"%s\" already exists",
1028 newname, get_rel_name(con->conrelid))));
1029 if (OidIsValid(con->contypid) &&
1031 con->contypid,
1032 newname))
1033 ereport(ERROR,
1035 errmsg("constraint \"%s\" for domain %s already exists",
1036 newname, format_type_be(con->contypid))));
1037
1038 /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
1039 namestrcpy(&(con->conname), newname);
1040
1041 CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
1042
1044
1045 heap_freetuple(tuple);
1047}
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30

References CatalogTupleUpdate(), CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameIsUsed(), elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, fb(), format_type_be(), get_rel_name(), GETSTRUCT(), heap_freetuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, namestrcpy(), ObjectIdGetDatum(), OidIsValid, RowExclusiveLock, SearchSysCacheCopy1, HeapTupleData::t_self, table_close(), and table_open().

Referenced by rename_constraint_internal(), and RenameRelationInternal().

Variable Documentation

◆ FormData_pg_constraint

FormData_pg_constraint

Definition at line 168 of file pg_constraint.h.