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

700 {
701  Relation conRel;
702  ScanKeyData key[2];
703  SysScanDesc scan;
704  HeapTuple tup;
705 
706  conRel = table_open(ConstraintRelationId, RowExclusiveLock);
707 
708  ScanKeyInit(&key[0],
709  Anum_pg_constraint_conrelid,
710  BTEqualStrategyNumber, F_OIDEQ,
711  ObjectIdGetDatum(isType ? InvalidOid : ownerId));
712  ScanKeyInit(&key[1],
713  Anum_pg_constraint_contypid,
714  BTEqualStrategyNumber, F_OIDEQ,
715  ObjectIdGetDatum(isType ? ownerId : InvalidOid));
716 
718  NULL, 2, key);
719 
720  while (HeapTupleIsValid((tup = systable_getnext(scan))))
721  {
723  ObjectAddress thisobj;
724 
725  thisobj.classId = ConstraintRelationId;
726  thisobj.objectId = conform->oid;
727  thisobj.objectSubId = 0;
728 
729  if (object_address_present(&thisobj, objsMoved))
730  continue;
731 
732  /* Don't update if the object is already part of the namespace */
733  if (conform->connamespace == oldNspId && oldNspId != newNspId)
734  {
735  tup = heap_copytuple(tup);
736  conform = (Form_pg_constraint) GETSTRUCT(tup);
737 
738  conform->connamespace = newNspId;
739 
740  CatalogTupleUpdate(conRel, &tup->t_self, tup);
741 
742  /*
743  * Note: currently, the constraint will not have its own
744  * dependency on the namespace, so we don't need to do
745  * changeDependencyFor().
746  */
747  }
748 
749  InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0);
750 
751  add_exact_object_address(&thisobj, objsMoved);
752  }
753 
754  systable_endscan(scan);
755 
756  table_close(conRel, RowExclusiveLock);
757 }
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:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2533
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2473
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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:354
FormData_pg_constraint
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:355
Definition: c.h:609

◆ check_functional_grouping()

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

Definition at line 1282 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().

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

488 {
489  int pass = 0;
490  char *conname = NULL;
491  char modlabel[NAMEDATALEN];
492  Relation conDesc;
493  SysScanDesc conscan;
494  ScanKeyData skey[2];
495  bool found;
496  ListCell *l;
497 
498  conDesc = table_open(ConstraintRelationId, AccessShareLock);
499 
500  /* try the unmodified label first */
501  StrNCpy(modlabel, label, sizeof(modlabel));
502 
503  for (;;)
504  {
505  conname = makeObjectName(name1, name2, modlabel);
506 
507  found = false;
508 
509  foreach(l, others)
510  {
511  if (strcmp((char *) lfirst(l), conname) == 0)
512  {
513  found = true;
514  break;
515  }
516  }
517 
518  if (!found)
519  {
520  ScanKeyInit(&skey[0],
521  Anum_pg_constraint_conname,
522  BTEqualStrategyNumber, F_NAMEEQ,
523  CStringGetDatum(conname));
524 
525  ScanKeyInit(&skey[1],
526  Anum_pg_constraint_connamespace,
527  BTEqualStrategyNumber, F_OIDEQ,
528  ObjectIdGetDatum(namespaceid));
529 
530  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
531  NULL, 2, skey);
532 
533  found = (HeapTupleIsValid(systable_getnext(conscan)));
534 
535  systable_endscan(conscan);
536  }
537 
538  if (!found)
539  break;
540 
541  /* found a conflict, so try a new name component */
542  pfree(conname);
543  snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
544  }
545 
546  table_close(conDesc, AccessShareLock);
547 
548  return conname;
549 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:2154
#define NAMEDATALEN
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
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:944
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:193
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintNameExists()

bool ConstraintNameExists ( const char *  conname,
Oid  namespaceid 
)

Definition at line 431 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().

