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)
 
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, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
 
void RemoveConstraintById (Oid conId)
 
void RenameConstraintById (Oid conId, const char *newname)
 
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)
 
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)
 
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 154 of file pg_constraint.h.

Enumeration Type Documentation

◆ ConstraintCategory

Enumerator
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 177 of file pg_constraint.h.

Function Documentation

◆ AlterConstraintNamespaces()

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

Definition at line 699 of file pg_constraint.c.

References add_exact_object_address(), BTEqualStrategyNumber, CatalogTupleUpdate(), ObjectAddress::classId, ConstraintRelidTypidNameIndexId, GETSTRUCT, heap_copytuple(), HeapTupleIsValid, InvalidOid, InvokeObjectPostAlterHook, sort-test::key, object_address_present(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, table_close(), and table_open().

Referenced by AlterTableNamespaceInternal(), and AlterTypeNamespaceInternal().

701 {
702  Relation conRel;
703  ScanKeyData key[2];
704  SysScanDesc scan;
705  HeapTuple tup;
706 
707  conRel = table_open(ConstraintRelationId, RowExclusiveLock);
708 
709  ScanKeyInit(&key[0],
710  Anum_pg_constraint_conrelid,
711  BTEqualStrategyNumber, F_OIDEQ,
712  ObjectIdGetDatum(isType ? InvalidOid : ownerId));
713  ScanKeyInit(&key[1],
714  Anum_pg_constraint_contypid,
715  BTEqualStrategyNumber, F_OIDEQ,
716  ObjectIdGetDatum(isType ? ownerId : InvalidOid));
717 
719  NULL, 2, key);
720 
721  while (HeapTupleIsValid((tup = systable_getnext(scan))))
722  {
724  ObjectAddress thisobj;
725 
726  thisobj.classId = ConstraintRelationId;
727  thisobj.objectId = conform->oid;
728  thisobj.objectSubId = 0;
729 
730  if (object_address_present(&thisobj, objsMoved))
731  continue;
732 
733  /* Don't update if the object is already part of the namespace */
734  if (conform->connamespace == oldNspId && oldNspId != newNspId)
735  {
736  tup = heap_copytuple(tup);
737  conform = (Form_pg_constraint) GETSTRUCT(tup);
738 
739  conform->connamespace = newNspId;
740 
741  CatalogTupleUpdate(conRel, &tup->t_self, tup);
742 
743  /*
744  * Note: currently, the constraint will not have its own
745  * dependency on the namespace, so we don't need to do
746  * changeDependencyFor().
747  */
748  }
749 
750  InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0);
751 
752  add_exact_object_address(&thisobj, objsMoved);
753  }
754 
755  systable_endscan(scan);
756 
757  table_close(conRel, RowExclusiveLock);
758 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2517
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2457
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ 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; /* OID of namespace containing constraint */
50  char contype; /* constraint type; see codes below */
51  bool condeferrable; /* deferrable constraint? */
52  bool condeferred; /* deferred by default? */
53  bool convalidated; /* constraint has been validated? */
54 
55  /*
56  * conrelid and conkey are only meaningful if the constraint applies to a
57  * specific relation (this excludes domain constraints and assertions).
58  * Otherwise conrelid is 0 and conkey is NULL.
59  */
60  Oid conrelid; /* relation this constraint constrains */
61 
62  /*
63  * contypid links to the pg_type row for a domain if this is a domain
64  * constraint. Otherwise it's 0.
65  *
66  * For SQL-style global ASSERTIONs, both conrelid and contypid would be
67  * zero. This is not presently supported, however.
68  */
69  Oid contypid; /* domain this constraint constrains */
70 
71  /*
72  * conindid links to the index supporting the constraint, if any;
73  * otherwise it's 0. This is used for unique, primary-key, and exclusion
74  * constraints, and less obviously for foreign-key constraints (where the
75  * index is a unique index on the referenced relation's referenced
76  * columns). Notice that the index is on conrelid in the first case but
77  * confrelid in the second.
78  */
79  Oid conindid; /* index supporting this constraint */
80 
81  /*
82  * If this constraint is on a partition inherited from a partitioned
83  * table, this is the OID of the corresponding constraint in the parent.
84  */
85  Oid conparentid;
86 
87  /*
88  * These fields, plus confkey, are only meaningful for a foreign-key
89  * constraint. Otherwise confrelid is 0 and the char fields are spaces.
90  */
91  Oid confrelid; /* relation referenced by foreign key */
92  char confupdtype; /* foreign key's ON UPDATE action */
93  char confdeltype; /* foreign key's ON DELETE action */
94  char confmatchtype; /* foreign key's match type */
95 
96  /* Has a local definition (hence, do not drop when coninhcount is 0) */
97  bool conislocal;
98 
99  /* Number of times inherited from direct parent relation(s) */
100  int32 coninhcount;
101 
102  /* Has a local definition and cannot be inherited */
103  bool connoinherit;
104 
105 #ifdef CATALOG_VARLEN /* variable-length fields start here */
106 
107  /*
108  * Columns of conrelid that the constraint applies to, if known (this is
109  * NULL for trigger constraints)
110  */
111  int16 conkey[1];
112 
113  /*
114  * If a foreign key, the referenced columns of confrelid
115  */
116  int16 confkey[1];
117 
118  /*
119  * If a foreign key, the OIDs of the PK = FK equality operators for each
120  * column of the constraint
121  */
122  Oid conpfeqop[1];
123 
124  /*
125  * If a foreign key, the OIDs of the PK = PK equality operators for each
126  * column of the constraint (i.e., equality for the referenced columns)
127  */
128  Oid conppeqop[1];
129 
130  /*
131  * If a foreign key, the OIDs of the FK = FK equality operators for each
132  * column of the constraint (i.e., equality for the referencing columns)
133  */
134  Oid conffeqop[1];
135 
136  /*
137  * If an exclusion constraint, the OIDs of the exclusion operators for
138  * each column of the constraint
139  */
140  Oid conexclop[1];
141 
142  /*
143  * If a check constraint, nodeToString representation of expression
144  */
145  pg_node_tree conbin;
146 #endif
signed short int16
Definition: c.h:346
FormData_pg_constraint
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:347
Definition: c.h:610

