PostgreSQL Source Code  git master
pg_constraint_fn.h File Reference
#include "catalog/dependency.h"
#include "nodes/pg_list.h"
Include dependency graph for pg_constraint_fn.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef enum ConstraintCategory ConstraintCategory
 

Enumerations

enum  ConstraintCategory { CONSTRAINT_RELATION, CONSTRAINT_DOMAIN, CONSTRAINT_ASSERTION }
 

Functions

Oid CreateConstraintEntry (const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isValidated, Oid relId, const int16 *constraintKey, int constraintNKeys, 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, const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
 
void RemoveConstraintById (Oid conId)
 
void RenameConstraintById (Oid conId, const char *newname)
 
void SetValidatedConstraintById (Oid conId)
 
bool ConstraintNameIsUsed (ConstraintCategory conCat, Oid objId, Oid objNamespace, const char *conname)
 
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)
 
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)
 
Bitmapsetget_primary_key_attnos (Oid relid, bool deferrableOk, Oid *constraintOid)
 
bool check_functional_grouping (Oid relid, Index varno, Index varlevelsup, List *grouping_columns, List **constraintDeps)
 

Typedef Documentation

◆ ConstraintCategory

Enumeration Type Documentation

◆ ConstraintCategory

Enumerator
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 23 of file pg_constraint_fn.h.

Function Documentation

◆ AlterConstraintNamespaces()

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

Definition at line 680 of file pg_constraint.c.