432 {
433  bool found;
434  Relation conDesc;
435  SysScanDesc conscan;
436  ScanKeyData skey[2];
437 
438  conDesc = table_open(ConstraintRelationId, AccessShareLock);
439 
440  ScanKeyInit(&skey[0],
441  Anum_pg_constraint_conname,
442  BTEqualStrategyNumber, F_NAMEEQ,
443  CStringGetDatum(conname));
444 
445  ScanKeyInit(&skey[1],
446  Anum_pg_constraint_connamespace,
447  BTEqualStrategyNumber, F_OIDEQ,
448  ObjectIdGetDatum(namespaceid));
449 
450  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
451  NULL, 2, skey);
452 
453  found = (HeapTupleIsValid(systable_getnext(conscan)));
454 
455  systable_endscan(conscan);
456  table_close(conDesc, AccessShareLock);
457 
458  return found;
459 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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 386 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().

388 {
389  bool found;
390  Relation conDesc;
391  SysScanDesc conscan;
392  ScanKeyData skey[3];
393 
394  conDesc = table_open(ConstraintRelationId, AccessShareLock);
395 
396  ScanKeyInit(&skey[0],
397  Anum_pg_constraint_conrelid,
398  BTEqualStrategyNumber, F_OIDEQ,
400  ? objId : InvalidOid));
401  ScanKeyInit(&skey[1],
402  Anum_pg_constraint_contypid,
403  BTEqualStrategyNumber, F_OIDEQ,
405  ? objId : InvalidOid));
406  ScanKeyInit(&skey[2],
407  Anum_pg_constraint_conname,
408  BTEqualStrategyNumber, F_NAMEEQ,
409  CStringGetDatum(conname));
410 
412  true, NULL, 3, skey);
413 
414  /* There can be at most one matching row */
415  found = (HeapTupleIsValid(systable_getnext(conscan)));
416 
417  systable_endscan(conscan);
418  table_close(conDesc, AccessShareLock);
419 
420  return found;
421 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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 769 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().

772 {
773  Relation constrRel;
774  Form_pg_constraint constrForm;
775  HeapTuple tuple,
776  newtup;
777  ObjectAddress depender;
778  ObjectAddress referenced;
779 
780  constrRel = table_open(ConstraintRelationId, RowExclusiveLock);
781  tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(childConstrId));
782  if (!HeapTupleIsValid(tuple))
783  elog(ERROR, "cache lookup failed for constraint %u", childConstrId);
784  newtup = heap_copytuple(tuple);
785  constrForm = (Form_pg_constraint) GETSTRUCT(newtup);
786  if (OidIsValid(parentConstrId))
787  {
788  /* don't allow setting parent for a constraint that already has one */
789  Assert(constrForm->coninhcount == 0);
790  if (constrForm->conparentid != InvalidOid)
791  elog(ERROR, "constraint %u already has a parent constraint",
792  childConstrId);
793 
794  constrForm->conislocal = false;
795  constrForm->coninhcount++;
796  constrForm->conparentid = parentConstrId;
797 
798  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
799 
800  ObjectAddressSet(depender, ConstraintRelationId, childConstrId);
801 
802  ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId);
803  recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_PRI);
804 
805  ObjectAddressSet(referenced, RelationRelationId, childTableId);
806  recordDependencyOn(&depender, &referenced, DEPENDENCY_PARTITION_SEC);
807  }
808  else
809  {
810  constrForm->coninhcount--;
811  constrForm->conislocal = true;
812  constrForm->conparentid = InvalidOid;
813 
814  /* Make sure there's no further inheritance. */
815  Assert(constrForm->coninhcount == 0);
816 
817  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
818 
819  deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
820  ConstraintRelationId,
822  deleteDependencyRecordsForClass(ConstraintRelationId, childConstrId,
823  RelationRelationId,
825  }
826 
827  ReleaseSysCache(tuple);
828  table_close(constrRel, RowExclusiveLock);
829 }
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:644
#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:738
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:214
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 50 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().

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

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

