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

Go to the source code of this file.

Typedefs

typedef FormData_pg_constraintForm_pg_constraint
 
typedef enum ConstraintCategory ConstraintCategory
 

Enumerations

enum  ConstraintCategory { CONSTRAINT_RELATION, CONSTRAINT_DOMAIN, CONSTRAINT_ASSERTION }
 

Functions

 CATALOG (pg_constraint, 2606, ConstraintRelationId)
 
Oid CreateConstraintEntry (const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isValidated, Oid parentConstrId, Oid relId, const int16 *constraintKey, int constraintNKeys, int constraintNTotalKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
 
void RemoveConstraintById (Oid conId)
 
void RenameConstraintById (Oid conId, const char *newname)
 
bool ConstraintNameIsUsed (ConstraintCategory conCat, Oid objId, const char *conname)
 
bool ConstraintNameExists (const char *conname, Oid namespaceid)
 
char * ChooseConstraintName (const char *name1, const char *name2, const char *label, Oid namespaceid, List *others)
 
void AlterConstraintNamespaces (Oid ownerId, Oid oldNspId, Oid newNspId, bool isType, ObjectAddresses *objsMoved)
 
void ConstraintSetParentConstraint (Oid childConstrId, Oid parentConstrId, Oid childTableId)
 
Oid get_relation_constraint_oid (Oid relid, const char *conname, bool missing_ok)
 
Bitmapsetget_relation_constraint_attnos (Oid relid, const char *conname, bool missing_ok, Oid *constraintOid)
 
Oid get_domain_constraint_oid (Oid typid, const char *conname, bool missing_ok)
 
Oid get_relation_idx_constraint_oid (Oid relationId, Oid indexId)
 
Bitmapsetget_primary_key_attnos (Oid relid, bool deferrableOk, Oid *constraintOid)
 
void DeconstructFkConstraintRow (HeapTuple tuple, int *numfks, AttrNumber *conkey, AttrNumber *confkey, Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs)
 
bool check_functional_grouping (Oid relid, Index varno, Index varlevelsup, List *grouping_columns, List **constraintDeps)
 

Variables

 FormData_pg_constraint
 

Typedef Documentation

◆ ConstraintCategory

◆ Form_pg_constraint

Definition at line 154 of file pg_constraint.h.

Enumeration Type Documentation

◆ ConstraintCategory

Enumerator
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 177 of file pg_constraint.h.

Function Documentation

◆ AlterConstraintNamespaces()

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

Definition at line 684 of file pg_constraint.c.

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

Referenced by AlterTableNamespaceInternal(), and AlterTypeNamespaceInternal().

686 {
687  Relation conRel;
688  ScanKeyData key[2];
689  SysScanDesc scan;
690  HeapTuple tup;
691 
692  conRel = table_open(ConstraintRelationId, RowExclusiveLock);
693 
694  ScanKeyInit(&key[0],
695  Anum_pg_constraint_conrelid,
696  BTEqualStrategyNumber, F_OIDEQ,
697  ObjectIdGetDatum(isType ? InvalidOid : ownerId));
698  ScanKeyInit(&key[1],
699  Anum_pg_constraint_contypid,
700  BTEqualStrategyNumber, F_OIDEQ,
701  ObjectIdGetDatum(isType ? ownerId : InvalidOid));
702 
704  NULL, 2, key);
705 
706  while (HeapTupleIsValid((tup = systable_getnext(scan))))
707  {
709  ObjectAddress thisobj;
710 
711  ObjectAddressSet(thisobj, ConstraintRelationId, conform->oid);
712 
713  if (object_address_present(&thisobj, objsMoved))
714  continue;
715 
716  /* Don't update if the object is already part of the namespace */
717  if (conform->connamespace == oldNspId && oldNspId != newNspId)
718  {
719  tup = heap_copytuple(tup);
720  conform = (Form_pg_constraint) GETSTRUCT(tup);
721 
722  conform->connamespace = newNspId;
723 
724  CatalogTupleUpdate(conRel, &tup->t_self, tup);
725 
726  /*
727  * Note: currently, the constraint will not have its own
728  * dependency on the namespace, so we don't need to do
729  * changeDependencyFor().
730  */
731  }
732 
733  InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0);
734 
735  add_exact_object_address(&thisobj, objsMoved);
736  }
737 
738  systable_endscan(scan);
739 
740  table_close(conRel, RowExclusiveLock);
741 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:680
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2527
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2467
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:133
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ CATALOG()