References add_exact_object_address(), Anum_pg_constraint_conrelid, Anum_pg_constraint_contypid, BTEqualStrategyNumber, CatalogTupleUpdate(), ObjectAddress::classId, ConstraintRelationId, ConstraintRelidIndexId, ConstraintTypidIndexId, GETSTRUCT, heap_close, heap_copytuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, object_address_present(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.

Referenced by AlterTableNamespaceInternal(), and AlterTypeNamespaceInternal().

682 {
683  Relation conRel;
684  ScanKeyData key[1];
685  SysScanDesc scan;
686  HeapTuple tup;
687 
689 
690  if (isType)
691  {
692  ScanKeyInit(&key[0],
694  BTEqualStrategyNumber, F_OIDEQ,
695  ObjectIdGetDatum(ownerId));
696 
697  scan = systable_beginscan(conRel, ConstraintTypidIndexId, true,
698  NULL, 1, key);
699  }
700  else
701  {
702  ScanKeyInit(&key[0],
704  BTEqualStrategyNumber, F_OIDEQ,
705  ObjectIdGetDatum(ownerId));
706 
707  scan = systable_beginscan(conRel, ConstraintRelidIndexId, true,
708  NULL, 1, key);
709  }
710 
711  while (HeapTupleIsValid((tup = systable_getnext(scan))))
712  {
714  ObjectAddress thisobj;
715 
716  thisobj.classId = ConstraintRelationId;
717  thisobj.objectId = HeapTupleGetOid(tup);
718  thisobj.objectSubId = 0;
719 
720  if (object_address_present(&thisobj, objsMoved))
721  continue;
722 
723  /* Don't update if the object is already part of the namespace */
724  if (conform->connamespace == oldNspId && oldNspId != newNspId)
725  {
726  tup = heap_copytuple(tup);
727  conform = (Form_pg_constraint) GETSTRUCT(tup);
728 
729  conform->connamespace = newNspId;
730 
731  CatalogTupleUpdate(conRel, &tup->t_self, tup);
732 
733  /*
734  * Note: currently, the constraint will not have its own
735  * dependency on the namespace, so we don't need to do
736  * changeDependencyFor().
737  */
738  }
739 
741 
742  add_exact_object_address(&thisobj, objsMoved);
743  }
744 
745  systable_endscan(scan);
746 
747  heap_close(conRel, RowExclusiveLock);
748 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:611
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2220
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2160
#define heap_close(r, l)
Definition: heapam.h:97
#define ConstraintTypidIndexId
Definition: indexing.h:128
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
#define Anum_pg_constraint_contypid
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
#define Anum_pg_constraint_conrelid
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:700
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126

◆ check_functional_grouping()

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

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

1077 {
1078  Bitmapset *pkattnos;
1079  Bitmapset *groupbyattnos;
1080  Oid constraintOid;
1081  ListCell *gl;
1082 
1083  /* If the rel has no PK, then we can't prove functional dependency */
1084  pkattnos = get_primary_key_attnos(relid, false, &constraintOid);
1085  if (pkattnos == NULL)
1086  return false;
1087 
1088  /* Identify all the rel's columns that appear in grouping_columns */
1089  groupbyattnos = NULL;
1090  foreach(gl, grouping_columns)
1091  {
1092  Var *gvar = (Var *) lfirst(gl);
1093 
1094  if (IsA(gvar, Var) &&
1095  gvar->varno == varno &&
1096  gvar->varlevelsup == varlevelsup)
1097  groupbyattnos = bms_add_member(groupbyattnos,
1099  }
1100 
1101  if (bms_is_subset(pkattnos, groupbyattnos))
1102  {
1103  /* The PK is a subset of grouping_columns, so we win */
1104  *constraintDeps = lappend_oid(*constraintDeps, constraintOid);
1105  return true;
1106  }
1107 
1108  return false;
1109 }
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
Index varlevelsup
Definition: primnodes.h:173
AttrNumber varattno
Definition: primnodes.h:168
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:308
Index varno
Definition: primnodes.h:166
#define lfirst(lc)
Definition: pg_list.h:106
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698

◆ ChooseConstraintName()

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

Definition at line 464 of file pg_constraint.c.

References AccessShareLock, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, BTEqualStrategyNumber, ConstraintNameNspIndexId, ConstraintRelationId, CStringGetDatum, heap_close, heap_open(), HeapTupleIsValid, lfirst, makeObjectName(), NAMEDATALEN, ObjectIdGetDatum, pfree(), ScanKeyInit(), snprintf(), StrNCpy, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by AddRelationNewConstraints(), ATExecAddConstraint(), and domainAddConstraint().

467 {
468  int pass = 0;
469  char *conname = NULL;
470  char modlabel[NAMEDATALEN];
471  Relation conDesc;
472  SysScanDesc conscan;
473  ScanKeyData skey[2];
474  bool found;
475  ListCell *l;
476 
478 
479  /* try the unmodified label first */
480  StrNCpy(modlabel, label, sizeof(modlabel));
481 
482  for (;;)
483  {
484  conname = makeObjectName(name1, name2, modlabel);
485 
486  found = false;
487 
488  foreach(l, others)
489  {
490  if (strcmp((char *) lfirst(l), conname) == 0)
491  {
492  found = true;
493  break;
494  }
495  }
496 
497  if (!found)
498  {
499  ScanKeyInit(&skey[0],
501  BTEqualStrategyNumber, F_NAMEEQ,
502  CStringGetDatum(conname));
503 
504  ScanKeyInit(&skey[1],
506  BTEqualStrategyNumber, F_OIDEQ,
507  ObjectIdGetDatum(namespaceid));
508 
509  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
510  NULL, 2, skey);
511 
512  found = (HeapTupleIsValid(systable_getnext(conscan)));
513 
514  systable_endscan(conscan);
515  }
516 
517  if (!found)
518  break;
519 
520  /* found a conflict, so try a new name component */
521  pfree(conname);
522  snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
523  }
524 
525  heap_close(conDesc, AccessShareLock);
526 
527  return conname;
528 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define AccessShareLock
Definition: lockdefs.h:36
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_constraint_conname
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:1515
#define NAMEDATALEN
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:949
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define CStringGetDatum(X)
Definition: postgres.h:584
static char * label
Definition: pg_basebackup.c:82
#define Anum_pg_constraint_connamespace
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define ConstraintNameNspIndexId
Definition: indexing.h:124
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define lfirst(lc)
Definition: pg_list.h:106
#define StrNCpy(dst, src, len)
Definition: c.h:826
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintNameIsUsed()

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

Definition at line 392 of file pg_constraint.c.

References AccessShareLock, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, BTEqualStrategyNumber, CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameNspIndexId, ConstraintRelationId, CStringGetDatum, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ATExecAddConstraint(), domainAddConstraint(), and RenameConstraintById().

394 {
395  bool found;
396  Relation conDesc;
397  SysScanDesc conscan;
398  ScanKeyData skey[2];
399  HeapTuple tup;
400 
402 
403  found = false;
404 
405  ScanKeyInit(&skey[0],
407  BTEqualStrategyNumber, F_NAMEEQ,
408  CStringGetDatum(conname));
409 
410  ScanKeyInit(&skey[1],
412  BTEqualStrategyNumber, F_OIDEQ,
413  ObjectIdGetDatum(objNamespace));
414 
415  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
416  NULL, 2, skey);
417 
418  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
419  {
421 
422  if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)
423  {
424  found = true;
425  break;
426  }
427  else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)
428  {
429  found = true;
430  break;
431  }
432  }
433 
434  systable_endscan(conscan);
435  heap_close(conDesc, AccessShareLock);
436 
437  return found;
438 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_constraint_conname
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define CStringGetDatum(X)
Definition: postgres.h:584
#define Anum_pg_constraint_connamespace
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define ConstraintNameNspIndexId
Definition: indexing.h:124
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ CreateConstraintEntry()

Oid CreateConstraintEntry ( const char *  constraintName,
Oid  constraintNamespace,
char  constraintType,
bool  isDeferrable,
bool  isDeferred,
bool  isValidated,
Oid  relId,
const int16 constraintKey,
int  constraintNKeys,
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,
const char *  conSrc,
bool  conIsLocal,
int  conInhCount,
bool  conNoInherit,
bool  is_internal 
)

Definition at line 49 of file pg_constraint.c.

References Anum_pg_constraint_conbin, Anum_pg_constraint_condeferrable, Anum_pg_constraint_condeferred, Anum_pg_constraint_conexclop, Anum_pg_constraint_confdeltype, Anum_pg_constraint_conffeqop, Anum_pg_constraint_confkey, Anum_pg_constraint_confmatchtype, Anum_pg_constraint_confrelid, Anum_pg_constraint_confupdtype, Anum_pg_constraint_conindid, Anum_pg_constraint_coninhcount, Anum_pg_constraint_conislocal, Anum_pg_constraint_conkey, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, Anum_pg_constraint_connoinherit, Anum_pg_constraint_conpfeqop, Anum_pg_constraint_conppeqop, Anum_pg_constraint_conrelid, Anum_pg_constraint_consrc, Anum_pg_constraint_contype, Anum_pg_constraint_contypid, Anum_pg_constraint_convalidated, Assert, BoolGetDatum, CatalogTupleInsert(), CharGetDatum, ObjectAddress::classId, CONSTRAINT_FOREIGN, ConstraintRelationId, construct_array(), CStringGetTextDatum, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, heap_close, heap_form_tuple(), heap_open(), i, Int16GetDatum, INT2OID, Int32GetDatum, InvokeObjectPostCreateHookArg, NameGetDatum, namestrcpy(), Natts_pg_constraint, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, OIDOID, OperatorRelationId, palloc(), PointerGetDatum, recordDependencyOn(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RelationRelationId, RowExclusiveLock, TypeRelationId, and values.

Referenced by ATAddForeignKeyConstraint(), CreateTrigger(), domainAddConstraint(), index_constraint_create(), and StoreRelCheck().

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

◆ get_domain_constraint_oid()

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

Definition at line 912 of file pg_constraint.c.

References AccessShareLock, Anum_pg_constraint_contypid, BTEqualStrategyNumber, ConstraintRelationId, ConstraintTypidIndexId, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, format_type_be(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvalidOid, NameStr, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_object_address(), and rename_constraint_internal().

913 {
914  Relation pg_constraint;
915  HeapTuple tuple;
916  SysScanDesc scan;
917  ScanKeyData skey[1];
918  Oid conOid = InvalidOid;
919 
920  /*
921  * Fetch the constraint tuple from pg_constraint. There may be more than
922  * one match, because constraints are not required to have unique names;
923  * if so, error out.
924  */
926 
927  ScanKeyInit(&skey[0],
929  BTEqualStrategyNumber, F_OIDEQ,
930  ObjectIdGetDatum(typid));
931 
932  scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true,
933  NULL, 1, skey);
934 
935  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
936  {
938 
939  if (strcmp(NameStr(con->conname), conname) == 0)
940  {
941  if (OidIsValid(conOid))
942  ereport(ERROR,
944  errmsg("domain %s has multiple constraints named \"%s\"",
945  format_type_be(typid), conname)));
946  conOid = HeapTupleGetOid(tuple);
947  }
948  }
949 
950  systable_endscan(scan);
951 
952  /* If no such constraint exists, complain */
953  if (!OidIsValid(conOid) && !missing_ok)
954  ereport(ERROR,
955  (errcode(ERRCODE_UNDEFINED_OBJECT),
956  errmsg("constraint \"%s\" for domain %s does not exist",
957  conname, format_type_be(typid))));
958 
959  heap_close(pg_constraint, AccessShareLock);
960 
961  return conOid;
962 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:576
#define ConstraintTypidIndexId
Definition: indexing.h:128
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_constraint_contypid
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:547
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:700
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_primary_key_attnos()

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

Definition at line 979 of file pg_constraint.c.

References AccessShareLock, Anum_pg_constraint_conkey, Anum_pg_constraint_conrelid, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, CONSTRAINT_PRIMARY, ConstraintRelationId, ConstraintRelidIndexId, DatumGetArrayTypeP, elog, ERROR, FirstLowInvalidHeapAttributeNumber, GETSTRUCT, heap_close, heap_getattr, heap_open(), HeapTupleGetOid, HeapTupleIsValid, i, INT2OID, InvalidOid, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by check_functional_grouping(), and remove_useless_groupby_columns().

980 {
981  Bitmapset *pkattnos = NULL;
982  Relation pg_constraint;
983  HeapTuple tuple;
984  SysScanDesc scan;
985  ScanKeyData skey[1];
986 
987  /* Set *constraintOid, to avoid complaints about uninitialized vars */
988  *constraintOid = InvalidOid;
989 
990  /* Scan pg_constraint for constraints of the target rel */
992 
993  ScanKeyInit(&skey[0],
995  BTEqualStrategyNumber, F_OIDEQ,
996  ObjectIdGetDatum(relid));
997 
998  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
999  NULL, 1, skey);
1000 
1001  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1002  {
1004  Datum adatum;
1005  bool isNull;
1006  ArrayType *arr;
1007  int16 *attnums;
1008  int numkeys;
1009  int i;
1010 
1011  /* Skip constraints that are not PRIMARY KEYs */
1012  if (con->contype != CONSTRAINT_PRIMARY)
1013  continue;
1014 
1015  /*
1016  * If the primary key is deferrable, but we've been instructed to
1017  * ignore deferrable constraints, then we might as well give up
1018  * searching, since there can only be a single primary key on a table.
1019  */
1020  if (con->condeferrable && !deferrableOk)
1021  break;
1022 
1023  /* Extract the conkey array, ie, attnums of PK's columns */
1024  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
1025  RelationGetDescr(pg_constraint), &isNull);
1026  if (isNull)
1027  elog(ERROR, "null conkey for constraint %u",
1028  HeapTupleGetOid(tuple));
1029  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1030  numkeys = ARR_DIMS(arr)[0];
1031  if (ARR_NDIM(arr) != 1 ||
1032  numkeys < 0 ||
1033  ARR_HASNULL(arr) ||
1034  ARR_ELEMTYPE(arr) != INT2OID)
1035  elog(ERROR, "conkey is not a 1-D smallint array");
1036  attnums = (int16 *) ARR_DATA_PTR(arr);
1037 
1038  /* Construct the result value */
1039  for (i = 0; i < numkeys; i++)
1040  {
1041  pkattnos = bms_add_member(pkattnos,
1042  attnums[i] - FirstLowInvalidHeapAttributeNumber);
1043  }
1044  *constraintOid = HeapTupleGetOid(tuple);
1045 
1046  /* No need to search further */
1047  break;
1048  }
1049 
1050  systable_endscan(scan);
1051 
1052  heap_close(pg_constraint, AccessShareLock);
1053 
1054  return pkattnos;
1055 }
signed short int16
Definition: c.h:283
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define RelationGetDescr(relation)
Definition: rel.h:437
#define AccessShareLock
Definition: lockdefs.h:36
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define CONSTRAINT_PRIMARY
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:279
#define INT2OID
Definition: pg_type.h:308
#define ARR_DATA_PTR(a)
Definition: array.h:307
#define ARR_HASNULL(a)
Definition: array.h:276
#define Anum_pg_constraint_conkey
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:774
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define ARR_NDIM(a)
Definition: array.h:275
int i
#define Anum_pg_constraint_conrelid
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:700
#define ARR_ELEMTYPE(a)
Definition: array.h:277
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126
#define DatumGetArrayTypeP(X)
Definition: array.h:246