1021 {
1022  Relation pg_constraint;
1023  HeapTuple tuple;
1024  SysScanDesc scan;
1025  ScanKeyData skey[3];
1026  Oid conOid = InvalidOid;
1027 
1028  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1029 
1030  ScanKeyInit(&skey[0],
1031  Anum_pg_constraint_conrelid,
1032  BTEqualStrategyNumber, F_OIDEQ,
1034  ScanKeyInit(&skey[1],
1035  Anum_pg_constraint_contypid,
1036  BTEqualStrategyNumber, F_OIDEQ,
1037  ObjectIdGetDatum(typid));
1038  ScanKeyInit(&skey[2],
1039  Anum_pg_constraint_conname,
1040  BTEqualStrategyNumber, F_NAMEEQ,
1041  CStringGetDatum(conname));
1042 
1043  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1044  NULL, 3, skey);
1045 
1046  /* There can be at most one matching row */
1047  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1048  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1049 
1050  systable_endscan(scan);
1051 
1052  /* If no such constraint exists, complain */
1053  if (!OidIsValid(conOid) && !missing_ok)
1054  ereport(ERROR,
1055  (errcode(ERRCODE_UNDEFINED_OBJECT),
1056  errmsg("constraint \"%s\" for domain %s does not exist",
1057  conname, format_type_be(typid))));
1058 
1059  table_close(pg_constraint, AccessShareLock);
1060 
1061  return conOid;
1062 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:327
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
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:824
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 1079 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().

1080 {
1081  Bitmapset *pkattnos = NULL;
1082  Relation pg_constraint;
1083  HeapTuple tuple;
1084  SysScanDesc scan;
1085  ScanKeyData skey[1];
1086 
1087  /* Set *constraintOid, to avoid complaints about uninitialized vars */
1088  *constraintOid = InvalidOid;
1089 
1090  /* Scan pg_constraint for constraints of the target rel */
1091  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1092 
1093  ScanKeyInit(&skey[0],
1094  Anum_pg_constraint_conrelid,
1095  BTEqualStrategyNumber, F_OIDEQ,
1096  ObjectIdGetDatum(relid));
1097 
1098  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1099  NULL, 1, skey);
1100 
1101  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1102  {
1104  Datum adatum;
1105  bool isNull;
1106  ArrayType *arr;
1107  int16 *attnums;
1108  int numkeys;
1109  int i;
1110 
1111  /* Skip constraints that are not PRIMARY KEYs */
1112  if (con->contype != CONSTRAINT_PRIMARY)
1113  continue;
1114 
1115  /*
1116  * If the primary key is deferrable, but we've been instructed to
1117  * ignore deferrable constraints, then we might as well give up
1118  * searching, since there can only be a single primary key on a table.
1119  */
1120  if (con->condeferrable && !deferrableOk)
1121  break;
1122 
1123  /* Extract the conkey array, ie, attnums of PK's columns */
1124  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
1125  RelationGetDescr(pg_constraint), &isNull);
1126  if (isNull)
1127  elog(ERROR, "null conkey for constraint %u",
1128  ((Form_pg_constraint) GETSTRUCT(tuple))->oid);
1129  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1130  numkeys = ARR_DIMS(arr)[0];
1131  if (ARR_NDIM(arr) != 1 ||
1132  numkeys < 0 ||
1133  ARR_HASNULL(arr) ||
1134  ARR_ELEMTYPE(arr) != INT2OID)
1135  elog(ERROR, "conkey is not a 1-D smallint array");
1136  attnums = (int16 *) ARR_DATA_PTR(arr);
1137 
1138  /* Construct the result value */
1139  for (i = 0; i < numkeys; i++)
1140  {
1141  pkattnos = bms_add_member(pkattnos,
1142  attnums[i] - FirstLowInvalidHeapAttributeNumber);
1143  }
1144  *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1145 
1146  /* No need to search further */
1147  break;
1148  }
1149 
1150  systable_endscan(scan);
1151 
1152  table_close(pg_constraint, AccessShareLock);
1153 
1154  return pkattnos;
1155 }
signed short int16
Definition: c.h:354
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:482
#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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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:214
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 895 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().

