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 enum ConstraintCategory ConstraintCategory
 

Enumerations

enum  ConstraintCategory { CONSTRAINT_RELATION , CONSTRAINT_DOMAIN , CONSTRAINT_ASSERTION }
 

Functions

BEGIN_CATALOG_STRUCT 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)
 
char * ChooseConstraintName (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)
 
List * RelationGetNotNullConstraints (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)
 
Bitmapset * get_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)
 
Bitmapset * get_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

END_CATALOG_STRUCT typedef FormData_pg_constraint * Form_pg_constraint
 
 FormData_pg_constraint
 

Typedef Documentation

◆ ConstraintCategory

Enumeration Type Documentation

◆ ConstraintCategory

Enumerator
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 217 of file pg_constraint.h.

218{
221 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:894
int errcode(int sqlerrcode)
Definition elog.c:875
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
#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:2242
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
Definition lsyscache.c:1053
static char * errmsg
int16 attnum
HeapTuple findNotNullConstraintAttnum(Oid relid, AttrNumber attnum)
END_CATALOG_STRUCT typedef 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(), Form_pg_constraint, 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:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
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:686
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
#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(), Form_pg_constraint, 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()

Definition at line 33 of file pg_constraint.h.

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

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:547
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition bitmapset.c:934
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
#define IsA(nodeptr, _type_)
Definition nodes.h:162
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:2556
#define AccessShareLock
Definition lockdefs.h:36
void pfree(void *pointer)
Definition mcxt.c:1619
static char * label
#define NAMEDATALEN
#define snprintf
Definition port.h:261
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383

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:1002
#define OidIsValid(objectId)
Definition c.h:917
@ DEPENDENCY_PARTITION_PRI
Definition dependency.h:36
@ DEPENDENCY_PARTITION_SEC
Definition dependency.h:37
#define elog(elevel,...)
Definition elog.h:228
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition pg_depend.c:51
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition pg_depend.c:364
ItemPointerData t_self
Definition htup.h:65
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221

References Assert, CatalogTupleUpdate(), deleteDependencyRecordsForClass(), DEPENDENCY_PARTITION_PRI, DEPENDENCY_PARTITION_SEC, elog, ereport, errcode(), errmsg, ERROR, fb(), Form_pg_constraint, 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:190
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define Max(x, y)
Definition c.h:1125
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition catalog.c:475
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:1025
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
int i
Definition isn.c:77
void * palloc(Size size)
Definition mcxt.c:1390
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 Int16GetDatum(int16 X)
Definition postgres.h:172
static Datum BoolGetDatum(bool X)
Definition postgres.h:112
static Datum NameGetDatum(const NameData *X)
Definition postgres.h:406
uint64_t Datum
Definition postgres.h:70
#define PointerGetDatum(X)
Definition postgres.h:354
static Datum CharGetDatum(char X)
Definition postgres.h:132
#define RelationGetDescr(relation)
Definition rel.h:542

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
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define INDEX_MAX_KEYS
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596

References ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, DatumGetArrayTypeP, DatumGetPointer(), elog, ERROR, fb(), INDEX_MAX_KEYS, memcpy(), 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(), Form_pg_constraint, 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(), Form_pg_constraint, 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:2483
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
Definition lsyscache.c:1487
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:1084

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(), Form_pg_constraint, 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(), Form_pg_constraint, 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, Form_pg_constraint, 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, Form_pg_constraint, 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(), Form_pg_constraint, get_rel_name(), GETSTRUCT(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ATExecAlterCheckConstrEnforceability(), 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:89
List * lappend(List *list, void *datum)
Definition list.c:339
char * pstrdup(const char *in)
Definition mcxt.c:1910
#define makeNode(_type_)
Definition nodes.h:159
@ CONSTR_NOTNULL
#define NIL
Definition pg_list.h:68
#define list_make1(x1)
Definition pg_list.h:244
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(), Form_pg_constraint, 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:37
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1372
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:160
#define RelationGetRelationName(relation)
Definition rel.h:550
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91

References AccessExclusiveLock, CatalogTupleDelete(), CatalogTupleUpdate(), elog, ERROR, fb(), Form_pg_constraint, 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(), Form_pg_constraint, 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

◆ Form_pg_constraint

Definition at line 179 of file pg_constraint.h.

Referenced by AdjustNotNullInheritance(), AfterTriggerSetState(), AlterConstraintNamespaces(), AlterConstrDeferrabilityRecurse(), AlterConstrUpdateConstraintEntry(), AlterDomainDropConstraint(), AlterDomainNotNull(), AlterDomainValidateConstraint(), AlterFKConstrEnforceabilityRecurse(), ATCheckCheckConstrHasEnforcedParent(), ATDetachCheckNoForeignKeyRefs(), ATExecAddIdentity(), ATExecAlterCheckConstrEnforceability(), ATExecAlterConstraint(), ATExecAlterConstraintInternal(), ATExecAlterConstrDeferrability(), ATExecAlterConstrInheritability(), ATExecAlterFKConstrEnforceability(), ATExecSetNotNull(), ATExecValidateConstraint(), ATPostAlterTypeCleanup(), ATPrepChangePersistence(), AttachPartitionForeignKey(), CacheInvalidateHeapTupleCommon(), check_object_ownership(), CheckNNConstraintFetch(), CloneFkReferenced(), CloneFkReferencing(), constraints_equivalent(), ConstraintSetParentConstraint(), copy_index_constraints(), decompile_conbin(), DetachPartitionFinalize(), dropconstraint_internal(), extractNotNullColumn(), findDomainNotNullConstraint(), findNotNullConstraintAttnum(), generateClonedIndexStmt(), get_constraint_index(), get_constraint_name(), get_constraint_type(), get_domain_constraint_oid(), get_primary_key_attnos(), get_relation_constraint_attnos(), get_relation_constraint_oid(), get_relation_idx_constraint_oid(), get_ri_constraint_root(), getConstraintTypeDescription(), getObjectDescription(), getObjectIdentityParts(), GetParentedForeignKeyRefs(), heap_truncate_find_FKs(), index_concurrently_swap(), load_domaintype_info(), MergeAttributesIntoExisting(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), pg_get_constraintdef_worker(), QueueCheckConstraintValidation(), QueueFKConstraintValidation(), QueueNNConstraintValidation(), RelationGetExclusionInfo(), RelationGetFKeyList(), RelationGetNotNullConstraints(), RememberWholeRowDependentForRebuilding(), RemoveConstraintById(), RemoveInheritance(), RemoveInheritedConstraint(), rename_constraint_internal(), RenameConstraintById(), ri_LoadConstraintInfo(), tryAttachPartitionForeignKey(), and verifyNotNullPKCompatible().

◆ FormData_pg_constraint

FormData_pg_constraint

Definition at line 170 of file pg_constraint.h.