◆ get_relation_constraint_attnos()

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

Definition at line 821 of file pg_constraint.c.

References AccessShareLock, Anum_pg_constraint_conkey, Anum_pg_constraint_conrelid, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, ConstraintRelationId, ConstraintRelidIndexId, DatumGetArrayTypeP, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, FirstLowInvalidHeapAttributeNumber, get_rel_name(), GETSTRUCT, heap_close, heap_getattr, heap_open(), HeapTupleGetOid, HeapTupleIsValid, i, INT2OID, InvalidOid, NameStr, ObjectIdGetDatum, OidIsValid, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by transformOnConflictArbiter().

823 {
824  Bitmapset *conattnos = NULL;
825  Relation pg_constraint;
826  HeapTuple tuple;
827  SysScanDesc scan;
828  ScanKeyData skey[1];
829 
830  /* Set *constraintOid, to avoid complaints about uninitialized vars */
831  *constraintOid = InvalidOid;
832 
833  /*
834  * Fetch the constraint tuple from pg_constraint. There may be more than
835  * one match, because constraints are not required to have unique names;
836  * if so, error out.
837  */
839 
840  ScanKeyInit(&skey[0],
842  BTEqualStrategyNumber, F_OIDEQ,
843  ObjectIdGetDatum(relid));
844 
845  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
846  NULL, 1, skey);
847 
848  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
849  {
851  Datum adatum;
852  bool isNull;
853  ArrayType *arr;
854  int16 *attnums;
855  int numcols;
856  int i;
857 
858  /* Check the constraint name */
859  if (strcmp(NameStr(con->conname), conname) != 0)
860  continue;
861  if (OidIsValid(*constraintOid))
862  ereport(ERROR,
864  errmsg("table \"%s\" has multiple constraints named \"%s\"",
865  get_rel_name(relid), conname)));
866 
867  *constraintOid = HeapTupleGetOid(tuple);
868 
869  /* Extract the conkey array, ie, attnums of constrained columns */
870  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
871  RelationGetDescr(pg_constraint), &isNull);
872  if (isNull)
873  continue; /* no constrained columns */
874 
875  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
876  numcols = ARR_DIMS(arr)[0];
877  if (ARR_NDIM(arr) != 1 ||
878  numcols < 0 ||
879  ARR_HASNULL(arr) ||
880  ARR_ELEMTYPE(arr) != INT2OID)
881  elog(ERROR, "conkey is not a 1-D smallint array");
882  attnums = (int16 *) ARR_DATA_PTR(arr);
883 
884  /* Construct the result value */
885  for (i = 0; i < numcols; i++)
886  {
887  conattnos = bms_add_member(conattnos,
889  }
890  }
891 
892  systable_endscan(scan);
893 
894  /* If no such constraint exists, complain */
895  if (!OidIsValid(*constraintOid) && !missing_ok)
896  ereport(ERROR,
897  (errcode(ERRCODE_UNDEFINED_OBJECT),
898  errmsg("constraint \"%s\" for table \"%s\" does not exist",
899  conname, get_rel_name(relid))));
900 
901  heap_close(pg_constraint, AccessShareLock);
902 
903  return conattnos;
904 }
signed short int16
Definition: c.h:283
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define RelationGetDescr(relation)
Definition: rel.h:437
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
#define heap_close(r, l)
Definition: heapam.h:97
#define OidIsValid(objectId)
Definition: c.h:576
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:279
#define INT2OID
Definition: pg_type.h:308
#define ARR_DATA_PTR(a)
Definition: array.h:307
#define ARR_HASNULL(a)
Definition: array.h:276
#define ereport(elevel, rest)
Definition: elog.h:122
#define Anum_pg_constraint_conkey
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:774
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define ARR_NDIM(a)
Definition: array.h:275
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:547
#define Anum_pg_constraint_conrelid
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:700
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1745
#define ARR_ELEMTYPE(a)
Definition: array.h:277
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126
#define DatumGetArrayTypeP(X)
Definition: array.h:246