◆ check_functional_grouping()

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

Definition at line 1283 of file pg_constraint.c.

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

1287 {
1288  Bitmapset *pkattnos;
1289  Bitmapset *groupbyattnos;
1290  Oid constraintOid;
1291  ListCell *gl;
1292 
1293  /* If the rel has no PK, then we can't prove functional dependency */
1294  pkattnos = get_primary_key_attnos(relid, false, &constraintOid);
1295  if (pkattnos == NULL)
1296  return false;
1297 
1298  /* Identify all the rel's columns that appear in grouping_columns */
1299  groupbyattnos = NULL;
1300  foreach(gl, grouping_columns)
1301  {
1302  Var *gvar = (Var *) lfirst(gl);
1303 
1304  if (IsA(gvar, Var) &&
1305  gvar->varno == varno &&
1306  gvar->varlevelsup == varlevelsup)
1307  groupbyattnos = bms_add_member(groupbyattnos,
1309  }
1310 
1311  if (bms_is_subset(pkattnos, groupbyattnos))
1312  {
1313  /* The PK is a subset of grouping_columns, so we win */
1314  *constraintDeps = lappend_oid(*constraintDeps, constraintOid);
1315  return true;
1316  }
1317 
1318  return false;
1319 }
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
Index varlevelsup
Definition: primnodes.h:177
AttrNumber varattno
Definition: primnodes.h:172
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:167
List * lappend_oid(List *list, Oid datum)
Definition: list.c:358
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:315
Index varno
Definition: primnodes.h:170
#define lfirst(lc)
Definition: pg_list.h:190
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736

◆ ChooseConstraintName()

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

Definition at line 486 of file pg_constraint.c.

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

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

489 {
490  int pass = 0;
491  char *conname = NULL;
492  char modlabel[NAMEDATALEN];
493  Relation conDesc;
494  SysScanDesc conscan;
495  ScanKeyData skey[2];
496  bool found;
497  ListCell *l;
498 
499  conDesc = table_open(ConstraintRelationId, AccessShareLock);
500 
501  /* try the unmodified label first */
502  StrNCpy(modlabel, label, sizeof(modlabel));
503 
504  for (;;)
505  {
506  conname = makeObjectName(name1, name2, modlabel);
507 
508  found = false;
509 
510  foreach(l, others)
511  {
512  if (strcmp((char *) lfirst(l), conname) == 0)
513  {
514  found = true;
515  break;
516  }
517  }
518 
519  if (!found)
520  {
521  ScanKeyInit(&skey[0],
522  Anum_pg_constraint_conname,
523  BTEqualStrategyNumber, F_NAMEEQ,
524  CStringGetDatum(conname));
525 
526  ScanKeyInit(&skey[1],
527  Anum_pg_constraint_connamespace,
528  BTEqualStrategyNumber, F_OIDEQ,
529  ObjectIdGetDatum(namespaceid));
530 
531  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
532  NULL, 2, skey);
533 
534  found = (HeapTupleIsValid(systable_getnext(conscan)));
535 
536  systable_endscan(conscan);
537  }
538 
539  if (!found)
540  break;
541 
542  /* found a conflict, so try a new name component */
543  pfree(conname);
544  snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
545  }
546 
547  table_close(conDesc, AccessShareLock);
548 
549  return conname;
550 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:2048
#define NAMEDATALEN
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
void pfree(void *pointer)
Definition: mcxt.c:1056
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define CStringGetDatum(X)
Definition: postgres.h:578
static char * label
#define ConstraintNameNspIndexId
Definition: indexing.h:126
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:190
#define StrNCpy(dst, src, len)
Definition: c.h:935
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define snprintf
Definition: port.h:192
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintNameExists()

bool ConstraintNameExists ( const char *  conname,
Oid  namespaceid 
)

Definition at line 432 of file pg_constraint.c.

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

Referenced by ChooseRelationName().

433 {
434  bool found;
435  Relation conDesc;
436  SysScanDesc conscan;
437  ScanKeyData skey[2];
438 
439  conDesc = table_open(ConstraintRelationId, AccessShareLock);
440 
441  ScanKeyInit(&skey[0],
442  Anum_pg_constraint_conname,
443  BTEqualStrategyNumber, F_NAMEEQ,
444  CStringGetDatum(conname));
445 
446  ScanKeyInit(&skey[1],
447  Anum_pg_constraint_connamespace,
448  BTEqualStrategyNumber, F_OIDEQ,
449  ObjectIdGetDatum(namespaceid));
450 
451  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
452  NULL, 2, skey);
453 
454  found = (HeapTupleIsValid(systable_getnext(conscan)));
455 
456  systable_endscan(conscan);
457  table_close(conDesc, AccessShareLock);
458 
459  return found;
460 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ConstraintNameNspIndexId
Definition: indexing.h:126
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintNameIsUsed()

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

Definition at line 387 of file pg_constraint.c.

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

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

389 {
390  bool found;
391  Relation conDesc;
392  SysScanDesc conscan;
393  ScanKeyData skey[3];
394 
395  conDesc = table_open(ConstraintRelationId, AccessShareLock);
396 
397  ScanKeyInit(&skey[0],
398  Anum_pg_constraint_conrelid,
399  BTEqualStrategyNumber, F_OIDEQ,
401  ? objId : InvalidOid));
402  ScanKeyInit(&skey[1],
403  Anum_pg_constraint_contypid,
404  BTEqualStrategyNumber, F_OIDEQ,
406  ? objId : InvalidOid));
407  ScanKeyInit(&skey[2],
408  Anum_pg_constraint_conname,
409  BTEqualStrategyNumber, F_NAMEEQ,
410  CStringGetDatum(conname));
411 
413  true, NULL, 3, skey);
414 
415  /* There can be at most one matching row */
416  found = (HeapTupleIsValid(systable_getnext(conscan)));
417 
418  systable_endscan(conscan);
419  table_close(conDesc, AccessShareLock);
420 
421  return found;
422 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintSetParentConstraint()

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