CATALOG ( pg_constraint  ,
2606  ,
ConstraintRelationId   
)

Definition at line 31 of file pg_constraint.h.

32 {
33  Oid oid; /* oid */
34 
35  /*
36  * conname + connamespace is deliberately not unique; we allow, for
37  * example, the same name to be used for constraints of different
38  * relations. This is partly for backwards compatibility with past
39  * Postgres practice, and partly because we don't want to have to obtain a
40  * global lock to generate a globally unique name for a nameless
41  * constraint. We associate a namespace with constraint names only for
42  * SQL-spec compatibility.
43  *
44  * However, we do require conname to be unique among the constraints of a
45  * single relation or domain. This is enforced by a unique index on
46  * conrelid + contypid + conname.
47  */
48  NameData conname; /* name of this constraint */
49  Oid connamespace; /* OID of namespace containing constraint */
50  char contype; /* constraint type; see codes below */
51  bool condeferrable; /* deferrable constraint? */
52  bool condeferred; /* deferred by default? */
53  bool convalidated; /* constraint has been validated? */
54 
55  /*
56  * conrelid and conkey are only meaningful if the constraint applies to a
57  * specific relation (this excludes domain constraints and assertions).
58  * Otherwise conrelid is 0 and conkey is NULL.
59  */
60  Oid conrelid; /* relation this constraint constrains */
61 
62  /*
63  * contypid links to the pg_type row for a domain if this is a domain
64  * constraint. Otherwise it's 0.
65  *
66  * For SQL-style global ASSERTIONs, both conrelid and contypid would be
67  * zero. This is not presently supported, however.
68  */
69  Oid contypid; /* domain this constraint constrains */
70 
71  /*
72  * conindid links to the index supporting the constraint, if any;
73  * otherwise it's 0. This is used for unique, primary-key, and exclusion
74  * constraints, and less obviously for foreign-key constraints (where the
75  * index is a unique index on the referenced relation's referenced
76  * columns). Notice that the index is on conrelid in the first case but
77  * confrelid in the second.
78  */
79  Oid conindid; /* index supporting this constraint */
80 
81  /*
82  * If this constraint is on a partition inherited from a partitioned
83  * table, this is the OID of the corresponding constraint in the parent.
84  */
85  Oid conparentid;
86 
87  /*
88  * These fields, plus confkey, are only meaningful for a foreign-key
89  * constraint. Otherwise confrelid is 0 and the char fields are spaces.
90  */
91  Oid confrelid; /* relation referenced by foreign key */
92  char confupdtype; /* foreign key's ON UPDATE action */
93  char confdeltype; /* foreign key's ON DELETE action */
94  char confmatchtype; /* foreign key's match type */
95 
96  /* Has a local definition (hence, do not drop when coninhcount is 0) */
97  bool conislocal;
98 
99  /* Number of times inherited from direct parent relation(s) */
100  int32 coninhcount;
101 
102  /* Has a local definition and cannot be inherited */
103  bool connoinherit;
104 
105 #ifdef CATALOG_VARLEN /* variable-length fields start here */
106 
107  /*
108  * Columns of conrelid that the constraint applies to, if known (this is
109  * NULL for trigger constraints)
110  */
111  int16 conkey[1];
112 
113  /*
114  * If a foreign key, the referenced columns of confrelid
115  */
116  int16 confkey[1];
117 
118  /*
119  * If a foreign key, the OIDs of the PK = FK equality operators for each
120  * column of the constraint
121  */
122  Oid conpfeqop[1];
123 
124  /*
125  * If a foreign key, the OIDs of the PK = PK equality operators for each
126  * column of the constraint (i.e., equality for the referenced columns)
127  */
128  Oid conppeqop[1];
129 
130  /*
131  * If a foreign key, the OIDs of the FK = FK equality operators for each
132  * column of the constraint (i.e., equality for the referencing columns)
133  */
134  Oid conffeqop[1];
135 
136  /*
137  * If an exclusion constraint, the OIDs of the exclusion operators for
138  * each column of the constraint
139  */
140  Oid conexclop[1];
141 
142  /*
143  * If a check constraint, nodeToString representation of expression
144  */
145  pg_node_tree conbin;
146 #endif
signed short int16
Definition: c.h:361
FormData_pg_constraint
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:362
Definition: c.h:616

◆ check_functional_grouping()

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

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

1270 {
1271  Bitmapset *pkattnos;
1272  Bitmapset *groupbyattnos;
1273  Oid constraintOid;
1274  ListCell *gl;
1275 
1276  /* If the rel has no PK, then we can't prove functional dependency */
1277  pkattnos = get_primary_key_attnos(relid, false, &constraintOid);
1278  if (pkattnos == NULL)
1279  return false;
1280 
1281  /* Identify all the rel's columns that appear in grouping_columns */
1282  groupbyattnos = NULL;
1283  foreach(gl, grouping_columns)
1284  {
1285  Var *gvar = (Var *) lfirst(gl);
1286 
1287  if (IsA(gvar, Var) &&
1288  gvar->varno == varno &&
1289  gvar->varlevelsup == varlevelsup)
1290  groupbyattnos = bms_add_member(groupbyattnos,
1292  }
1293 
1294  if (bms_is_subset(pkattnos, groupbyattnos))
1295  {
1296  /* The PK is a subset of grouping_columns, so we win */
1297  *constraintDeps = lappend_oid(*constraintDeps, constraintOid);
1298  return true;
1299  }
1300 
1301  return false;
1302 }
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define IsA(nodeptr, _type_)
Definition: nodes.h:580
Index varlevelsup
Definition: primnodes.h:191
AttrNumber varattno
Definition: primnodes.h:186
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:27
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:181
List * lappend_oid(List *list, Oid datum)
Definition: list.c:357
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:315
Index varno
Definition: primnodes.h:184
#define lfirst(lc)
Definition: pg_list.h:190
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:736

◆ ChooseConstraintName()

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

Definition at line 471 of file pg_constraint.c.

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

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

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

◆ ConstraintNameExists()

bool ConstraintNameExists ( const char *  conname,
Oid  namespaceid 
)

Definition at line 417 of file pg_constraint.c.

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

Referenced by ChooseRelationName().

418 {
419  bool found;
420  Relation conDesc;
421  SysScanDesc conscan;
422  ScanKeyData skey[2];
423 
424  conDesc = table_open(ConstraintRelationId, AccessShareLock);
425 
426  ScanKeyInit(&skey[0],
427  Anum_pg_constraint_conname,
428  BTEqualStrategyNumber, F_NAMEEQ,
429  CStringGetDatum(conname));
430 
431  ScanKeyInit(&skey[1],
432  Anum_pg_constraint_connamespace,
433  BTEqualStrategyNumber, F_OIDEQ,
434  ObjectIdGetDatum(namespaceid));
435 
436  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
437  NULL, 2, skey);
438 
439  found = (HeapTupleIsValid(systable_getnext(conscan)));
440 
441  systable_endscan(conscan);
442  table_close(conDesc, AccessShareLock);
443 
444  return found;
445 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define CStringGetDatum(X)
Definition: postgres.h:578
#define ConstraintNameNspIndexId
Definition: indexing.h:131
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintNameIsUsed()

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

Definition at line 372 of file pg_constraint.c.

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

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

374 {
375  bool found;
376  Relation conDesc;
377  SysScanDesc conscan;
378  ScanKeyData skey[3];
379 
380  conDesc = table_open(ConstraintRelationId, AccessShareLock);
381 
382  ScanKeyInit(&skey[0],
383  Anum_pg_constraint_conrelid,
384  BTEqualStrategyNumber, F_OIDEQ,
386  ? objId : InvalidOid));
387  ScanKeyInit(&skey[1],
388  Anum_pg_constraint_contypid,
389  BTEqualStrategyNumber, F_OIDEQ,
391  ? objId : InvalidOid));
392  ScanKeyInit(&skey[2],
393  Anum_pg_constraint_conname,
394  BTEqualStrategyNumber, F_NAMEEQ,
395  CStringGetDatum(conname));
396 
398  true, NULL, 3, skey);
399 
400  /* There can be at most one matching row */
401  found = (HeapTupleIsValid(systable_getnext(conscan)));
402 
403  systable_endscan(conscan);
404  table_close(conDesc, AccessShareLock);
405 
406  return found;
407 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvalidOid
Definition: postgres_ext.h:36
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:133
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintSetParentConstraint()

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