◆ get_relation_constraint_oid()

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

Definition at line 756 of file pg_constraint.c.

References AccessShareLock, Anum_pg_constraint_conrelid, BTEqualStrategyNumber, ConstraintRelationId, ConstraintRelidIndexId, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, get_rel_name(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvalidOid, NameStr, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_object_address_relobject(), rename_constraint_internal(), and transformTableLikeClause().

757 {
758  Relation pg_constraint;
759  HeapTuple tuple;
760  SysScanDesc scan;
761  ScanKeyData skey[1];
762  Oid conOid = InvalidOid;
763 
764  /*
765  * Fetch the constraint tuple from pg_constraint. There may be more than
766  * one match, because constraints are not required to have unique names;
767  * if so, error out.
768  */
770 
771  ScanKeyInit(&skey[0],
773  BTEqualStrategyNumber, F_OIDEQ,
774  ObjectIdGetDatum(relid));
775 
776  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
777  NULL, 1, skey);
778 
779  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
780  {
782 
783  if (strcmp(NameStr(con->conname), conname) == 0)
784  {
785  if (OidIsValid(conOid))
786  ereport(ERROR,
788  errmsg("table \"%s\" has multiple constraints named \"%s\"",
789  get_rel_name(relid), conname)));
790  conOid = HeapTupleGetOid(tuple);
791  }
792  }
793 
794  systable_endscan(scan);
795 
796  /* If no such constraint exists, complain */
797  if (!OidIsValid(conOid) && !missing_ok)
798  ereport(ERROR,
799  (errcode(ERRCODE_UNDEFINED_OBJECT),
800  errmsg("constraint \"%s\" for table \"%s\" does not exist",
801  conname, get_rel_name(relid))));
802 
803  heap_close(pg_constraint, AccessShareLock);
804 
805  return conOid;
806 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:576
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:547
#define Anum_pg_constraint_conrelid
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:700
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1745
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126

