34 #include "utils/fmgroids.h"
52 Oid constraintNamespace,
59 const int16 *constraintKey,
61 int constraintNTotalKeys,
65 const int16 *foreignKey,
70 char foreignUpdateType,
71 char foreignDeleteType,
72 const int16 *fkDeleteSetCols,
73 int numFkDeleteSetCols,
74 char foreignMatchType,
87 bool nulls[Natts_pg_constraint];
110 if (constraintNKeys > 0)
115 for (
i = 0;
i < constraintNKeys;
i++)
122 if (foreignNKeys > 0)
127 for (
i = 0;
i < foreignNKeys;
i++)
130 for (
i = 0;
i < foreignNKeys;
i++)
133 for (
i = 0;
i < foreignNKeys;
i++)
136 for (
i = 0;
i < foreignNKeys;
i++)
140 if (numFkDeleteSetCols > 0)
142 for (
i = 0;
i < numFkDeleteSetCols;
i++)
147 confdelsetcolsArray = NULL;
152 conpfeqopArray = NULL;
153 conppeqopArray = NULL;
154 conffeqopArray = NULL;
155 confdelsetcolsArray = NULL;
163 for (
i = 0;
i < constraintNKeys;
i++)
168 conexclopArray = NULL;
171 for (
i = 0;
i < Natts_pg_constraint;
i++)
178 Anum_pg_constraint_oid);
202 nulls[Anum_pg_constraint_conkey - 1] =
true;
207 nulls[Anum_pg_constraint_confkey - 1] =
true;
212 nulls[Anum_pg_constraint_conpfeqop - 1] =
true;
217 nulls[Anum_pg_constraint_conppeqop - 1] =
true;
222 nulls[Anum_pg_constraint_conffeqop - 1] =
true;
224 if (confdelsetcolsArray)
227 nulls[Anum_pg_constraint_confdelsetcols - 1] =
true;
232 nulls[Anum_pg_constraint_conexclop - 1] =
true;
237 nulls[Anum_pg_constraint_conbin - 1] =
true;
258 if (constraintNTotalKeys > 0)
260 for (
i = 0;
i < constraintNTotalKeys;
i++)
300 if (foreignNKeys > 0)
302 for (
i = 0;
i < foreignNKeys;
i++)
305 foreignRelId, foreignKey[
i]);
316 if (
OidIsValid(indexRelId) && constraintType == CONSTRAINT_FOREIGN)
330 if (foreignNKeys > 0)
340 oprobject.
classId = OperatorRelationId;
343 for (
i = 0;
i < foreignNKeys;
i++)
347 if (ppEqOp[
i] != pfEqOp[
i])
352 if (ffEqOp[
i] != pfEqOp[
i])
414 Anum_pg_constraint_conrelid,
419 Anum_pg_constraint_contypid,
424 Anum_pg_constraint_conname,
429 true, NULL, 3, skey);
458 Anum_pg_constraint_conname,
463 Anum_pg_constraint_connamespace,
507 char *conname = NULL;
528 if (strcmp((
char *)
lfirst(l), conname) == 0)
538 Anum_pg_constraint_conname,
543 Anum_pg_constraint_connamespace,
587 Anum_pg_constraint_conrelid,
591 true, NULL, 1, &
key);
602 if (con->contype != CONSTRAINT_NOTNULL)
604 if (!con->convalidated)
649 Anum_pg_constraint_contypid,
653 true, NULL, 1, &
key);
662 if (con->contype != CONSTRAINT_NOTNULL)
664 if (!con->convalidated)
693 Anum_pg_constraint_conkey);
699 elog(
ERROR,
"conkey is not a 1-D smallint array");
744 if (is_no_inherit && !conform->connoinherit)
746 errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
747 errmsg(
"cannot change NO INHERIT status of inherited NOT NULL constraint \"%s\" on relation \"%s\"",
755 if (!is_no_inherit && conform->connoinherit)
757 conform->connoinherit =
false;
762 conform->coninhcount += count;
765 if (conform->coninhcount < 0)
766 elog(
ERROR,
"invalid inhcount %d for constraint \"%s\" on relation \"%s\"",
767 conform->coninhcount,
NameStr(conform->conname),
775 if (conform->coninhcount == 0)
776 conform->conislocal =
true;
820 errcode(ERRCODE_DATATYPE_MISMATCH),
821 errmsg(
"column \"%s\" in child table must be marked NOT NULL",
826 conform->coninhcount += count;
827 if (conform->coninhcount < 0)
828 elog(
ERROR,
"invalid inhcount %d for constraint \"%s\" on relation \"%s\"",
829 conform->coninhcount,
NameStr(conform->conname),
837 if (conform->coninhcount == 0)
838 conform->conislocal =
true;
868 Anum_pg_constraint_conrelid,
879 if (conForm->contype != CONSTRAINT_NOTNULL)
881 if (conForm->connoinherit)
901 notnulls =
lappend(notnulls, cooked);
917 notnulls =
lappend(notnulls, constr);
937 bool dropping_pk =
false;
938 List *unconstrained_cols =
NIL;
944 elog(
ERROR,
"cache lookup failed for constraint %u", conId);
967 if (con->contype == CONSTRAINT_CHECK)
977 elog(
ERROR,
"cache lookup failed for relation %u",
981 if (classForm->relchecks == 0)
982 elog(
ERROR,
"relation \"%s\" has relchecks = 0",
984 classForm->relchecks--;
992 else if (con->contype == CONSTRAINT_NOTNULL)
996 else if (con->contype == CONSTRAINT_PRIMARY)
1009 elog(
ERROR,
"null conkey for constraint %u", con->oid);
1016 elog(
ERROR,
"conkey is not a 1-D smallint array");
1019 for (
int i = 0;
i < numkeys;
i++)
1020 unconstrained_cols =
lappend_int(unconstrained_cols, attnums[
i]);
1036 elog(
ERROR,
"constraint %u is not of a known type", conId);
1046 if (unconstrained_cols !=
NIL)
1063 pkcols = dropping_pk ? NULL :
1067 foreach(lc, unconstrained_cols)
1081 elog(
ERROR,
"cache lookup failed for attribute %d of relation %u",
1101 if (attForm->attidentity !=
'\0')
1110 if (attForm->attnotnull)
1112 attForm->attnotnull =
false;
1147 elog(
ERROR,
"cache lookup failed for constraint %u", conId);
1159 errmsg(
"constraint \"%s\" for relation \"%s\" already exists",
1167 errmsg(
"constraint \"%s\" for domain %s already exists",
1200 Anum_pg_constraint_conrelid,
1204 Anum_pg_constraint_contypid,
1222 if (conform->connamespace == oldNspId && oldNspId != newNspId)
1227 conform->connamespace = newNspId;
1272 elog(
ERROR,
"cache lookup failed for constraint %u", childConstrId);
1278 Assert(constrForm->coninhcount == 0);
1280 elog(
ERROR,
"constraint %u already has a parent constraint",
1283 constrForm->conislocal =
false;
1284 constrForm->coninhcount++;
1285 if (constrForm->coninhcount < 0)
1287 errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1288 errmsg(
"too many inheritance parents"));
1289 constrForm->conparentid = parentConstrId;
1303 constrForm->coninhcount--;
1304 constrForm->conislocal =
true;
1308 Assert(constrForm->coninhcount == 0);
1313 ConstraintRelationId,
1342 Anum_pg_constraint_conrelid,
1346 Anum_pg_constraint_contypid,
1350 Anum_pg_constraint_conname,
1366 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1367 errmsg(
"constraint \"%s\" for table \"%s\" does not exist",
1389 bool missing_ok,
Oid *constraintOid)
1403 Anum_pg_constraint_conrelid,
1407 Anum_pg_constraint_contypid,
1411 Anum_pg_constraint_conname,
1427 adatum =
heap_getattr(tuple, Anum_pg_constraint_conkey,
1442 elog(
ERROR,
"conkey is not a 1-D smallint array");
1446 for (
i = 0;
i < numcols;
i++)
1457 if (!
OidIsValid(*constraintOid) && !missing_ok)
1459 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1460 errmsg(
"constraint \"%s\" for table \"%s\" does not exist",
1488 Anum_pg_constraint_conrelid,
1493 true, NULL, 1, &
key);
1501 if (constrForm->contype != CONSTRAINT_PRIMARY &&
1502 constrForm->contype != CONSTRAINT_UNIQUE &&
1503 constrForm->contype != CONSTRAINT_EXCLUSION)
1506 if (constrForm->conindid == indexId)
1508 constraintId = constrForm->oid;
1515 return constraintId;
1535 Anum_pg_constraint_conrelid,
1539 Anum_pg_constraint_contypid,
1543 Anum_pg_constraint_conname,
1559 (
errcode(ERRCODE_UNDEFINED_OBJECT),
1560 errmsg(
"constraint \"%s\" for domain %s does not exist",
1598 Anum_pg_constraint_conrelid,
1616 if (con->contype != CONSTRAINT_PRIMARY)
1624 if (con->condeferrable && !deferrableOk)
1628 adatum =
heap_getattr(tuple, Anum_pg_constraint_conkey,
1631 elog(
ERROR,
"null conkey for constraint %u",
1639 elog(
ERROR,
"conkey is not a 1-D smallint array");
1643 for (
i = 0;
i < numkeys;
i++)
1671 Oid *pf_eq_oprs,
Oid *pp_eq_oprs,
Oid *ff_eq_oprs,
1672 int *num_fk_del_set_cols,
AttrNumber *fk_del_set_cols)
1685 Anum_pg_constraint_conkey);
1690 elog(
ERROR,
"conkey is not a 1-D smallint array");
1693 elog(
ERROR,
"foreign key constraint cannot have %d columns", numkeys);
1699 Anum_pg_constraint_confkey);
1705 elog(
ERROR,
"confkey is not a 1-D smallint array");
1713 Anum_pg_constraint_conpfeqop);
1720 elog(
ERROR,
"conpfeqop is not a 1-D Oid array");
1729 Anum_pg_constraint_conppeqop);
1735 elog(
ERROR,
"conppeqop is not a 1-D Oid array");
1744 Anum_pg_constraint_conffeqop);
1750 elog(
ERROR,
"conffeqop is not a 1-D Oid array");
1756 if (fk_del_set_cols)
1759 Anum_pg_constraint_confdelsetcols, &isNull);
1762 *num_fk_del_set_cols = 0;
1766 int num_delete_cols;
1772 elog(
ERROR,
"confdelsetcols is not a 1-D smallint array");
1773 num_delete_cols =
ARR_DIMS(arr)[0];
1778 *num_fk_del_set_cols = num_delete_cols;
1798 Oid *containedbyoperoid,
1799 Oid *aggedcontainedbyoperoid)
1808 if (opcintype != ANYRANGEOID && opcintype != ANYMULTIRANGEOID)
1810 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1811 errmsg(
"invalid type for PERIOD part of foreign key"),
1812 errdetail(
"Only range and multirange are supported."));
1816 elog(
ERROR,
"cache lookup failed for opclass %u", opclass);
1838 aggedcontainedbyoperoid,
1860 List *grouping_columns,
1861 List **constraintDeps)
1870 if (pkattnos == NULL)
1874 groupbyattnos = NULL;
1875 foreach(gl, grouping_columns)
1880 gvar->
varno == varno &&
1889 *constraintDeps =
lappend_oid(*constraintDeps, constraintOid);
#define DatumGetArrayTypeP(X)
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
int bms_next_member(const Bitmapset *a, int prevbit)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
bool bms_is_member(int x, const Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
static Datum values[MAXATTR]
#define CStringGetTextDatum(s)
#define Assert(condition)
#define OidIsValid(objectId)
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
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)
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
ObjectAddresses * new_object_addresses(void)
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
void free_object_addresses(ObjectAddresses *addrs)
@ DEPENDENCY_PARTITION_PRI
@ DEPENDENCY_PARTITION_SEC
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void systable_endscan(SysScanDesc sysscan)
HeapTuple systable_getnext(SysScanDesc sysscan)
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
HeapTuple heap_copytuple(HeapTuple tuple)
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
void heap_freetuple(HeapTuple htup)
#define HeapTupleIsValid(tuple)
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
char * makeObjectName(const char *name1, const char *name2, const char *label)
void GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype, Oid *opid, StrategyNumber *strat)
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
List * lappend_oid(List *list, Oid datum)
#define AccessExclusiveLock
AttrNumber get_attnum(Oid relid, const char *attname)
bool get_opclass_opfamily_and_input_type(Oid opclass, Oid *opfamily, Oid *opcintype)
char * get_rel_name(Oid relid)
char * get_attname(Oid relid, AttrNumber attnum, bool missing_ok)
char * pstrdup(const char *in)
void pfree(void *pointer)
void namestrcpy(Name name, const char *str)
#define IsA(nodeptr, _type_)
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
#define ObjectAddressSet(addr, class_id, object_id)
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
FormData_pg_attribute * Form_pg_attribute
FormData_pg_class * Form_pg_class
char * ChooseConstraintName(const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)
HeapTuple findNotNullConstraint(Oid relid, const char *colname)
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
int AdjustNotNullInheritance1(Oid relid, AttrNumber attnum, int count, bool is_no_inherit)
Oid CreateConstraintEntry(const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, 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, int conInhCount, bool conNoInherit, bool conPeriod, bool is_internal)
void RemoveConstraintById(Oid conId)
void RenameConstraintById(Oid conId, const char *newname)
Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId)
void ConstraintSetParentConstraint(Oid childConstrId, Oid parentConstrId, Oid childTableId)
List * RelationGetNotNullConstraints(Oid relid, bool cooked)
HeapTuple findDomainNotNullConstraint(Oid typid)
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 AdjustNotNullInheritance(Oid relid, Bitmapset *columns, int count)
HeapTuple findNotNullConstraintAttnum(Oid relid, AttrNumber attnum)
void AlterConstraintNamespaces(Oid ownerId, Oid oldNspId, Oid newNspId, bool isType, ObjectAddresses *objsMoved)
bool ConstraintNameExists(const char *conname, Oid namespaceid)
bool check_functional_grouping(Oid relid, Index varno, Index varlevelsup, List *grouping_columns, List **constraintDeps)
void FindFKPeriodOpers(Oid opclass, Oid *containedbyoperoid, Oid *aggedcontainedbyoperoid)
Oid get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok)
AttrNumber extractNotNullColumn(HeapTuple constrTup)
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
Oid get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)
Bitmapset * get_relation_constraint_attnos(Oid relid, const char *conname, bool missing_ok, Oid *constraintOid)
FormData_pg_constraint * Form_pg_constraint
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
#define list_make1_int(x1)
size_t strlcpy(char *dst, const char *src, size_t siz)
static Datum PointerGetDatum(const void *X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum NameGetDatum(const NameData *X)
static Pointer DatumGetPointer(Datum X)
static Datum CStringGetDatum(const char *X)
static Datum CharGetDatum(char X)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
@ INDEX_ATTR_BITMAP_PRIMARY_KEY
@ INDEX_ATTR_BITMAP_IDENTITY_KEY
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
#define BTEqualStrategyNumber
#define RTContainedByStrategyNumber
#define ERRCODE_DUPLICATE_OBJECT
#define FirstLowInvalidHeapAttributeNumber
HeapTuple SearchSysCacheCopyAttNum(Oid relid, int16 attnum)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
#define SearchSysCacheCopy1(cacheId, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
String * makeString(char *str)
void CommandCounterIncrement(void)