Definition at line 753 of file pg_constraint.c.

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

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

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

◆ CreateConstraintEntry()

Oid CreateConstraintEntry ( const char *  constraintName,
Oid  constraintNamespace,
char  constraintType,
bool  isDeferrable,
bool  isDeferred,
bool  isValidated,
Oid  parentConstrId,
Oid  relId,
const int16 constraintKey,
int  constraintNKeys,
int  constraintNTotalKeys,
Oid  domainId,
Oid  indexRelId,
Oid  foreignRelId,
const int16 foreignKey,
const Oid pfEqOp,
const Oid ppEqOp,
const Oid ffEqOp,
int  foreignNKeys,
char  foreignUpdateType,
char  foreignDeleteType,
char  foreignMatchType,
const Oid exclOp,
Node conExpr,
const char *  conBin,
bool  conIsLocal,
int  conInhCount,
bool  conNoInherit,
bool  is_internal 
)

Definition at line 50 of file pg_constraint.c.

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

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

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

◆ DeconstructFkConstraintRow()

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

Definition at line 1148 of file pg_constraint.c.

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

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

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

◆ get_domain_constraint_oid()

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

Definition at line 1004 of file pg_constraint.c.

References AccessShareLock, BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, format_type_be(), GETSTRUCT, HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by get_object_address(), and rename_constraint_internal().

