PostgreSQL Source Code  git master
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 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 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 findDomainNotNullConstraint (Oid typid)
 
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)
 
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

Definition at line 165 of file pg_constraint.h.

Enumeration Type Documentation

◆ ConstraintCategory

Enumerator
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 203 of file pg_constraint.h.

204 {
207  CONSTRAINT_ASSERTION, /* for future expansion */
ConstraintCategory
@ CONSTRAINT_DOMAIN
@ CONSTRAINT_RELATION
@ CONSTRAINT_ASSERTION

Function Documentation

◆ AlterConstraintNamespaces()

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

Definition at line 754 of file pg_constraint.c.

756 {
757  Relation conRel;
758  ScanKeyData key[2];
759  SysScanDesc scan;
760  HeapTuple tup;
761 
762  conRel = table_open(ConstraintRelationId, RowExclusiveLock);
763 
764  ScanKeyInit(&key[0],
765  Anum_pg_constraint_conrelid,
766  BTEqualStrategyNumber, F_OIDEQ,
767  ObjectIdGetDatum(isType ? InvalidOid : ownerId));
768  ScanKeyInit(&key[1],
769  Anum_pg_constraint_contypid,
770  BTEqualStrategyNumber, F_OIDEQ,
771  ObjectIdGetDatum(isType ? ownerId : InvalidOid));
772 
773  scan = systable_beginscan(conRel, ConstraintRelidTypidNameIndexId, true,
774  NULL, 2, key);
775 
776  while (HeapTupleIsValid((tup = systable_getnext(scan))))
777  {
779  ObjectAddress thisobj;
780 
781  ObjectAddressSet(thisobj, ConstraintRelationId, conform->oid);
782 
783  if (object_address_present(&thisobj, objsMoved))
784  continue;
785 
786  /* Don't update if the object is already part of the namespace */
787  if (conform->connamespace == oldNspId && oldNspId != newNspId)
788  {
789  tup = heap_copytuple(tup);
790  conform = (Form_pg_constraint) GETSTRUCT(tup);
791 
792  conform->connamespace = newNspId;
793 
794  CatalogTupleUpdate(conRel, &tup->t_self, tup);
795 
796  /*
797  * Note: currently, the constraint will not have its own
798  * dependency on the namespace, so we don't need to do
799  * changeDependencyFor().
800  */
801  }
802 
803  InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0);
804 
805  add_exact_object_address(&thisobj, objsMoved);
806  }
807 
808  systable_endscan(scan);
809 
810  table_close(conRel, RowExclusiveLock);
811 }
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2593
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2533
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:596
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:503
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:384
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:776
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:313
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:197
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
FormData_pg_constraint * Form_pg_constraint
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
#define InvalidOid
Definition: postgres_ext.h:36
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31
ItemPointerData t_self
Definition: htup.h:65
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References add_exact_object_address(), BTEqualStrategyNumber, CatalogTupleUpdate(), GETSTRUCT, heap_copytuple(), HeapTupleIsValid, InvalidOid, InvokeObjectPostAlterHook, sort-test::key, object_address_present(), ObjectAddressSet, ObjectAddress::objectId, ObjectIdGetDatum(), RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, 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 convalidated; /* constraint has been validated? */
55 
56  /*
57  * conrelid and conkey are only meaningful if the constraint applies to a
58  * specific relation (this excludes domain constraints and assertions).
59  * Otherwise conrelid is 0 and conkey is NULL.
60  */
61  Oid conrelid BKI_LOOKUP_OPT(pg_class); /* relation this
62  * constraint constrains */
63 
64  /*
65  * contypid links to the pg_type row for a domain if this is a domain
66  * constraint. Otherwise it's 0.
67  *
68  * For SQL-style global ASSERTIONs, both conrelid and contypid would be
69  * zero. This is not presently supported, however.
70  */
71  Oid contypid BKI_LOOKUP_OPT(pg_type); /* domain this constraint
72  * constrains */
73 
74  /*
75  * conindid links to the index supporting the constraint, if any;
76  * otherwise it's 0. This is used for unique, primary-key, and exclusion
77  * constraints, and less obviously for foreign-key constraints (where the
78  * index is a unique index on the referenced relation's referenced
79  * columns). Notice that the index is on conrelid in the first case but
80  * confrelid in the second.
81  */
82  Oid conindid BKI_LOOKUP_OPT(pg_class); /* index supporting this
83  * constraint */
84 
85  /*
86  * If this constraint is on a partition inherited from a partitioned
87  * table, this is the OID of the corresponding constraint in the parent.
88  */
89  Oid conparentid BKI_LOOKUP_OPT(pg_constraint);
90 
91  /*
92  * These fields, plus confkey, are only meaningful for a foreign-key
93  * constraint. Otherwise confrelid is 0 and the char fields are spaces.
94  */
95  Oid confrelid BKI_LOOKUP_OPT(pg_class); /* relation referenced by
96  * foreign key */
97  char confupdtype; /* foreign key's ON UPDATE action */
98  char confdeltype; /* foreign key's ON DELETE action */
99  char confmatchtype; /* foreign key's match type */
100 
101  /* Has a local definition (hence, do not drop when coninhcount is 0) */
102  bool conislocal;
103 
104  /* Number of times inherited from direct parent relation(s) */
105  int16 coninhcount;
106 
107  /* Has a local definition and cannot be inherited */
108  bool connoinherit;
109 
110 #ifdef CATALOG_VARLEN /* variable-length fields start here */
111 
112  /*
113  * Columns of conrelid that the constraint applies to, if known (this is
114  * NULL for trigger constraints)
115  */
116  int16 conkey[1];
117 
118  /*
119  * If a foreign key, the referenced columns of confrelid
120  */
121  int16 confkey[1];
122 
123  /*
124  * If a foreign key, the OIDs of the PK = FK equality operators for each
125  * column of the constraint
126  */
127  Oid conpfeqop[1] BKI_LOOKUP(pg_operator);
128 
129  /*
130  * If a foreign key, the OIDs of the PK = PK equality operators for each
131  * column of the constraint (i.e., equality for the referenced columns)
132  */
133  Oid conppeqop[1] BKI_LOOKUP(pg_operator);
134 
135  /*
136  * If a foreign key, the OIDs of the FK = FK equality operators for each
137  * column of the constraint (i.e., equality for the referencing columns)
138  */
139  Oid conffeqop[1] BKI_LOOKUP(pg_operator);
140 
141  /*
142  * If a foreign key with an ON DELETE SET NULL/DEFAULT action, the subset
143  * of conkey to updated. If null, all columns are updated.
144  */
145  int16 confdelsetcols[1];
146 
147  /*
148  * If an exclusion constraint, the OIDs of the exclusion operators for
149  * each column of the constraint
150  */
151  Oid conexclop[1] BKI_LOOKUP(pg_operator);
152 
153  /*
154  * If a check constraint, nodeToString representation of expression
155  */
156  pg_node_tree conbin;
157 #endif
signed short int16
Definition: c.h:493
#define BKI_LOOKUP(catalog)
Definition: genbki.h:46
#define BKI_LOOKUP_OPT(catalog)
Definition: genbki.h:47
FormData_pg_constraint
unsigned int Oid
Definition: postgres_ext.h:31
Definition: c.h:741