897 {
898  Bitmapset *conattnos = NULL;
899  Relation pg_constraint;
900  HeapTuple tuple;
901  SysScanDesc scan;
902  ScanKeyData skey[3];
903 
904  /* Set *constraintOid, to avoid complaints about uninitialized vars */
905  *constraintOid = InvalidOid;
906 
907  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
908 
909  ScanKeyInit(&skey[0],
910  Anum_pg_constraint_conrelid,
911  BTEqualStrategyNumber, F_OIDEQ,
912  ObjectIdGetDatum(relid));
913  ScanKeyInit(&skey[1],
914  Anum_pg_constraint_contypid,
915  BTEqualStrategyNumber, F_OIDEQ,
917  ScanKeyInit(&skey[2],
918  Anum_pg_constraint_conname,
919  BTEqualStrategyNumber, F_NAMEEQ,
920  CStringGetDatum(conname));
921 
922  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
923  NULL, 3, skey);
924 
925  /* There can be at most one matching row */
926  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
927  {
928  Datum adatum;
929  bool isNull;
930 
931  *constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
932 
933  /* Extract the conkey array, ie, attnums of constrained columns */
934  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
935  RelationGetDescr(pg_constraint), &isNull);
936  if (!isNull)
937  {
938  ArrayType *arr;
939  int numcols;
940  int16 *attnums;
941  int i;
942 
943  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
944  numcols = ARR_DIMS(arr)[0];
945  if (ARR_NDIM(arr) != 1 ||
946  numcols < 0 ||
947  ARR_HASNULL(arr) ||
948  ARR_ELEMTYPE(arr) != INT2OID)
949  elog(ERROR, "conkey is not a 1-D smallint array");
950  attnums = (int16 *) ARR_DATA_PTR(arr);
951 
952  /* Construct the result value */
953  for (i = 0; i < numcols; i++)
954  {
955  conattnos = bms_add_member(conattnos,
957  }
958  }
959  }
960 
961  systable_endscan(scan);
962 
963  /* If no such constraint exists, complain */
964  if (!OidIsValid(*constraintOid) && !missing_ok)
965  ereport(ERROR,
966  (errcode(ERRCODE_UNDEFINED_OBJECT),
967  errmsg("constraint \"%s\" for table \"%s\" does not exist",
968  conname, get_rel_name(relid))));
969 
970  table_close(pg_constraint, AccessShareLock);
971 
972  return conattnos;
973 }
signed short int16
Definition: c.h:354
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define RelationGetDescr(relation)
Definition: rel.h:482
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
#define OidIsValid(objectId)
Definition: c.h:644
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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 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
#define ereport(elevel,...)
Definition: elog.h:144
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:824
#define elog(elevel,...)
Definition: elog.h:214
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:1791
#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 838 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().