1005 {
1006  Relation pg_constraint;
1007  HeapTuple tuple;
1008  SysScanDesc scan;
1009  ScanKeyData skey[3];
1010  Oid conOid = InvalidOid;
1011 
1012  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
1013 
1014  ScanKeyInit(&skey[0],
1015  Anum_pg_constraint_conrelid,
1016  BTEqualStrategyNumber, F_OIDEQ,
1018  ScanKeyInit(&skey[1],
1019  Anum_pg_constraint_contypid,
1020  BTEqualStrategyNumber, F_OIDEQ,
1021  ObjectIdGetDatum(typid));
1022  ScanKeyInit(&skey[2],
1023  Anum_pg_constraint_conname,
1024  BTEqualStrategyNumber, F_NAMEEQ,
1025  CStringGetDatum(conname));
1026 
1027  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
1028  NULL, 3, skey);
1029 
1030  /* There can be at most one matching row */
1031  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
1032  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1033 
1034  systable_endscan(scan);
1035 
1036  /* If no such constraint exists, complain */
1037  if (!OidIsValid(conOid) && !missing_ok)
1038  ereport(ERROR,
1039  (errcode(ERRCODE_UNDEFINED_OBJECT),
1040  errmsg("constraint \"%s\" for domain %s does not exist",
1041  conname, format_type_be(typid))));
1042 
1043  table_close(pg_constraint, AccessShareLock);
1044 
1045  return conOid;
1046 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:651
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:133
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_primary_key_attnos()

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

Definition at line 1063 of file pg_constraint.c.

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, DatumGetArrayTypeP, elog, ERROR, FirstLowInvalidHeapAttributeNumber, GETSTRUCT, heap_getattr, HeapTupleIsValid, i, InvalidOid, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by check_functional_grouping(), and remove_useless_groupby_columns().

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

◆ get_relation_constraint_attnos()

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

Definition at line 879 of file pg_constraint.c.

References AccessShareLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, bms_add_member(), BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, CStringGetDatum, DatumGetArrayTypeP, elog, ereport, errcode(), errmsg(), ERROR, FirstLowInvalidHeapAttributeNumber, get_rel_name(), GETSTRUCT, heap_getattr, HeapTupleIsValid, i, InvalidOid, ObjectIdGetDatum, OidIsValid, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by transformOnConflictArbiter().

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

◆ get_relation_constraint_oid()

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

Definition at line 822 of file pg_constraint.c.

References AccessShareLock, BTEqualStrategyNumber, ConstraintRelidTypidNameIndexId, CStringGetDatum, ereport, errcode(), errmsg(), ERROR, get_rel_name(), GETSTRUCT, HeapTupleIsValid, InvalidOid, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

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

823 {
824  Relation pg_constraint;
825  HeapTuple tuple;
826  SysScanDesc scan;
827  ScanKeyData skey[3];
828  Oid conOid = InvalidOid;
829 
830  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
831 
832  ScanKeyInit(&skey[0],
833  Anum_pg_constraint_conrelid,
834  BTEqualStrategyNumber, F_OIDEQ,
835  ObjectIdGetDatum(relid));
836  ScanKeyInit(&skey[1],
837  Anum_pg_constraint_contypid,
838  BTEqualStrategyNumber, F_OIDEQ,
840  ScanKeyInit(&skey[2],
841  Anum_pg_constraint_conname,
842  BTEqualStrategyNumber, F_NAMEEQ,
843  CStringGetDatum(conname));
844 
845  scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
846  NULL, 3, skey);
847 
848  /* There can be at most one matching row */
849  if (HeapTupleIsValid(tuple = systable_getnext(scan)))
850  conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
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 table \"%s\" does not exist",
859  conname, get_rel_name(relid))));
860 
861  table_close(pg_constraint, AccessShareLock);
862 
863  return conOid;
864 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:610
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:651
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define CStringGetDatum(X)
Definition: postgres.h:578
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:133
int errmsg(const char *fmt,...)
Definition: elog.c:824
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1840
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_relation_idx_constraint_oid()