Definition at line 770 of file pg_constraint.c.

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

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

773 {
774  Relation constrRel;
775  Form_pg_constraint constrForm;
776  HeapTuple tuple,
777  newtup;
778  ObjectAddress depender;
779  ObjectAddress referenced;
780 
781  constrRel = table_open(ConstraintRelationId, RowExclusiveLock);
782  tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(childConstrId));
783  if (!HeapTupleIsValid(tuple))
784  elog(ERROR, "cache lookup failed for constraint %u", childConstrId);
785  newtup = heap_copytuple(tuple);
786  constrForm = (Form_pg_constraint) GETSTRUCT(newtup);
787  if (OidIsValid(parentConstrId))
788  {
789  /* don't allow setting parent for a constraint that already has one */
790  Assert(constrForm->coninhcount == 0);
791  if (constrForm->conparentid != InvalidOid)
792  elog(ERROR, "constraint %u already has a parent constraint",
793  childConstrId);
794 
795  constrForm->conislocal = false;
796  constrForm->coninhcount++;
797  constrForm->conparentid = parentConstrId;
798 
799  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
800 
801  ObjectAddressSet(depender, ConstraintRelationId, childConstrId);
802 
803  ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId);
804  recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI);
805 
806  ObjectAddressSet(referenced, RelationRelationId, childTableId);
807  recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC);
808  }
809  else
810  {
811  constrForm->coninhcount--;
812  constrForm->conislocal = true;
813  constrForm->conparentid = InvalidOid;
814 
815  /* Make sure there's no further inheritance. */
816  Assert(constrForm->coninhcount == 0);
817 
818  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
819 
820  deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
821  ConstraintRelationId,
823  deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
824  RelationRelationId,
826  }
827 
828  ReleaseSysCache(tuple);
829  table_close(constrRel, RowExclusiveLock);
830 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:43
#define OidIsValid(objectId)
Definition: c.h:645
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
long deleteDependencyRecordsForClass(Oid classId, Oid objectId, Oid refclassId, char deptype)
Definition: pg_depend.c:240
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:739
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define elog(elevel,...)
Definition: elog.h:228
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ 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,
char  foreignMatchType,
const Oid exclOp,
Node conExpr,
const char *  conBin,
bool  conIsLocal,
int  conInhCount,
bool  conNoInherit,
bool  is_internal 
)