References BKI_LOOKUP, and BKI_LOOKUP_OPT.

◆ check_functional_grouping()

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

Definition at line 1366 of file pg_constraint.c.

1370 {
1371  Bitmapset *pkattnos;
1372  Bitmapset *groupbyattnos;
1373  Oid constraintOid;
1374  ListCell *gl;
1375 
1376  /* If the rel has no PK, then we can't prove functional dependency */
1377  pkattnos = get_primary_key_attnos(relid, false, &constraintOid);
1378  if (pkattnos == NULL)
1379  return false;
1380 
1381  /* Identify all the rel's columns that appear in grouping_columns */
1382  groupbyattnos = NULL;
1383  foreach(gl, grouping_columns)
1384  {
1385  Var *gvar = (Var *) lfirst(gl);
1386 
1387  if (IsA(gvar, Var) &&
1388  gvar->varno == varno &&
1389  gvar->varlevelsup == varlevelsup)
1390  groupbyattnos = bms_add_member(groupbyattnos,
1392  }
1393 
1394  if (bms_is_subset(pkattnos, groupbyattnos))
1395  {
1396  /* The PK is a subset of grouping_columns, so we win */
1397  *constraintDeps = lappend_oid(*constraintDeps, constraintOid);
1398  return true;
1399  }
1400 
1401  return false;
1402 }
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:815
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define lfirst(lc)
Definition: pg_list.h:172
Definition: primnodes.h:248
AttrNumber varattno
Definition: primnodes.h:260
int varno
Definition: primnodes.h:255
Index varlevelsup
Definition: primnodes.h:280
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27

References bms_add_member(), bms_is_subset(), FirstLowInvalidHeapAttributeNumber, get_primary_key_attnos(), IsA, lappend_oid(), lfirst, Var::varattno, Var::varlevelsup, and Var::varno.

Referenced by check_ungrouped_columns_walker().

◆ ChooseConstraintName()

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

Definition at line 497 of file pg_constraint.c.

500 {
501  int pass = 0;
502  char *conname = NULL;
503  char modlabel[NAMEDATALEN];
504  Relation conDesc;
505  SysScanDesc conscan;
506  ScanKeyData skey[2];
507  bool found;
508  ListCell *l;
509 
510  conDesc = table_open(ConstraintRelationId, AccessShareLock);
511 
512  /* try the unmodified label first */
513  strlcpy(modlabel, label, sizeof(modlabel));
514 
515  for (;;)
516  {
517  conname = makeObjectName(name1, name2, modlabel);
518 
519  found = false;
520 
521  foreach(l, others)
522  {
523  if (strcmp((char *) lfirst(l), conname) == 0)
524  {
525  found = true;
526  break;
527  }
528  }
529 
530  if (!found)
531  {
532  ScanKeyInit(&skey[0],
533  Anum_pg_constraint_conname,
534  BTEqualStrategyNumber, F_NAMEEQ,
535  CStringGetDatum(conname));
536 
537  ScanKeyInit(&skey[1],
538  Anum_pg_constraint_connamespace,
539  BTEqualStrategyNumber, F_OIDEQ,
540  ObjectIdGetDatum(namespaceid));
541 
542  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
543  NULL, 2, skey);
544 
545  found = (HeapTupleIsValid(systable_getnext(conscan)));
546 
547  systable_endscan(conscan);
548  }
549 
550  if (!found)
551  break;
552 
553  /* found a conflict, so try a new name component */
554  pfree(conname);
555  snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
556  }
557 
558  table_close(conDesc, AccessShareLock);
559 
560  return conname;
561 }
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:2413
#define AccessShareLock
Definition: lockdefs.h:36
void pfree(void *pointer)
Definition: mcxt.c:1521
static char * label
#define NAMEDATALEN
#define snprintf
Definition: port.h:238
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
static Datum CStringGetDatum(const char *X)
Definition: postgres.h:350

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

Referenced by addFkRecurseReferenced(), addFkRecurseReferencing(), AddRelationNewConstraints(), ATExecAddConstraint(), CloneFkReferencing(), domainAddCheckConstraint(), and domainAddNotNullConstraint().

◆ ConstraintNameExists()

bool ConstraintNameExists ( const char *  conname,
Oid  namespaceid 
)

Definition at line 443 of file pg_constraint.c.

444 {
445  bool found;
446  Relation conDesc;
447  SysScanDesc conscan;
448  ScanKeyData skey[2];
449 
450  conDesc = table_open(ConstraintRelationId, AccessShareLock);
451 
452  ScanKeyInit(&skey[0],
453  Anum_pg_constraint_conname,
454  BTEqualStrategyNumber, F_NAMEEQ,
455  CStringGetDatum(conname));
456 
457  ScanKeyInit(&skey[1],
458  Anum_pg_constraint_connamespace,
459  BTEqualStrategyNumber, F_OIDEQ,
460  ObjectIdGetDatum(namespaceid));
461 
462  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
463  NULL, 2, skey);
464 
465  found = (HeapTupleIsValid(systable_getnext(conscan)));
466 
467  systable_endscan(conscan);
468  table_close(conDesc, AccessShareLock);
469 
470  return found;
471 }

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

Referenced by ChooseRelationName().

◆ ConstraintNameIsUsed()

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

Definition at line 398 of file pg_constraint.c.

