PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_constraint.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_constraint_fn.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
Include dependency graph for pg_constraint.c:

Go to the source code of this file.

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)
 
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 RemoveConstraintById (Oid conId)
 
void RenameConstraintById (Oid conId, const char *newname)
 
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)
 
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)
 

Function Documentation

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, NULL, 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:608
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2154
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2094
#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:1284
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
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:695
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126
bool check_functional_grouping ( Oid  relid,
Index  varno,
Index  varlevelsup,
List grouping_columns,
List **  constraintDeps 
)

Definition at line 975 of file pg_constraint.c.

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

Referenced by check_ungrouped_columns_walker().

979 {
980  Bitmapset *pkattnos;
981  Bitmapset *groupbyattnos;
982  Oid constraintOid;
983  ListCell *gl;
984 
985  /* If the rel has no PK, then we can't prove functional dependency */
986  pkattnos = get_primary_key_attnos(relid, false, &constraintOid);
987  if (pkattnos == NULL)
988  return false;
989 
990  /* Identify all the rel's columns that appear in grouping_columns */
991  groupbyattnos = NULL;
992  foreach(gl, grouping_columns)
993  {
994  Var *gvar = (Var *) lfirst(gl);
995 
996  if (IsA(gvar, Var) &&
997  gvar->varno == varno &&
998  gvar->varlevelsup == varlevelsup)
999  groupbyattnos = bms_add_member(groupbyattnos,
1001  }
1002 
1003  if (bms_is_subset(pkattnos, groupbyattnos))
1004  {
1005  /* The PK is a subset of grouping_columns, so we win */
1006  *constraintDeps = lappend_oid(*constraintDeps, constraintOid);
1007  return true;
1008  }
1009 
1010  return false;
1011 }
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
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 NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
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, NULL, 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:1486
#define NAMEDATALEN
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:950
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define CStringGetDatum(X)
Definition: postgres.h:584
static char * label
Definition: pg_basebackup.c:81
#define Anum_pg_constraint_connamespace
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define ConstraintNameNspIndexId
Definition: indexing.h:124
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
#define StrNCpy(dst, src, len)
Definition: c.h:830
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
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, NULL, 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:656
#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:1284
#define ConstraintNameNspIndexId
Definition: indexing.h:124
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
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
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, NULL, 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:429
#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:3306
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:692
#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:217
#define Anum_pg_constraint_coninhcount
#define OidIsValid(objectId)
Definition: c.h:538
#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:493
#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:1284
#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 NULL
Definition: c.h:229
#define Anum_pg_constraint_conpfeqop
#define Assert(condition)
Definition: c.h:675
#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:1379
#define CharGetDatum(X)
Definition: postgres.h:422
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define Int32GetDatum(X)
Definition: postgres.h:485
void * palloc(Size size)
Definition: mcxt.c:849
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
Oid get_domain_constraint_oid ( Oid  typid,
const char *  conname,
bool  missing_ok 
)

Definition at line 814 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, NULL, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_object_address(), and rename_constraint_internal().

815 {
816  Relation pg_constraint;
817  HeapTuple tuple;
818  SysScanDesc scan;
819  ScanKeyData skey[1];
820  Oid conOid = InvalidOid;
821 
822  /*
823  * Fetch the constraint tuple from pg_constraint. There may be more than
824  * one match, because constraints are not required to have unique names;
825  * if so, error out.
826  */
828 
829  ScanKeyInit(&skey[0],
831  BTEqualStrategyNumber, F_OIDEQ,
832  ObjectIdGetDatum(typid));
833 
834  scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true,
835  NULL, 1, skey);
836 
837  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
838  {
840 
841  if (strcmp(NameStr(con->conname), conname) == 0)
842  {
843  if (OidIsValid(conOid))
844  ereport(ERROR,
846  errmsg("domain \"%s\" has multiple constraints named \"%s\"",
847  format_type_be(typid), conname)));
848  conOid = HeapTupleGetOid(tuple);
849  }
850  }
851 
852  systable_endscan(scan);
853 
854  /* If no such constraint exists, complain */
855  if (!OidIsValid(conOid) && !missing_ok)
856  ereport(ERROR,
857  (errcode(ERRCODE_UNDEFINED_OBJECT),
858  errmsg("constraint \"%s\" for domain \"%s\" does not exist",
859  conname, format_type_be(typid))));
860 
861  heap_close(pg_constraint, AccessShareLock);
862 
863  return conOid;
864 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#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:538
#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:1284
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:499
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:695
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
#define BTEqualStrategyNumber
Definition: stratnum.h:31
Bitmapset* get_primary_key_attnos ( Oid  relid,
bool  deferrableOk,
Oid constraintOid 
)