Definition at line 51 of file pg_constraint.c.

References Assert, BoolGetDatum, CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, ConstraintOidIndexId, construct_array(), CStringGetTextDatum, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, GetNewOidWithIndex(), heap_form_tuple(), i, Int16GetDatum, Int32GetDatum, InvokeObjectPostCreateHookArg, NameGetDatum, namestrcpy(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, palloc(), PointerGetDatum, recordDependencyOn(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RowExclusiveLock, table_close(), table_open(), and values.

Referenced by addFkRecurseReferenced(), addFkRecurseReferencing(), CloneFkReferencing(), CreateTrigger(), domainAddConstraint(), index_constraint_create(), and StoreRelCheck().

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

◆ DeconstructFkConstraintRow()

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

Definition at line 1165 of file pg_constraint.c.

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

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

1168 {
1169  Oid constrId;
1170  Datum adatum;
1171  bool isNull;
1172  ArrayType *arr;
1173  int numkeys;
1174 
1175  constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1176 
1177  /*
1178  * We expect the arrays to be 1-D arrays of the right types; verify that.
1179  * We don't need to use deconstruct_array() since the array data is just
1180  * going to look like a C array of values.
1181  */
1182  adatum = SysCacheGetAttr(CONSTROID, tuple,
1183  Anum_pg_constraint_conkey, &isNull);
1184  if (isNull)
1185  elog(ERROR, "null conkey for constraint %u", constrId);
1186  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1187  if (ARR_NDIM(arr) != 1 ||
1188  ARR_HASNULL(arr) ||
1189  ARR_ELEMTYPE(arr) != INT2OID)
1190  elog(ERROR, "conkey is not a 1-D smallint array");
1191  numkeys = ARR_DIMS(arr)[0];
1192  if (numkeys <= 0 || numkeys > INDEX_MAX_KEYS)
1193  elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
1194  memcpy(conkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1195  if ((Pointer) arr != DatumGetPointer(adatum))
1196  pfree(arr); /* free de-toasted copy, if any */
1197 
1198  adatum = SysCacheGetAttr(CONSTROID, tuple,
1199  Anum_pg_constraint_confkey, &isNull);
1200  if (isNull)
1201  elog(ERROR, "null confkey for constraint %u", constrId);
1202  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1203  if (ARR_NDIM(arr) != 1 ||
1204  ARR_DIMS(arr)[0] != numkeys ||
1205  ARR_HASNULL(arr) ||
1206  ARR_ELEMTYPE(arr) != INT2OID)
1207  elog(ERROR, "confkey is not a 1-D smallint array");
1208  memcpy(confkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1209  if ((Pointer) arr != DatumGetPointer(adatum))
1210  pfree(arr); /* free de-toasted copy, if any */
1211 
1212  if (pf_eq_oprs)
1213  {
1214  adatum = SysCacheGetAttr(CONSTROID, tuple,
1215  Anum_pg_constraint_conpfeqop, &isNull);
1216  if (isNull)
1217  elog(ERROR, "null conpfeqop for constraint %u", constrId);
1218  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1219  /* see TryReuseForeignKey if you change the test below */
1220  if (ARR_NDIM(arr) != 1 ||
1221  ARR_DIMS(arr)[0] != numkeys ||
1222  ARR_HASNULL(arr) ||
1223  ARR_ELEMTYPE(arr) != OIDOID)
1224  elog(ERROR, "conpfeqop is not a 1-D Oid array");
1225  memcpy(pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1226  if ((Pointer) arr != DatumGetPointer(adatum))
1227  pfree(arr); /* free de-toasted copy, if any */
1228  }
1229 
1230  if (pp_eq_oprs)
1231  {
1232  adatum = SysCacheGetAttr(CONSTROID, tuple,
1233  Anum_pg_constraint_conppeqop, &isNull);
1234  if (isNull)
1235  elog(ERROR, "null conppeqop for constraint %u", constrId);
1236  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1237  if (ARR_NDIM(arr) != 1 ||
1238  ARR_DIMS(arr)[0] != numkeys ||
1239  ARR_HASNULL(arr) ||
1240  ARR_ELEMTYPE(arr) != OIDOID)
1241  elog(ERROR, "conppeqop is not a 1-D Oid array");
1242  memcpy(pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1243  if ((Pointer) arr != DatumGetPointer(adatum))
1244  pfree(arr); /* free de-toasted copy, if any */
1245  }
1246 
1247  if (ff_eq_oprs)
1248  {
1249  adatum = SysCacheGetAttr(CONSTROID, tuple,
1250  Anum_pg_constraint_conffeqop, &isNull);
1251  if (isNull)
1252  elog(ERROR, "null conffeqop for constraint %u", constrId);
1253  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1254  if (ARR_NDIM(arr) != 1 ||
1255  ARR_DIMS(arr)[0] != numkeys ||
1256  ARR_HASNULL(arr) ||
1257  ARR_ELEMTYPE(arr) != OIDOID)
1258  elog(ERROR, "conffeqop is not a 1-D Oid array");
1259  memcpy(ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1260  if ((Pointer) arr != DatumGetPointer(adatum))
1261  pfree(arr); /* free de-toasted copy, if any */
1262  }
1263 
1264  *numfks = numkeys;
1265 }
signed short int16
Definition: c.h:346
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
unsigned int Oid
Definition: postgres_ext.h:31
void pfree(void *pointer)
Definition: mcxt.c:1056
char * Pointer
Definition: c.h:336
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:282
#define ARR_DATA_PTR(a)
Definition: array.h:310
#define ARR_HASNULL(a)
Definition: array.h:279
uintptr_t Datum
Definition: postgres.h:367
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1377
FormData_pg_constraint * Form_pg_constraint
#define INDEX_MAX_KEYS
#define ARR_NDIM(a)
Definition: array.h:278
#define DatumGetPointer(X)
Definition: postgres.h:549
#define elog(elevel,...)
Definition: elog.h:228
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define DatumGetArrayTypeP(X)
Definition: array.h:249

◆ get_domain_constraint_oid()

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

Definition at line 1021 of file pg_constraint.c.

References AccessShareLock, BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, 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().

1022 {
1023  Relation pg_constraint;
1024  HeapTuple tuple;
1025  SysScanDesc scan;
1026  ScanKeyData skey[3];
1027  Oid conOid = InvalidOid;
1028 
1029  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1030 
1031  ScanKeyInit(&skey[0],
1032  Anum_pg_constraint_conrelid,
1033  BTEqualStrategyNumber, F_OIDEQ,
1035  ScanKeyInit(&skey[1],
1036  Anum_pg_constraint_contypid,
1037  BTEqualStrategyNumber, F_OIDEQ,
1038  ObjectIdGetDatum(typid));
1039  ScanKeyInit(&skey[2],
1040  Anum_pg_constraint_conname,
1041  BTEqualStrategyNumber, F_NAMEEQ,
1042  CStringGetDatum(conname));
1043 
1044  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1045  NULL, 3, skey);
1046 
1047  /* There can be at most one matching row */
1048  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1049  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1050 
1051  systable_endscan(scan);
1052 
1053  /* If no such constraint exists, complain */
1054  if (!OidIsValid(conOid) && !missing_ok)
1055  ereport(ERROR,
1056  (errcode(ERRCODE_UNDEFINED_OBJECT),
1057  errmsg("constraint \"%s\" for domain %s does not exist",
1058  conname, format_type_be(typid))));
1059 
1060  table_close(pg_constraint, AccessShareLock);
1061 
1062  return conOid;
1063 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:608
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:645
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
int errmsg(const char *fmt,...)
Definition: elog.c:822
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_primary_key_attnos()

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

Definition at line 1080 of file pg_constraint.c.

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, 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().

1081 {
1082  Bitmapset *pkattnos = NULL;
1083  Relation pg_constraint;
1084  HeapTuple tuple;
1085  SysScanDesc scan;
1086  ScanKeyData skey[1];
1087 
1088  /* Set *constraintOid, to avoid complaints about uninitialized vars */
1089  *constraintOid = InvalidOid;
1090 
1091  /* Scan pg_constraint for constraints of the target rel */
1092  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1093 
1094  ScanKeyInit(&skey[0],
1095  Anum_pg_constraint_conrelid,
1096  BTEqualStrategyNumber, F_OIDEQ,
1097  ObjectIdGetDatum(relid));
1098 
1099  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1100  NULL, 1, skey);
1101 
1102  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1103  {
1105  Datum adatum;
1106  bool isNull;
1107  ArrayType *arr;
1108  int16 *attnums;
1109  int numkeys;
1110  int i;
1111 
1112  /* Skip constraints that are not PRIMARY KEYs */
1113  if (con->contype != CONSTRAINT_PRIMARY)
1114  continue;
1115 
1116  /*
1117  * If the primary key is deferrable, but we've been instructed to
1118  * ignore deferrable constraints, then we might as well give up
1119  * searching, since there can only be a single primary key on a table.
1120  */
1121  if (con->condeferrable && !deferrableOk)
1122  break;
1123 
1124  /* Extract the conkey array, ie, attnums of PK's columns */
1125  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
1126  RelationGetDescr(pg_constraint), &isNull);
1127  if (isNull)
1128  elog(ERROR, "null conkey for constraint %u",
1129  ((Form_pg_constraint) GETSTRUCT(tuple))->oid);
1130  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1131  numkeys = ARR_DIMS(arr)[0];
1132  if (ARR_NDIM(arr) != 1 ||
1133  numkeys < 0 ||
1134  ARR_HASNULL(arr) ||
1135  ARR_ELEMTYPE(arr) != INT2OID)
1136  elog(ERROR, "conkey is not a 1-D smallint array");
1137  attnums = (int16 *) ARR_DATA_PTR(arr);
1138 
1139  /* Construct the result value */
1140  for (i = 0; i < numkeys; i++)
1141  {
1142  pkattnos = bms_add_member(pkattnos,
1143  attnums[i] - FirstLowInvalidHeapAttributeNumber);
1144  }
1145  *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1146 
1147  /* No need to search further */
1148  break;
1149  }
1150 
1151  systable_endscan(scan);
1152 
1153  table_close(pg_constraint, AccessShareLock);
1154 
1155  return pkattnos;
1156 }
signed short int16
Definition: c.h:346
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:448
#define AccessShareLock
Definition: lockdefs.h:36
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:282
#define ARR_DATA_PTR(a)
Definition: array.h:310
#define ARR_HASNULL(a)
Definition: array.h:279
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
#define ARR_NDIM(a)
Definition: array.h:278
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
#define elog(elevel,...)
Definition: elog.h:228
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define DatumGetArrayTypeP(X)
Definition: array.h:249

◆ get_relation_constraint_attnos()

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

Definition at line 896 of file pg_constraint.c.

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, 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().

898 {
899  Bitmapset *conattnos = NULL;
900  Relation pg_constraint;
901  HeapTuple tuple;
902  SysScanDesc scan;
903  ScanKeyData skey[3];
904 
905  /* Set *constraintOid, to avoid complaints about uninitialized vars */
906  *constraintOid = InvalidOid;
907 
908  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
909 
910  ScanKeyInit(&skey[0],
911  Anum_pg_constraint_conrelid,
912  BTEqualStrategyNumber, F_OIDEQ,
913  ObjectIdGetDatum(relid));
914  ScanKeyInit(&skey[1],
915  Anum_pg_constraint_contypid,
916  BTEqualStrategyNumber, F_OIDEQ,
918  ScanKeyInit(&skey[2],
919  Anum_pg_constraint_conname,
920  BTEqualStrategyNumber, F_NAMEEQ,
921  CStringGetDatum(conname));
922 
923  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
924  NULL, 3, skey);
925 
926  /* There can be at most one matching row */
927  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
928  {
929  Datum adatum;
930  bool isNull;
931 
932  *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
933 
934  /* Extract the conkey array, ie, attnums of constrained columns */
935  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
936  RelationGetDescr(pg_constraint), &isNull);
937  if (!isNull)
938  {
939  ArrayType *arr;
940  int numcols;
941  int16 *attnums;
942  int i;
943 
944  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
945  numcols = ARR_DIMS(arr)[0];
946  if (ARR_NDIM(arr) != 1 ||
947  numcols < 0 ||
948  ARR_HASNULL(arr) ||
949  ARR_ELEMTYPE(arr) != INT2OID)
950  elog(ERROR, "conkey is not a 1-D smallint array");
951  attnums = (int16 *) ARR_DATA_PTR(arr);
952 
953  /* Construct the result value */
954  for (i = 0; i < numcols; i++)
955  {
956  conattnos = bms_add_member(conattnos,
958  }
959  }
960  }
961 
962  systable_endscan(scan);
963 
964  /* If no such constraint exists, complain */
965  if (!OidIsValid(*constraintOid) && !missing_ok)
966  ereport(ERROR,
967  (errcode(ERRCODE_UNDEFINED_OBJECT),
968  errmsg("constraint \"%s\" for table \"%s\" does not exist",
969  conname, get_rel_name(relid))));
970 
971  table_close(pg_constraint, AccessShareLock);
972 
973  return conattnos;
974 }
signed short int16
Definition: c.h:346
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:448
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:608
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
#define OidIsValid(objectId)
Definition: c.h:645
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:282
#define ARR_DATA_PTR(a)
Definition: array.h:310
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ARR_HASNULL(a)
Definition: array.h:279
#define ereport(elevel, rest)
Definition: elog.h:141
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
uintptr_t Datum
Definition: postgres.h:367
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736
#define ARR_NDIM(a)
Definition: array.h:278
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
#define ARR_ELEMTYPE(a)
Definition: array.h:280
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define DatumGetArrayTypeP(X)
Definition: array.h:249

◆ get_relation_constraint_oid()

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

Definition at line 839 of file pg_constraint.c.

References AccessShareLock, BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, 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 get_object_address_relobject(), rename_constraint_internal(), and transformTableLikeClause().

840 {
841  Relation pg_constraint;
842  HeapTuple tuple;
843  SysScanDesc scan;
844  ScanKeyData skey[3];
845  Oid conOid = InvalidOid;
846 
847  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
848 
849  ScanKeyInit(&skey[0],
850  Anum_pg_constraint_conrelid,
851  BTEqualStrategyNumber, F_OIDEQ,
852  ObjectIdGetDatum(relid));
853  ScanKeyInit(&skey[1],
854  Anum_pg_constraint_contypid,
855  BTEqualStrategyNumber, F_OIDEQ,
857  ScanKeyInit(&skey[2],
858  Anum_pg_constraint_conname,
859  BTEqualStrategyNumber, F_NAMEEQ,
860  CStringGetDatum(conname));
861 
862  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
863  NULL, 3, skey);
864 
865  /* There can be at most one matching row */
866  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
867  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
868 
869  systable_endscan(scan);
870 
871  /* If no such constraint exists, complain */
872  if (!OidIsValid(conOid) && !missing_ok)
873  ereport(ERROR,
874  (errcode(ERRCODE_UNDEFINED_OBJECT),
875  errmsg("constraint \"%s\" for table \"%s\" does not exist",
876  conname, get_rel_name(relid))));
877 
878  table_close(pg_constraint, AccessShareLock);
879 
880  return conOid;
881 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:608
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:645
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
int errmsg(const char *fmt,...)
Definition: elog.c:822
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_relation_idx_constraint_oid()

Oid get_relation_idx_constraint_oid ( Oid  relationId,
Oid  indexId 
)

Definition at line 981 of file pg_constraint.c.

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

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

982 {
983  Relation pg_constraint;
984  SysScanDesc scan;
986  HeapTuple tuple;
987  Oid constraintId = InvalidOid;
988 
989  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
990 
991  ScanKeyInit(&key,
992  Anum_pg_constraint_conrelid,
994  F_OIDEQ,
995  ObjectIdGetDatum(relationId));
997  true, NULL, 1, &key);
998  while ((tuple = systable_getnext(scan)) != NULL)
999  {
1000  Form_pg_constraint constrForm;
1001 
1002  constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
1003  if (constrForm->conindid == indexId)
1004  {
1005  constraintId = constrForm->oid;
1006  break;
1007  }
1008  }
1009  systable_endscan(scan);
1010 
1011  table_close(pg_constraint, AccessShareLock);
1012  return constraintId;
1013 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:525
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:352
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:444
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:128
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ RemoveConstraintById()

void RemoveConstraintById ( Oid  conId)

Definition at line 556 of file pg_constraint.c.

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

Referenced by doDeletion().

557 {
558  Relation conDesc;
559  HeapTuple tup;
560  Form_pg_constraint con;
561 
562  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
563 
565  if (!HeapTupleIsValid(tup)) /* should not happen */
566  elog(ERROR, "cache lookup failed for constraint %u", conId);
567  con = (Form_pg_constraint) GETSTRUCT(tup);
568 
569  /*
570  * Special processing depending on what the constraint is for.
571  */
572  if (OidIsValid(con->conrelid))
573  {
574  Relation rel;
575 
576  /*
577  * If the constraint is for a relation, open and exclusive-lock the
578  * relation it's for.
579  */
580  rel = table_open(con->conrelid, AccessExclusiveLock);
581 
582  /*
583  * We need to update the relchecks count if it is a check constraint
584  * being dropped. This update will force backends to rebuild relcache
585  * entries when we commit.
586  */
587  if (con->contype == CONSTRAINT_CHECK)
588  {
589  Relation pgrel;
590  HeapTuple relTup;
591  Form_pg_class classForm;
592 
593  pgrel = table_open(RelationRelationId, RowExclusiveLock);
594  relTup = SearchSysCacheCopy1(RELOID,
595  ObjectIdGetDatum(con->conrelid));
596  if (!HeapTupleIsValid(relTup))
597  elog(ERROR, "cache lookup failed for relation %u",
598  con->conrelid);
599  classForm = (Form_pg_class) GETSTRUCT(relTup);
600 
601  if (classForm->relchecks == 0) /* should not happen */
602  elog(ERROR, "relation \"%s\" has relchecks = 0",
604  classForm->relchecks--;
605 
606  CatalogTupleUpdate(pgrel, &relTup->t_self, relTup);
607 
608  heap_freetuple(relTup);
609 
611  }
612 
613  /* Keep lock on constraint's rel until end of xact */
614  table_close(rel, NoLock);
615  }
616  else if (OidIsValid(con->contypid))
617  {
618  /*
619  * XXX for now, do nothing special when dropping a domain constraint
620  *
621  * Probably there should be some form of locking on the domain type,
622  * but we have no such concept at the moment.
623  */
624  }
625  else
626  elog(ERROR, "constraint %u is not of a known type", conId);
627 
628  /* Fry the constraint itself */
629  CatalogTupleDelete(conDesc, &tup->t_self);
630 
631  /* Clean up */
632  ReleaseSysCache(tup);
633  table_close(conDesc, RowExclusiveLock);
634 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:269
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
#define OidIsValid(objectId)
Definition: c.h:645
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define NoLock
Definition: lockdefs.h:34
#define RowExclusiveLock
Definition: lockdefs.h:38
#define RelationGetRelationName(relation)
Definition: rel.h:456
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1116
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1164
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
FormData_pg_class * Form_pg_class
Definition: pg_class.h:150
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
#define AccessExclusiveLock
Definition: lockdefs.h:45
#define elog(elevel,...)
Definition: elog.h:228
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char *  newname 
)

Definition at line 647 of file pg_constraint.c.

References CatalogTupleUpdate(), CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameIsUsed(), CONSTROID, 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().

648 {
649  Relation conDesc;
650  HeapTuple tuple;
651  Form_pg_constraint con;
652 
653  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
654 
656  if (!HeapTupleIsValid(tuple))
657  elog(ERROR, "cache lookup failed for constraint %u", conId);
658  con = (Form_pg_constraint) GETSTRUCT(tuple);
659 
660  /*
661  * For user-friendliness, check whether the name is already in use.
662  */
663  if (OidIsValid(con->conrelid) &&
665  con->conrelid,
666  newname))
667  ereport(ERROR,
669  errmsg("constraint \"%s\" for relation \"%s\" already exists",
670  newname, get_rel_name(con->conrelid))));
671  if (OidIsValid(con->contypid) &&
673  con->contypid,
674  newname))
675  ereport(ERROR,
677  errmsg("constraint \"%s\" for domain %s already exists",
678  newname, format_type_be(con->contypid))));
679 
680  /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
681  namestrcpy(&(con->conname), newname);
682 
683  CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
684 
685  InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0);
686 
687  heap_freetuple(tuple);
688  table_close(conDesc, RowExclusiveLock);
689 }
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int errcode(int sqlerrcode)
Definition: elog.c:608
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:645
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define ereport(elevel, rest)
Definition: elog.h:141
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:224
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:822
#define elog(elevel,...)
Definition: elog.h:228
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730

Variable Documentation

◆ FormData_pg_constraint

FormData_pg_constraint

Definition at line 147 of file pg_constraint.h.