400 {
401  bool found;
402  Relation conDesc;
403  SysScanDesc conscan;
404  ScanKeyData skey[3];
405 
406  conDesc = table_open(ConstraintRelationId, AccessShareLock);
407 
408  ScanKeyInit(&skey[0],
409  Anum_pg_constraint_conrelid,
410  BTEqualStrategyNumber, F_OIDEQ,
412  ? objId : InvalidOid));
413  ScanKeyInit(&skey[1],
414  Anum_pg_constraint_contypid,
415  BTEqualStrategyNumber, F_OIDEQ,
417  ? objId : InvalidOid));
418  ScanKeyInit(&skey[2],
419  Anum_pg_constraint_conname,
420  BTEqualStrategyNumber, F_NAMEEQ,
421  CStringGetDatum(conname));
422 
423  conscan = systable_beginscan(conDesc, ConstraintRelidTypidNameIndexId,
424  true, NULL, 3, skey);
425 
426  /* There can be at most one matching row */
427  found = (HeapTupleIsValid(systable_getnext(conscan)));
428 
429  systable_endscan(conscan);
430  table_close(conDesc, AccessShareLock);
431 
432  return found;
433 }

References AccessShareLock, BTEqualStrategyNumber, CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, CStringGetDatum(), HeapTupleIsValid, InvalidOid, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by addFkRecurseReferenced(), addFkRecurseReferencing(), ATExecAddConstraint(), CloneFkReferencing(), domainAddCheckConstraint(), domainAddNotNullConstraint(), index_create(), and RenameConstraintById().

◆ ConstraintSetParentConstraint()

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

Definition at line 823 of file pg_constraint.c.

826 {
827  Relation constrRel;
828  Form_pg_constraint constrForm;
829  HeapTuple tuple,
830  newtup;
831  ObjectAddress depender;
832  ObjectAddress referenced;
833 
834  constrRel = table_open(ConstraintRelationId, RowExclusiveLock);
835  tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(childConstrId));
836  if (!HeapTupleIsValid(tuple))
837  elog(ERROR, "cache lookup failed for constraint %u", childConstrId);
838  newtup = heap_copytuple(tuple);
839  constrForm = (Form_pg_constraint) GETSTRUCT(newtup);
840  if (OidIsValid(parentConstrId))
841  {
842  /* don't allow setting parent for a constraint that already has one */
843  Assert(constrForm->coninhcount == 0);
844  if (constrForm->conparentid != InvalidOid)
845  elog(ERROR, "constraint %u already has a parent constraint",
846  childConstrId);
847 
848  constrForm->conislocal = false;
849  constrForm->coninhcount++;
850  if (constrForm->coninhcount < 0)
851  ereport(ERROR,
852  errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
853  errmsg("too many inheritance parents"));
854  constrForm->conparentid = parentConstrId;
855 
856  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
857 
858  ObjectAddressSet(depender, ConstraintRelationId, childConstrId);
859 
860  ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId);
861  recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI);
862 
863  ObjectAddressSet(referenced, RelationRelationId, childTableId);
864  recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC);
865  }
866  else
867  {
868  constrForm->coninhcount--;
869  constrForm->conislocal = true;
870  constrForm->conparentid = InvalidOid;
871 
872  /* Make sure there's no further inheritance. */
873  Assert(constrForm->coninhcount == 0);
874 
875  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
876 
877  deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
878  ConstraintRelationId,
880  deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
881  RelationRelationId,
883  }
884 
885  ReleaseSysCache(tuple);
886  table_close(constrRel, RowExclusiveLock);
887 }
#define Assert(condition)
Definition: c.h:858
#define OidIsValid(objectId)
Definition: c.h:775
@ DEPENDENCY_PARTITION_PRI
Definition: dependency.h:36
@ DEPENDENCY_PARTITION_SEC
Definition: dependency.h:37
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
#define ereport(elevel,...)
Definition: elog.h:149
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:46
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition: pg_depend.c:352
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:266
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:218

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

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

◆ CreateConstraintEntry()

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  is_internal 
)

Definition at line 48 of file pg_constraint.c.