839 {
840  Relation pg_constraint;
841  HeapTuple tuple;
842  SysScanDesc scan;
843  ScanKeyData skey[3];
844  Oid conOid = InvalidOid;
845 
846  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
847 
848  ScanKeyInit(&skey[0],
849  Anum_pg_constraint_conrelid,
850  BTEqualStrategyNumber, F_OIDEQ,
851  ObjectIdGetDatum(relid));
852  ScanKeyInit(&skey[1],
853  Anum_pg_constraint_contypid,
854  BTEqualStrategyNumber, F_OIDEQ,
856  ScanKeyInit(&skey[2],
857  Anum_pg_constraint_conname,
858  BTEqualStrategyNumber, F_NAMEEQ,
859  CStringGetDatum(conname));
860 
861  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
862  NULL, 3, skey);
863 
864  /* There can be at most one matching row */
865  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
866  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
867 
868  systable_endscan(scan);
869 
870  /* If no such constraint exists, complain */
871  if (!OidIsValid(conOid) && !missing_ok)
872  ereport(ERROR,
873  (errcode(ERRCODE_UNDEFINED_OBJECT),
874  errmsg("constraint \"%s\" for table \"%s\" does not exist",
875  conname, get_rel_name(relid))));
876 
877  table_close(pg_constraint, AccessShareLock);
878 
879  return conOid;
880 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:644
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
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:824
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:1791
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_relation_idx_constraint_oid()

Oid get_relation_idx_constraint_oid ( Oid  relationId,
Oid  indexId 
)

Definition at line 980 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().

981 {
982  Relation pg_constraint;
983  SysScanDesc scan;
985  HeapTuple tuple;
986  Oid constraintId = InvalidOid;
987 
988  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
989 
990  ScanKeyInit(&key,
991  Anum_pg_constraint_conrelid,
993  F_OIDEQ,
994  ObjectIdGetDatum(relationId));
996  true, NULL, 1, &key);
997  while ((tuple = systable_getnext(scan)) != NULL)
998  {
999  Form_pg_constraint constrForm;
1000 
1001  constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
1002  if (constrForm->conindid == indexId)
1003  {
1004  constraintId = constrForm->oid;
1005  break;
1006  }
1007  }
1008  systable_endscan(scan);
1009 
1010  table_close(pg_constraint, AccessShareLock);
1011  return constraintId;
1012 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#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:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#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 555 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().

556 {
557  Relation conDesc;
558  HeapTuple tup;
559  Form_pg_constraint con;
560 
561  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
562 
564  if (!HeapTupleIsValid(tup)) /* should not happen */
565  elog(ERROR, "cache lookup failed for constraint %u", conId);
566  con = (Form_pg_constraint) GETSTRUCT(tup);
567 
568  /*
569  * Special processing depending on what the constraint is for.
570  */
571  if (OidIsValid(con->conrelid))
572  {
573  Relation rel;
574 
575  /*
576  * If the constraint is for a relation, open and exclusive-lock the
577  * relation it's for.
578  */
579  rel = table_open(con->conrelid, AccessExclusiveLock);
580 
581  /*
582  * We need to update the relchecks count if it is a check constraint
583  * being dropped. This update will force backends to rebuild relcache
584  * entries when we commit.
585  */
586  if (con->contype == CONSTRAINT_CHECK)
587  {
588  Relation pgrel;
589  HeapTuple relTup;
590  Form_pg_class classForm;
591 
592  pgrel = table_open(RelationRelationId, RowExclusiveLock);
593  relTup = SearchSysCacheCopy1(RELOID,
594  ObjectIdGetDatum(con->conrelid));
595  if (!HeapTupleIsValid(relTup))
596  elog(ERROR, "cache lookup failed for relation %u",
597  con->conrelid);
598  classForm = (Form_pg_class) GETSTRUCT(relTup);
599 
600  if (classForm->relchecks == 0) /* should not happen */
601  elog(ERROR, "relation \"%s\" has relchecks = 0",
603  classForm->relchecks--;
604 
605  CatalogTupleUpdate(pgrel, &relTup->t_self, relTup);
606 
607  heap_freetuple(relTup);
608 
610  }
611 
612  /* Keep lock on constraint's rel until end of xact */
613  table_close(rel, NoLock);
614  }
615  else if (OidIsValid(con->contypid))
616  {
617  /*
618  * XXX for now, do nothing special when dropping a domain constraint
619  *
620  * Probably there should be some form of locking on the domain type,
621  * but we have no such concept at the moment.
622  */
623  }
624  else
625  elog(ERROR, "constraint %u is not of a known type", conId);
626 
627  /* Fry the constraint itself */
628  CatalogTupleDelete(conDesc, &tup->t_self);
629 
630  /* Clean up */
631  ReleaseSysCache(tup);
632  table_close(conDesc, RowExclusiveLock);
633 }
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:644
#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:490
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:153
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
#define AccessExclusiveLock
Definition: lockdefs.h:45
#define elog(elevel,...)
Definition: elog.h:214
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char *  newname 
)

Definition at line 646 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().

647 {
648  Relation conDesc;
649  HeapTuple tuple;
650  Form_pg_constraint con;
651 
652  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
653 
655  if (!HeapTupleIsValid(tuple))
656  elog(ERROR, "cache lookup failed for constraint %u", conId);
657  con = (Form_pg_constraint) GETSTRUCT(tuple);
658 
659  /*
660  * For user-friendliness, check whether the name is already in use.
661  */
662  if (OidIsValid(con->conrelid) &&
664  con->conrelid,
665  newname))
666  ereport(ERROR,
668  errmsg("constraint \"%s\" for relation \"%s\" already exists",
669  newname, get_rel_name(con->conrelid))));
670  if (OidIsValid(con->contypid) &&
672  con->contypid,
673  newname))
674  ereport(ERROR,
676  errmsg("constraint \"%s\" for domain %s already exists",
677  newname, format_type_be(con->contypid))));
678 
679  /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
680  namestrcpy(&(con->conname), newname);
681 
682  CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
683 
684  InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0);
685 
686  heap_freetuple(tuple);
687  table_close(conDesc, RowExclusiveLock);
688 }
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:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:327
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:644
#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 InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
#define ereport(elevel,...)
Definition: elog.h:144
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:824
#define elog(elevel,...)
Definition: elog.h:214
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:1791

Variable Documentation

◆ FormData_pg_constraint

FormData_pg_constraint

Definition at line 147 of file pg_constraint.h.