Definition at line 881 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, NULL, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by check_functional_grouping(), and remove_useless_groupby_columns().

882 {
883  Bitmapset *pkattnos = NULL;
884  Relation pg_constraint;
885  HeapTuple tuple;
886  SysScanDesc scan;
887  ScanKeyData skey[1];
888 
889  /* Set *constraintOid, to avoid complaints about uninitialized vars */
890  *constraintOid = InvalidOid;
891 
892  /* Scan pg_constraint for constraints of the target rel */
894 
895  ScanKeyInit(&skey[0],
897  BTEqualStrategyNumber, F_OIDEQ,
898  ObjectIdGetDatum(relid));
899 
900  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
901  NULL, 1, skey);
902 
903  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
904  {
906  Datum adatum;
907  bool isNull;
908  ArrayType *arr;
909  int16 *attnums;
910  int numkeys;
911  int i;
912 
913  /* Skip constraints that are not PRIMARY KEYs */
914  if (con->contype != CONSTRAINT_PRIMARY)
915  continue;
916 
917  /*
918  * If the primary key is deferrable, but we've been instructed to
919  * ignore deferrable constraints, then we might as well give up
920  * searching, since there can only be a single primary key on a table.
921  */
922  if (con->condeferrable && !deferrableOk)
923  break;
924 
925  /* Extract the conkey array, ie, attnums of PK's columns */
926  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
927  RelationGetDescr(pg_constraint), &isNull);
928  if (isNull)
929  elog(ERROR, "null conkey for constraint %u",
930  HeapTupleGetOid(tuple));
931  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
932  numkeys = ARR_DIMS(arr)[0];
933  if (ARR_NDIM(arr) != 1 ||
934  numkeys < 0 ||
935  ARR_HASNULL(arr) ||
936  ARR_ELEMTYPE(arr) != INT2OID)
937  elog(ERROR, "conkey is not a 1-D smallint array");
938  attnums = (int16 *) ARR_DATA_PTR(arr);
939 
940  /* Construct the result value */
941  for (i = 0; i < numkeys; i++)
942  {
943  pkattnos = bms_add_member(pkattnos,
945  }
946  *constraintOid = HeapTupleGetOid(tuple);
947 
948  /* No need to search further */
949  break;
950  }
951 
952  systable_endscan(scan);
953 
954  heap_close(pg_constraint, AccessShareLock);
955 
956  return pkattnos;
957 }
signed short int16
Definition: c.h:255
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define RelationGetDescr(relation)
Definition: rel.h:429
#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:275
#define INT2OID
Definition: pg_type.h:308
#define ARR_DATA_PTR(a)
Definition: array.h:303
#define ARR_HASNULL(a)
Definition: array.h:272
#define Anum_pg_constraint_conkey
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
uintptr_t Datum
Definition: postgres.h:372
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:698
#define ARR_NDIM(a)
Definition: array.h:271
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:695
#define ARR_ELEMTYPE(a)
Definition: array.h:273
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126
#define DatumGetArrayTypeP(X)
Definition: array.h:242
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, NULL, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by get_object_address_relobject(), rename_constraint_internal(), transformOnConflictArbiter(), 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:656
#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:538
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:1284
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:499
#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:695
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:126
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:656
#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:1374
#define OidIsValid(objectId)
Definition: c.h:538
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
#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:437
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
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:161
#define AccessExclusiveLock
Definition: lockdefs.h:46
#define ConstraintRelationId
Definition: pg_constraint.h:29
#define elog
Definition: elog.h:219
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:656
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:1374
int namestrcpy(Name name, const char *str)
Definition: name.c:217
#define OidIsValid(objectId)
Definition: c.h:538
#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:1284
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:161
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:31
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1726