79 {
80  Relation conDesc;
81  Oid conOid;
82  HeapTuple tup;
83  bool nulls[Natts_pg_constraint];
84  Datum values[Natts_pg_constraint];
85  ArrayType *conkeyArray;
86  ArrayType *confkeyArray;
87  ArrayType *conpfeqopArray;
88  ArrayType *conppeqopArray;
89  ArrayType *conffeqopArray;
90  ArrayType *conexclopArray;
91  ArrayType *confdelsetcolsArray;
93  int i;
94  ObjectAddress conobject;
95  ObjectAddresses *addrs_auto;
96  ObjectAddresses *addrs_normal;
97 
98  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
99 
100  Assert(constraintName);
101  namestrcpy(&cname, constraintName);
102 
103  /*
104  * Convert C arrays into Postgres arrays.
105  */
106  if (constraintNKeys > 0)
107  {
108  Datum *conkey;
109 
110  conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));
111  for (i = 0; i < constraintNKeys; i++)
112  conkey[i] = Int16GetDatum(constraintKey[i]);
113  conkeyArray = construct_array_builtin(conkey, constraintNKeys, INT2OID);
114  }
115  else
116  conkeyArray = NULL;
117 
118  if (foreignNKeys > 0)
119  {
120  Datum *fkdatums;
121 
122  fkdatums = (Datum *) palloc(foreignNKeys * sizeof(Datum));
123  for (i = 0; i < foreignNKeys; i++)
124  fkdatums[i] = Int16GetDatum(foreignKey[i]);
125  confkeyArray = construct_array_builtin(fkdatums, foreignNKeys, INT2OID);
126  for (i = 0; i < foreignNKeys; i++)
127  fkdatums[i] = ObjectIdGetDatum(pfEqOp[i]);
128  conpfeqopArray = construct_array_builtin(fkdatums, foreignNKeys, OIDOID);
129  for (i = 0; i < foreignNKeys; i++)
130  fkdatums[i] = ObjectIdGetDatum(ppEqOp[i]);
131  conppeqopArray = construct_array_builtin(fkdatums, foreignNKeys, OIDOID);
132  for (i = 0; i < foreignNKeys; i++)
133  fkdatums[i] = ObjectIdGetDatum(ffEqOp[i]);
134  conffeqopArray = construct_array_builtin(fkdatums, foreignNKeys, OIDOID);
135 
136  if (numFkDeleteSetCols > 0)
137  {
138  for (i = 0; i < numFkDeleteSetCols; i++)
139  fkdatums[i] = Int16GetDatum(fkDeleteSetCols[i]);
140  confdelsetcolsArray = construct_array_builtin(fkdatums, numFkDeleteSetCols, INT2OID);
141  }
142  else
143  confdelsetcolsArray = NULL;
144  }
145  else
146  {
147  confkeyArray = NULL;
148  conpfeqopArray = NULL;
149  conppeqopArray = NULL;
150  conffeqopArray = NULL;
151  confdelsetcolsArray = NULL;
152  }
153 
154  if (exclOp != NULL)
155  {
156  Datum *opdatums;
157 
158  opdatums = (Datum *) palloc(constraintNKeys * sizeof(Datum));
159  for (i = 0; i < constraintNKeys; i++)
160  opdatums[i] = ObjectIdGetDatum(exclOp[i]);
161  conexclopArray = construct_array_builtin(opdatums, constraintNKeys, OIDOID);
162  }
163  else
164  conexclopArray = NULL;
165 
166  /* initialize nulls and values */
167  for (i = 0; i < Natts_pg_constraint; i++)
168  {
169  nulls[i] = false;
170  values[i] = (Datum) NULL;
171  }
172 
173  conOid = GetNewOidWithIndex(conDesc, ConstraintOidIndexId,
174  Anum_pg_constraint_oid);
175  values[Anum_pg_constraint_oid - 1] = ObjectIdGetDatum(conOid);
176  values[Anum_pg_constraint_conname - 1] = NameGetDatum(&cname);
177  values[Anum_pg_constraint_connamespace - 1] = ObjectIdGetDatum(constraintNamespace);
178  values[Anum_pg_constraint_contype - 1] = CharGetDatum(constraintType);
179  values[Anum_pg_constraint_condeferrable - 1] = BoolGetDatum(isDeferrable);
180  values[Anum_pg_constraint_condeferred - 1] = BoolGetDatum(isDeferred);
181  values[Anum_pg_constraint_convalidated - 1] = BoolGetDatum(isValidated);
182  values[Anum_pg_constraint_conrelid - 1] = ObjectIdGetDatum(relId);
183  values[Anum_pg_constraint_contypid - 1] = ObjectIdGetDatum(domainId);
184  values[Anum_pg_constraint_conindid - 1] = ObjectIdGetDatum(indexRelId);
185  values[Anum_pg_constraint_conparentid - 1] = ObjectIdGetDatum(parentConstrId);
186  values[Anum_pg_constraint_confrelid - 1] = ObjectIdGetDatum(foreignRelId);
187  values[Anum_pg_constraint_confupdtype - 1] = CharGetDatum(foreignUpdateType);
188  values[Anum_pg_constraint_confdeltype - 1] = CharGetDatum(foreignDeleteType);
189  values[Anum_pg_constraint_confmatchtype - 1] = CharGetDatum(foreignMatchType);
190  values[Anum_pg_constraint_conislocal - 1] = BoolGetDatum(conIsLocal);
191  values[Anum_pg_constraint_coninhcount - 1] = Int16GetDatum(conInhCount);
192  values[Anum_pg_constraint_connoinherit - 1] = BoolGetDatum(conNoInherit);
193 
194  if (conkeyArray)
195  values[Anum_pg_constraint_conkey - 1] = PointerGetDatum(conkeyArray);
196  else
197  nulls[Anum_pg_constraint_conkey - 1] = true;
198 
199  if (confkeyArray)
200  values[Anum_pg_constraint_confkey - 1] = PointerGetDatum(confkeyArray);
201  else
202  nulls[Anum_pg_constraint_confkey - 1] = true;
203 
204  if (conpfeqopArray)
205  values[Anum_pg_constraint_conpfeqop - 1] = PointerGetDatum(conpfeqopArray);
206  else
207  nulls[Anum_pg_constraint_conpfeqop - 1] = true;
208 
209  if (conppeqopArray)
210  values[Anum_pg_constraint_conppeqop - 1] = PointerGetDatum(conppeqopArray);
211  else
212  nulls[Anum_pg_constraint_conppeqop - 1] = true;
213 
214  if (conffeqopArray)
215  values[Anum_pg_constraint_conffeqop - 1] = PointerGetDatum(conffeqopArray);
216  else
217  nulls[Anum_pg_constraint_conffeqop - 1] = true;
218 
219  if (confdelsetcolsArray)
220  values[Anum_pg_constraint_confdelsetcols - 1] = PointerGetDatum(confdelsetcolsArray);
221  else
222  nulls[Anum_pg_constraint_confdelsetcols - 1] = true;
223 
224  if (conexclopArray)
225  values[Anum_pg_constraint_conexclop - 1] = PointerGetDatum(conexclopArray);
226  else
227  nulls[Anum_pg_constraint_conexclop - 1] = true;
228 
229  if (conBin)
230  values[Anum_pg_constraint_conbin - 1] = CStringGetTextDatum(conBin);
231  else
232  nulls[Anum_pg_constraint_conbin - 1] = true;
233 
234  tup = heap_form_tuple(RelationGetDescr(conDesc), values, nulls);
235 
236  CatalogTupleInsert(conDesc, tup);
237 
238  ObjectAddressSet(conobject, ConstraintRelationId, conOid);
239 
240  table_close(conDesc, RowExclusiveLock);
241 
242  /* Handle set of auto dependencies */
243  addrs_auto = new_object_addresses();
244 
245  if (OidIsValid(relId))
246  {
247  /*
248  * Register auto dependency from constraint to owning relation, or to
249  * specific column(s) if any are mentioned.
250  */
251  ObjectAddress relobject;
252 
253  if (constraintNTotalKeys > 0)
254  {
255  for (i = 0; i < constraintNTotalKeys; i++)
256  {
257  ObjectAddressSubSet(relobject, RelationRelationId, relId,
258  constraintKey[i]);
259  add_exact_object_address(&relobject, addrs_auto);
260  }
261  }
262  else
263  {
264  ObjectAddressSet(relobject, RelationRelationId, relId);
265  add_exact_object_address(&relobject, addrs_auto);
266  }
267  }
268 
269  if (OidIsValid(domainId))
270  {
271  /*
272  * Register auto dependency from constraint to owning domain
273  */
274  ObjectAddress domobject;
275 
276  ObjectAddressSet(domobject, TypeRelationId, domainId);
277  add_exact_object_address(&domobject, addrs_auto);
278  }
279 
280  record_object_address_dependencies(&conobject, addrs_auto,
282  free_object_addresses(addrs_auto);
283 
284  /* Handle set of normal dependencies */
285  addrs_normal = new_object_addresses();
286 
287  if (OidIsValid(foreignRelId))
288  {
289  /*
290  * Register normal dependency from constraint to foreign relation, or
291  * to specific column(s) if any are mentioned.
292  */
293  ObjectAddress relobject;
294 
295  if (foreignNKeys > 0)
296  {
297  for (i = 0; i < foreignNKeys; i++)
298  {
299  ObjectAddressSubSet(relobject, RelationRelationId,
300  foreignRelId, foreignKey[i]);
301  add_exact_object_address(&relobject, addrs_normal);
302  }
303  }
304  else
305  {
306  ObjectAddressSet(relobject, RelationRelationId, foreignRelId);
307  add_exact_object_address(&relobject, addrs_normal);
308  }
309  }
310 
311  if (OidIsValid(indexRelId) && constraintType == CONSTRAINT_FOREIGN)
312  {
313  /*
314  * Register normal dependency on the unique index that supports a
315  * foreign-key constraint. (Note: for indexes associated with unique
316  * or primary-key constraints, the dependency runs the other way, and
317  * is not made here.)
318  */
319  ObjectAddress relobject;
320 
321  ObjectAddressSet(relobject, RelationRelationId, indexRelId);
322  add_exact_object_address(&relobject, addrs_normal);
323  }
324 
325  if (foreignNKeys > 0)
326  {
327  /*
328  * Register normal dependencies on the equality operators that support
329  * a foreign-key constraint. If the PK and FK types are the same then
330  * all three operators for a column are the same; otherwise they are
331  * different.
332  */
333  ObjectAddress oprobject;
334 
335  oprobject.classId = OperatorRelationId;
336  oprobject.objectSubId = 0;
337 
338  for (i = 0; i < foreignNKeys; i++)
339  {
340  oprobject.objectId = pfEqOp[i];
341  add_exact_object_address(&oprobject, addrs_normal);
342  if (ppEqOp[i] != pfEqOp[i])
343  {
344  oprobject.objectId = ppEqOp[i];
345  add_exact_object_address(&oprobject, addrs_normal);
346  }
347  if (ffEqOp[i] != pfEqOp[i])
348  {
349  oprobject.objectId = ffEqOp[i];
350  add_exact_object_address(&oprobject, addrs_normal);
351  }
352  }
353  }
354 
355  record_object_address_dependencies(&conobject, addrs_normal,
357  free_object_addresses(addrs_normal);
358 
359  /*
360  * We don't bother to register dependencies on the exclusion operators of
361  * an exclusion constraint. We assume they are members of the opclass
362  * supporting the index, so there's an indirect dependency via that. (This
363  * would be pretty dicey for cross-type operators, but exclusion operators
364  * can never be cross-type.)
365  */
366 
367  if (conExpr != NULL)
368  {
369  /*
370  * Register dependencies from constraint to objects mentioned in CHECK
371  * expression.
372  */
373  recordDependencyOnSingleRelExpr(&conobject, conExpr, relId,
375  DEPENDENCY_NORMAL, false);
376  }
377 
378  /* Post creation hook for new constraint */
379  InvokeObjectPostCreateHookArg(ConstraintRelationId, conOid, 0,
380  is_internal);
381 
382  return conOid;
383 }
ArrayType * construct_array_builtin(Datum *elems, int nelems, Oid elmtype)
Definition: arrayfuncs.c:3381
static Datum values[MAXATTR]
Definition: bootstrap.c:150
#define CStringGetTextDatum(s)
Definition: builtins.h:97
Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
Definition: catalog.c:412
void record_object_address_dependencies(const ObjectAddress *depender, ObjectAddresses *referenced, DependencyType behavior)
Definition: dependency.c:2742
void recordDependencyOnSingleRelExpr(const ObjectAddress *depender, Node *expr, Oid relId, DependencyType behavior, DependencyType self_behavior, bool reverse_self)
Definition: dependency.c:1596
ObjectAddresses * new_object_addresses(void)
Definition: dependency.c:2487
void free_object_addresses(ObjectAddresses *addrs)
Definition: dependency.c:2773
@ 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:1116
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition: indexing.c:233
int i
Definition: isn.c:73
void * palloc(Size size)
Definition: mcxt.c:1317
void namestrcpy(Name name, const char *str)
Definition: name.c:233
#define InvokeObjectPostCreateHookArg(classId, objectId, subId, is_internal)
Definition: objectaccess.h:175
#define ObjectAddressSubSet(addr, class_id, object_id, object_sub_id)
Definition: objectaddress.h:33
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum BoolGetDatum(bool X)
Definition: postgres.h:102
static Datum NameGetDatum(const NameData *X)
Definition: postgres.h:373
static Datum CharGetDatum(char X)
Definition: postgres.h:122
#define RelationGetDescr(relation)
Definition: rel.h:531

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

Referenced by addFkRecurseReferenced(), addFkRecurseReferencing(), CloneFkReferencing(), CreateTriggerFiringOn(), domainAddCheckConstraint(), domainAddNotNullConstraint(), index_constraint_create(), and StoreRelCheck().

◆ 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 
)