Oid get_relation_idx_constraint_oid ( Oid  relationId,
Oid  indexId 
)

Definition at line 964 of file pg_constraint.c.

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

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

965 {
966  Relation pg_constraint;
967  SysScanDesc scan;
969  HeapTuple tuple;
970  Oid constraintId = InvalidOid;
971 
972  pg_constraint = table_open(ConstraintRelationId, AccessShareLock);
973 
974  ScanKeyInit(&key,
975  Anum_pg_constraint_conrelid,
977  F_OIDEQ,
978  ObjectIdGetDatum(relationId));
980  true, NULL, 1, &key);
981  while ((tuple = systable_getnext(scan)) != NULL)
982  {
983  Form_pg_constraint constrForm;
984 
985  constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
986  if (constrForm->conindid == indexId)
987  {
988  constraintId = constrForm->oid;
989  break;
990  }
991  }
992  systable_endscan(scan);
993 
994  table_close(pg_constraint, AccessShareLock);
995  return constraintId;
996 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:529
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:356
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:448
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define ConstraintRelidTypidNameIndexId
Definition: indexing.h:133
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ RemoveConstraintById()

void RemoveConstraintById ( Oid  conId)

Definition at line 541 of file pg_constraint.c.

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

Referenced by doDeletion().

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

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char *  newname 
)

Definition at line 632 of file pg_constraint.c.

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

Referenced by rename_constraint_internal(), and RenameRelationInternal().

633 {
634  Relation conDesc;
635  HeapTuple tuple;
636  Form_pg_constraint con;
637 
638  conDesc = table_open(ConstraintRelationId, RowExclusiveLock);
639 
641  if (!HeapTupleIsValid(tuple))
642  elog(ERROR, "cache lookup failed for constraint %u", conId);
643  con = (Form_pg_constraint) GETSTRUCT(tuple);
644 
645  /*
646  * For user-friendliness, check whether the name is already in use.
647  */
648  if (OidIsValid(con->conrelid) &&
650  con->conrelid,
651  newname))
652  ereport(ERROR,
654  errmsg("constraint \"%s\" for relation \"%s\" already exists",
655  newname, get_rel_name(con->conrelid))));
656  if (OidIsValid(con->contypid) &&
658  con->contypid,
659  newname))
660  ereport(ERROR,
662  errmsg("constraint \"%s\" for domain %s already exists",
663  newname, format_type_be(con->contypid))));
664 
665  /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
666  namestrcpy(&(con->conname), newname);
667 
668  CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
669 
670  InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0);
671 
672  heap_freetuple(tuple);
673  table_close(conDesc, RowExclusiveLock);
674 }
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, const char *conname)
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:133
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
int errcode(int sqlerrcode)
Definition: elog.c:610
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1338
int namestrcpy(Name name, const char *str)
Definition: name.c:250
#define OidIsValid(objectId)
Definition: c.h:651
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:175
#define ereport(elevel,...)
Definition: elog.h:144
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:301
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:174
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1840

Variable Documentation

◆ FormData_pg_constraint

FormData_pg_constraint

Definition at line 147 of file pg_constraint.h.