◆ RemoveConstraintById()

void RemoveConstraintById ( Oid  conId)

Definition at line 534 of file pg_constraint.c.

References AccessExclusiveLock, CatalogTupleDelete(), CatalogTupleUpdate(), CONSTRAINT_CHECK, ConstraintRelationId, CONSTROID, elog, ERROR, GETSTRUCT, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, NoLock, ObjectIdGetDatum, OidIsValid, RelationGetRelationName, RelationRelationId, ReleaseSysCache(), RELOID, RowExclusiveLock, SearchSysCache1(), SearchSysCacheCopy1, and HeapTupleData::t_self.

Referenced by doDeletion().

535 {
536  Relation conDesc;
537  HeapTuple tup;
538  Form_pg_constraint con;
539 
541 
543  if (!HeapTupleIsValid(tup)) /* should not happen */
544  elog(ERROR, "cache lookup failed for constraint %u", conId);
545  con = (Form_pg_constraint) GETSTRUCT(tup);
546 
547  /*
548  * Special processing depending on what the constraint is for.
549  */
550  if (OidIsValid(con->conrelid))
551  {
552  Relation rel;
553 
554  /*
555  * If the constraint is for a relation, open and exclusive-lock the
556  * relation it's for.
557  */
558  rel = heap_open(con->conrelid, AccessExclusiveLock);
559 
560  /*
561  * We need to update the relcheck count if it is a check constraint
562  * being dropped. This update will force backends to rebuild relcache
563  * entries when we commit.
564  */
565  if (con->contype == CONSTRAINT_CHECK)
566  {
567  Relation pgrel;
568  HeapTuple relTup;
569  Form_pg_class classForm;
570 
572  relTup = SearchSysCacheCopy1(RELOID,
573  ObjectIdGetDatum(con->conrelid));
574  if (!HeapTupleIsValid(relTup))
575  elog(ERROR, "cache lookup failed for relation %u",
576  con->conrelid);
577  classForm = (Form_pg_class) GETSTRUCT(relTup);
578 
579  if (classForm->relchecks == 0) /* should not happen */
580  elog(ERROR, "relation \"%s\" has relchecks = 0",
582  classForm->relchecks--;
583 
584  CatalogTupleUpdate(pgrel, &relTup->t_self, relTup);
585 
586  heap_freetuple(relTup);
587 
589  }
590 
591  /* Keep lock on constraint's rel until end of xact */
592  heap_close(rel, NoLock);
593  }
594  else if (OidIsValid(con->contypid))
595  {
596  /*
597  * XXX for now, do nothing special when dropping a domain constraint
598  *
599  * Probably there should be some form of locking on the domain type,
600  * but we have no such concept at the moment.
601  */
602  }
603  else
604  elog(ERROR, "constraint %u is not of a known type", conId);
605 
606  /* Fry the constraint itself */
607  CatalogTupleDelete(conDesc, &tup->t_self);
608 
609  /* Clean up */
610  ReleaseSysCache(tup);
611  heap_close(conDesc, RowExclusiveLock);
612 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
#define RelationRelationId
Definition: pg_class.h:29
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:255
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
#define OidIsValid(objectId)
Definition: c.h:576
#define CONSTRAINT_CHECK
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:445
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
#define AccessExclusiveLock
Definition: lockdefs.h:45
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define elog
Definition: elog.h:219

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char *  newname 
)

Definition at line 625 of file pg_constraint.c.

References CatalogTupleUpdate(), CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameIsUsed(), ConstraintRelationId, CONSTROID, elog, ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, format_type_be(), get_rel_name(), GETSTRUCT, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, InvokeObjectPostAlterHook, namestrcpy(), ObjectIdGetDatum, OidIsValid, RowExclusiveLock, SearchSysCacheCopy1, and HeapTupleData::t_self.

Referenced by rename_constraint_internal(), and RenameRelationInternal().

626 {
627  Relation conDesc;
628  HeapTuple tuple;
629  Form_pg_constraint con;
630 
632 
634  if (!HeapTupleIsValid(tuple))
635  elog(ERROR, "cache lookup failed for constraint %u", conId);
636  con = (Form_pg_constraint) GETSTRUCT(tuple);
637 
638  /*
639  * We need to check whether the name is already in use --- note that there
640  * currently is not a unique index that would catch this.
641  */
642  if (OidIsValid(con->conrelid) &&
644  con->conrelid,
645  con->connamespace,
646  newname))
647  ereport(ERROR,
649  errmsg("constraint \"%s\" for relation \"%s\" already exists",
650  newname, get_rel_name(con->conrelid))));
651  if (OidIsValid(con->contypid) &&
653  con->contypid,
654  con->connamespace,
655  newname))
656  ereport(ERROR,
658  errmsg("constraint \"%s\" for domain %s already exists",
659  newname, format_type_be(con->contypid))));
660 
661  /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
662  namestrcpy(&(con->conname), newname);
663 
664  CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
665 
667 
668  heap_freetuple(tuple);
669  heap_close(conDesc, RowExclusiveLock);
670 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:661
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1373
int namestrcpy(Name name, const char *str)
Definition: name.c:216
#define OidIsValid(objectId)
Definition: c.h:576
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#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:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1290
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, Oid objNamespace, const char *conname)
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define elog
Definition: elog.h:219
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:30
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1745

◆ SetValidatedConstraintById()

void SetValidatedConstraintById ( Oid  conId)