Definition at line 1234 of file pg_constraint.c.

1238 {
1239  Datum adatum;
1240  bool isNull;
1241  ArrayType *arr;
1242  int numkeys;
1243 
1244  /*
1245  * We expect the arrays to be 1-D arrays of the right types; verify that.
1246  * We don't need to use deconstruct_array() since the array data is just
1247  * going to look like a C array of values.
1248  */
1249  adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
1250  Anum_pg_constraint_conkey);
1251  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1252  if (ARR_NDIM(arr) != 1 ||
1253  ARR_HASNULL(arr) ||
1254  ARR_ELEMTYPE(arr) != INT2OID)
1255  elog(ERROR, "conkey is not a 1-D smallint array");
1256  numkeys = ARR_DIMS(arr)[0];
1257  if (numkeys <= 0 || numkeys > INDEX_MAX_KEYS)
1258  elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
1259  memcpy(conkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1260  if ((Pointer) arr != DatumGetPointer(adatum))
1261  pfree(arr); /* free de-toasted copy, if any */
1262 
1263  adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
1264  Anum_pg_constraint_confkey);
1265  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1266  if (ARR_NDIM(arr) != 1 ||
1267  ARR_DIMS(arr)[0] != numkeys ||
1268  ARR_HASNULL(arr) ||
1269  ARR_ELEMTYPE(arr) != INT2OID)
1270  elog(ERROR, "confkey is not a 1-D smallint array");
1271  memcpy(confkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1272  if ((Pointer) arr != DatumGetPointer(adatum))
1273  pfree(arr); /* free de-toasted copy, if any */
1274 
1275  if (pf_eq_oprs)
1276  {
1277  adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
1278  Anum_pg_constraint_conpfeqop);
1279  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1280  /* see TryReuseForeignKey if you change the test below */
1281  if (ARR_NDIM(arr) != 1 ||
1282  ARR_DIMS(arr)[0] != numkeys ||
1283  ARR_HASNULL(arr) ||
1284  ARR_ELEMTYPE(arr) != OIDOID)
1285  elog(ERROR, "conpfeqop is not a 1-D Oid array");
1286  memcpy(pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1287  if ((Pointer) arr != DatumGetPointer(adatum))
1288  pfree(arr); /* free de-toasted copy, if any */
1289  }
1290 
1291  if (pp_eq_oprs)
1292  {
1293  adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
1294  Anum_pg_constraint_conppeqop);
1295  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1296  if (ARR_NDIM(arr) != 1 ||
1297  ARR_DIMS(arr)[0] != numkeys ||
1298  ARR_HASNULL(arr) ||
1299  ARR_ELEMTYPE(arr) != OIDOID)
1300  elog(ERROR, "conppeqop is not a 1-D Oid array");
1301  memcpy(pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1302  if ((Pointer) arr != DatumGetPointer(adatum))
1303  pfree(arr); /* free de-toasted copy, if any */
1304  }
1305 
1306  if (ff_eq_oprs)
1307  {
1308  adatum = SysCacheGetAttrNotNull(CONSTROID, tuple,
1309  Anum_pg_constraint_conffeqop);
1310  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1311  if (ARR_NDIM(arr) != 1 ||
1312  ARR_DIMS(arr)[0] != numkeys ||
1313  ARR_HASNULL(arr) ||
1314  ARR_ELEMTYPE(arr) != OIDOID)
1315  elog(ERROR, "conffeqop is not a 1-D Oid array");
1316  memcpy(ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1317  if ((Pointer) arr != DatumGetPointer(adatum))
1318  pfree(arr); /* free de-toasted copy, if any */
1319  }
1320 
1321  if (fk_del_set_cols)
1322  {
1323  adatum = SysCacheGetAttr(CONSTROID, tuple,
1324  Anum_pg_constraint_confdelsetcols, &isNull);
1325  if (isNull)
1326  {
1327  *num_fk_del_set_cols = 0;
1328  }
1329  else
1330  {
1331  int num_delete_cols;
1332 
1333  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1334  if (ARR_NDIM(arr) != 1 ||
1335  ARR_HASNULL(arr) ||
1336  ARR_ELEMTYPE(arr) != INT2OID)
1337  elog(ERROR, "confdelsetcols is not a 1-D smallint array");
1338  num_delete_cols = ARR_DIMS(arr)[0];
1339  memcpy(fk_del_set_cols, ARR_DATA_PTR(arr), num_delete_cols * sizeof(int16));
1340  if ((Pointer) arr != DatumGetPointer(adatum))
1341  pfree(arr); /* free de-toasted copy, if any */
1342 
1343  *num_fk_del_set_cols = num_delete_cols;
1344  }
1345  }
1346 
1347  *numfks = numkeys;
1348 }
#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
char * Pointer
Definition: c.h:483
#define INDEX_MAX_KEYS
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:479
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition: syscache.c:510

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

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

◆ findDomainNotNullConstraint()

HeapTuple findDomainNotNullConstraint ( Oid  typid)

Definition at line 568 of file pg_constraint.c.

569 {
570  Relation pg_constraint;
571  HeapTuple conTup,
572  retval = NULL;
573  SysScanDesc scan;
575 
576  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
577  ScanKeyInit(&key,
578  Anum_pg_constraint_contypid,
579  BTEqualStrategyNumber, F_OIDEQ,
580  ObjectIdGetDatum(typid));
581  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId,
582  true, NULL, 1, &key);
583 
584  while (HeapTupleIsValid(conTup = systable_getnext(scan)))
585  {
587 
588  /*
589  * We're looking for a NOTNULL constraint that's marked validated.
590  */
591  if (con->contype != CONSTRAINT_NOTNULL)
592  continue;
593  if (!con->convalidated)
594  continue;
595 
596  /* Found it */
597  retval = heap_copytuple(conTup);
598  break;
599  }
600 
601  systable_endscan(scan);
602  table_close(pg_constraint, AccessShareLock);
603 
604  return retval;
605 }

References AccessShareLock, BTEqualStrategyNumber, GETSTRUCT, heap_copytuple(), HeapTupleIsValid, sort-test::key, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by AlterDomainNotNull().

◆ get_domain_constraint_oid()

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

Definition at line 1089 of file pg_constraint.c.

1090 {
1091  Relation pg_constraint;
1092  HeapTuple tuple;
1093  SysScanDesc scan;
1094  ScanKeyData skey[3];
1095  Oid conOid = InvalidOid;
1096 
1097  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1098 
1099  ScanKeyInit(&skey[0],
1100  Anum_pg_constraint_conrelid,
1101  BTEqualStrategyNumber, F_OIDEQ,
1103  ScanKeyInit(&skey[1],
1104  Anum_pg_constraint_contypid,
1105  BTEqualStrategyNumber, F_OIDEQ,
1106  ObjectIdGetDatum(typid));
1107  ScanKeyInit(&skey[2],
1108  Anum_pg_constraint_conname,
1109  BTEqualStrategyNumber, F_NAMEEQ,
1110  CStringGetDatum(conname));
1111 
1112  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1113  NULL, 3, skey);
1114 
1115  /* There can be at most one matching row */
1116  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1117  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1118 
1119  systable_endscan(scan);
1120 
1121  /* If no such constraint exists, complain */
1122  if (!OidIsValid(conOid) && !missing_ok)
1123  ereport(ERROR,
1124  (errcode(ERRCODE_UNDEFINED_OBJECT),
1125  errmsg("constraint \"%s\" for domain %s does not exist",
1126  conname, format_type_be(typid))));
1127 
1128  table_close(pg_constraint, AccessShareLock);
1129 
1130  return conOid;
1131 }
char * format_type_be(Oid type_oid)
Definition: format_type.c:343

References AccessShareLock, BTEqualStrategyNumber, CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, 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 
)

Definition at line 1148 of file pg_constraint.c.

1149 {
1150  Bitmapset *pkattnos = NULL;
1151  Relation pg_constraint;
1152  HeapTuple tuple;
1153  SysScanDesc scan;
1154  ScanKeyData skey[1];
1155 
1156  /* Set *constraintOid, to avoid complaints about uninitialized vars */
1157  *constraintOid = InvalidOid;
1158 
1159  /* Scan pg_constraint for constraints of the target rel */
1160  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1161 
1162  ScanKeyInit(&skey[0],
1163  Anum_pg_constraint_conrelid,
1164  BTEqualStrategyNumber, F_OIDEQ,
1165  ObjectIdGetDatum(relid));
1166 
1167  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1168  NULL, 1, skey);
1169 
1170  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1171  {
1173  Datum adatum;
1174  bool isNull;
1175  ArrayType *arr;
1176  int16 *attnums;
1177  int numkeys;
1178  int i;
1179 
1180  /* Skip constraints that are not PRIMARY KEYs */
1181  if (con->contype != CONSTRAINT_PRIMARY)
1182  continue;
1183 
1184  /*
1185  * If the primary key is deferrable, but we've been instructed to
1186  * ignore deferrable constraints, then we might as well give up
1187  * searching, since there can only be a single primary key on a table.
1188  */
1189  if (con->condeferrable && !deferrableOk)
1190  break;
1191 
1192  /* Extract the conkey array, ie, attnums of PK's columns */
1193  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
1194  RelationGetDescr(pg_constraint), &isNull);
1195  if (isNull)
1196  elog(ERROR, "null conkey for constraint %u",
1197  ((Form_pg_constraint) GETSTRUCT(tuple))->oid);
1198  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1199  numkeys = ARR_DIMS(arr)[0];
1200  if (ARR_NDIM(arr) != 1 ||
1201  numkeys < 0 ||
1202  ARR_HASNULL(arr) ||
1203  ARR_ELEMTYPE(arr) != INT2OID)
1204  elog(ERROR, "conkey is not a 1-D smallint array");
1205  attnums = (int16 *) ARR_DATA_PTR(arr);
1206 
1207  /* Construct the result value */
1208  for (i = 0; i < numkeys; i++)
1209  {
1210  pkattnos = bms_add_member(pkattnos,
1212  }
1213  *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1214 
1215  /* No need to search further */
1216  break;
1217  }
1218 
1219  systable_endscan(scan);
1220 
1221  table_close(pg_constraint, AccessShareLock);
1222 
1223  return pkattnos;
1224 }
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, DatumGetArrayTypeP, elog, ERROR, 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(), and remove_useless_groupby_columns().

◆ get_relation_constraint_attnos()

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

Definition at line 953 of file pg_constraint.c.

955 {
956  Bitmapset *conattnos = NULL;
957  Relation pg_constraint;
958  HeapTuple tuple;
959  SysScanDesc scan;
960  ScanKeyData skey[3];
961 
962  /* Set *constraintOid, to avoid complaints about uninitialized vars */
963  *constraintOid = InvalidOid;
964 
965  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
966 
967  ScanKeyInit(&skey[0],
968  Anum_pg_constraint_conrelid,
969  BTEqualStrategyNumber, F_OIDEQ,
970  ObjectIdGetDatum(relid));
971  ScanKeyInit(&skey[1],
972  Anum_pg_constraint_contypid,
973  BTEqualStrategyNumber, F_OIDEQ,
975  ScanKeyInit(&skey[2],
976  Anum_pg_constraint_conname,
977  BTEqualStrategyNumber, F_NAMEEQ,
978  CStringGetDatum(conname));
979 
980  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
981  NULL, 3, skey);
982 
983  /* There can be at most one matching row */
984  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
985  {
986  Datum adatum;
987  bool isNull;
988 
989  *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
990 
991  /* Extract the conkey array, ie, attnums of constrained columns */
992  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
993  RelationGetDescr(pg_constraint), &isNull);
994  if (!isNull)
995  {
996  ArrayType *arr;
997  int numcols;
998  int16 *attnums;
999  int i;
1000 
1001  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1002  numcols = ARR_DIMS(arr)[0];
1003  if (ARR_NDIM(arr) != 1 ||
1004  numcols < 0 ||
1005  ARR_HASNULL(arr) ||
1006  ARR_ELEMTYPE(arr) != INT2OID)
1007  elog(ERROR, "conkey is not a 1-D smallint array");
1008  attnums = (int16 *) ARR_DATA_PTR(arr);
1009 
1010  /* Construct the result value */
1011  for (i = 0; i < numcols; i++)
1012  {
1013  conattnos = bms_add_member(conattnos,
1015  }
1016  }
1017  }
1018 
1019  systable_endscan(scan);
1020 
1021  /* If no such constraint exists, complain */
1022  if (!OidIsValid(*constraintOid) && !missing_ok)
1023  ereport(ERROR,
1024  (errcode(ERRCODE_UNDEFINED_OBJECT),
1025  errmsg("constraint \"%s\" for table \"%s\" does not exist",
1026  conname, get_rel_name(relid))));
1027 
1028  table_close(pg_constraint, AccessShareLock);
1029 
1030  return conattnos;
1031 }
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1928

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, CStringGetDatum(), DatumGetArrayTypeP, elog, ereport, errcode(), errmsg(), ERROR, 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 
)

Definition at line 896 of file pg_constraint.c.

897 {
898  Relation pg_constraint;
899  HeapTuple tuple;
900  SysScanDesc scan;
901  ScanKeyData skey[3];
902  Oid conOid = InvalidOid;
903 
904  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
905 
906  ScanKeyInit(&skey[0],
907  Anum_pg_constraint_conrelid,
908  BTEqualStrategyNumber, F_OIDEQ,
909  ObjectIdGetDatum(relid));
910  ScanKeyInit(&skey[1],
911  Anum_pg_constraint_contypid,
912  BTEqualStrategyNumber, F_OIDEQ,
914  ScanKeyInit(&skey[2],
915  Anum_pg_constraint_conname,
916  BTEqualStrategyNumber, F_NAMEEQ,
917  CStringGetDatum(conname));
918 
919  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
920  NULL, 3, skey);
921 
922  /* There can be at most one matching row */
923  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
924  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
925 
926  systable_endscan(scan);
927 
928  /* If no such constraint exists, complain */
929  if (!OidIsValid(conOid) && !missing_ok)
930  ereport(ERROR,
931  (errcode(ERRCODE_UNDEFINED_OBJECT),
932  errmsg("constraint \"%s\" for table \"%s\" does not exist",
933  conname, get_rel_name(relid))));
934 
935  table_close(pg_constraint, AccessShareLock);
936 
937  return conOid;
938 }

References AccessShareLock, BTEqualStrategyNumber, CStringGetDatum(), ereport, errcode(), errmsg(), ERROR, 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(), and rename_constraint_internal().

◆ get_relation_idx_constraint_oid()

Oid get_relation_idx_constraint_oid ( Oid  relationId,
Oid  indexId 
)

Definition at line 1042 of file pg_constraint.c.

1043 {
1044  Relation pg_constraint;
1045  SysScanDesc scan;
1046  ScanKeyData key;
1047  HeapTuple tuple;
1048  Oid constraintId = InvalidOid;
1049 
1050  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1051 
1052  ScanKeyInit(&key,
1053  Anum_pg_constraint_conrelid,
1055  F_OIDEQ,
1056  ObjectIdGetDatum(relationId));
1057  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId,
1058  true, NULL, 1, &key);
1059  while ((tuple = systable_getnext(scan)) != NULL)
1060  {
1061  Form_pg_constraint constrForm;
1062 
1063  constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
1064 
1065  /* See above */
1066  if (constrForm->contype != CONSTRAINT_PRIMARY &&
1067  constrForm->contype != CONSTRAINT_UNIQUE &&
1068  constrForm->contype != CONSTRAINT_EXCLUSION)
1069  continue;
1070 
1071  if (constrForm->conindid == indexId)
1072  {
1073  constraintId = constrForm->oid;
1074  break;
1075  }
1076  }
1077  systable_endscan(scan);
1078 
1079  table_close(pg_constraint, AccessShareLock);
1080  return constraintId;
1081 }

References AccessShareLock, BTEqualStrategyNumber, GETSTRUCT, InvalidOid, sort-test::key, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

◆ MAKE_SYSCACHE()

MAKE_SYSCACHE ( CONSTROID  ,
pg_constraint_oid_index  ,
16   
)

◆ RemoveConstraintById()

void RemoveConstraintById ( Oid  conId)

Definition at line 611 of file pg_constraint.c.

612 {
613  Relation conDesc;
614  HeapTuple tup;
615  Form_pg_constraint con;
616 
617  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
618 
619  tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conId));
620  if (!HeapTupleIsValid(tup)) /* should not happen */
621  elog(ERROR, "cache lookup failed for constraint %u", conId);
622  con = (Form_pg_constraint) GETSTRUCT(tup);
623 
624  /*
625  * Special processing depending on what the constraint is for.
626  */
627  if (OidIsValid(con->conrelid))
628  {
629  Relation rel;
630 
631  /*
632  * If the constraint is for a relation, open and exclusive-lock the
633  * relation it's for.
634  */
635  rel = table_open(con->conrelid, AccessExclusiveLock);
636 
637  /*
638  * We need to update the relchecks count if it is a check constraint
639  * being dropped. This update will force backends to rebuild relcache
640  * entries when we commit.
641  */
642  if (con->contype == CONSTRAINT_CHECK)
643  {
644  Relation pgrel;
645  HeapTuple relTup;
646  Form_pg_class classForm;
647 
648  pgrel = table_open(RelationRelationId, RowExclusiveLock);
649  relTup = SearchSysCacheCopy1(RELOID,
650  ObjectIdGetDatum(con->conrelid));
651  if (!HeapTupleIsValid(relTup))
652  elog(ERROR, "cache lookup failed for relation %u",
653  con->conrelid);
654  classForm = (Form_pg_class) GETSTRUCT(relTup);
655 
656  if (classForm->relchecks == 0) /* should not happen */
657  elog(ERROR, "relation \"%s\" has relchecks = 0",
659  classForm->relchecks--;
660 
661  CatalogTupleUpdate(pgrel, &relTup->t_self, relTup);
662 
663  heap_freetuple(relTup);
664 
666  }
667 
668  /* Keep lock on constraint's rel until end of xact */
669  table_close(rel, NoLock);
670  }
671  else if (OidIsValid(con->contypid))
672  {
673  /*
674  * XXX for now, do nothing special when dropping a domain constraint
675  *
676  * Probably there should be some form of locking on the domain type,
677  * but we have no such concept at the moment.
678  */
679  }
680  else
681  elog(ERROR, "constraint %u is not of a known type", conId);
682 
683  /* Fry the constraint itself */
684  CatalogTupleDelete(conDesc, &tup->t_self);
685 
686  /* Clean up */
687  ReleaseSysCache(tup);
688  table_close(conDesc, RowExclusiveLock);
689 }
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1434
void CatalogTupleDelete(Relation heapRel, ItemPointer 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:153
#define RelationGetRelationName(relation)
Definition: rel.h:539
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:86

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

Referenced by doDeletion().

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char *  newname 
)

Definition at line 702 of file pg_constraint.c.

703 {
704  Relation conDesc;
705  HeapTuple tuple;
706  Form_pg_constraint con;
707 
708  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
709 
710  tuple = SearchSysCacheCopy1(CONSTROID, ObjectIdGetDatum(conId));
711  if (!HeapTupleIsValid(tuple))
712  elog(ERROR, "cache lookup failed for constraint %u", conId);
713  con = (Form_pg_constraint) GETSTRUCT(tuple);
714 
715  /*
716  * For user-friendliness, check whether the name is already in use.
717  */
718  if (OidIsValid(con->conrelid) &&
720  con->conrelid,
721  newname))
722  ereport(ERROR,
724  errmsg("constraint \"%s\" for relation \"%s\" already exists",
725  newname, get_rel_name(con->conrelid))));
726  if (OidIsValid(con->contypid) &&
728  con->contypid,
729  newname))
730  ereport(ERROR,
732  errmsg("constraint \"%s\" for domain %s already exists",
733  newname, format_type_be(con->contypid))));
734 
735  /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
736  namestrcpy(&(con->conname), newname);
737 
738  CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
739 
740  InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0);
741 
742  heap_freetuple(tuple);
743  table_close(conDesc, RowExclusiveLock);
744 }
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32

References CatalogTupleUpdate(), CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameIsUsed(), elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, 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 158 of file pg_constraint.h.