PostgreSQL Source Code  git master
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 "access/tupconvert.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/objectaccess.h"
#include "catalog/partition.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "commands/tablecmds.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 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, const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
 
void CloneForeignKeyConstraints (Oid parentId, Oid relationId, List **cloned)
 
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)
 
void ConstraintSetParentConstraint (Oid childConstrId, Oid parentConstrId)
 
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_relation_idx_constraint_oid (Oid relationId, Oid indexId)
 
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

◆ AlterConstraintNamespaces()

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

Definition at line 943 of file pg_constraint.c.

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

Referenced by AlterTableNamespaceInternal(), and AlterTypeNamespaceInternal().

945 {
946  Relation conRel;
947  ScanKeyData key[1];
948  SysScanDesc scan;
949  HeapTuple tup;
950 
951  conRel = heap_open(ConstraintRelationId, RowExclusiveLock);
952 
953  if (isType)
954  {
955  ScanKeyInit(&key[0],
956  Anum_pg_constraint_contypid,
957  BTEqualStrategyNumber, F_OIDEQ,
958  ObjectIdGetDatum(ownerId));
959 
960  scan = systable_beginscan(conRel, ConstraintTypidIndexId, true,
961  NULL, 1, key);
962  }
963  else
964  {
965  ScanKeyInit(&key[0],
966  Anum_pg_constraint_conrelid,
967  BTEqualStrategyNumber, F_OIDEQ,
968  ObjectIdGetDatum(ownerId));
969 
970  scan = systable_beginscan(conRel, ConstraintRelidIndexId, true,
971  NULL, 1, key);
972  }
973 
974  while (HeapTupleIsValid((tup = systable_getnext(scan))))
975  {
977  ObjectAddress thisobj;
978 
979  thisobj.classId = ConstraintRelationId;
980  thisobj.objectId = HeapTupleGetOid(tup);
981  thisobj.objectSubId = 0;
982 
983  if (object_address_present(&thisobj, objsMoved))
984  continue;
985 
986  /* Don't update if the object is already part of the namespace */
987  if (conform->connamespace == oldNspId && oldNspId != newNspId)
988  {
989  tup = heap_copytuple(tup);
990  conform = (Form_pg_constraint) GETSTRUCT(tup);
991 
992  conform->connamespace = newNspId;
993 
994  CatalogTupleUpdate(conRel, &tup->t_self, tup);
995 
996  /*
997  * Note: currently, the constraint will not have its own
998  * dependency on the namespace, so we don't need to do
999  * changeDependencyFor().
1000  */
1001  }
1002 
1003  InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0);
1004 
1005  add_exact_object_address(&thisobj, objsMoved);
1006  }
1007 
1008  systable_endscan(scan);
1009 
1010  heap_close(conRel, RowExclusiveLock);
1011 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:722
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
bool object_address_present(const ObjectAddress *object, const ObjectAddresses *addrs)
Definition: dependency.c:2245
void add_exact_object_address(const ObjectAddress *object, ObjectAddresses *addrs)
Definition: dependency.c:2185
#define heap_close(r, l)
Definition: heapam.h:97
#define ConstraintTypidIndexId
Definition: indexing.h:127
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
ItemPointerData t_self
Definition: htup.h:65
#define RowExclusiveLock
Definition: lockdefs.h:38
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:125

◆ check_functional_grouping()

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

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

1417 {
1418  Bitmapset *pkattnos;
1419  Bitmapset *groupbyattnos;
1420  Oid constraintOid;
1421  ListCell *gl;
1422 
1423  /* If the rel has no PK, then we can't prove functional dependency */
1424  pkattnos = get_primary_key_attnos(relid, false, &constraintOid);
1425  if (pkattnos == NULL)
1426  return false;
1427 
1428  /* Identify all the rel's columns that appear in grouping_columns */
1429  groupbyattnos = NULL;
1430  foreach(gl, grouping_columns)
1431  {
1432  Var *gvar = (Var *) lfirst(gl);
1433 
1434  if (IsA(gvar, Var) &&
1435  gvar->varno == varno &&
1436  gvar->varlevelsup == varlevelsup)
1437  groupbyattnos = bms_add_member(groupbyattnos,
1439  }
1440 
1441  if (bms_is_subset(pkattnos, groupbyattnos))
1442  {
1443  /* The PK is a subset of grouping_columns, so we win */
1444  *constraintDeps = lappend_oid(*constraintDeps, constraintOid);
1445  return true;
1446  }
1447 
1448  return false;
1449 }
Bitmapset * get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
#define IsA(nodeptr, _type_)
Definition: nodes.h:568
Index varlevelsup
Definition: primnodes.h:174
AttrNumber varattno
Definition: primnodes.h:169
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:164
List * lappend_oid(List *list, Oid datum)
Definition: list.c:164
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:374
Index varno
Definition: primnodes.h:167
#define lfirst(lc)
Definition: pg_list.h:106
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:764

◆ ChooseConstraintName()

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

Definition at line 727 of file pg_constraint.c.

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

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

730 {
731  int pass = 0;
732  char *conname = NULL;
733  char modlabel[NAMEDATALEN];
734  Relation conDesc;
735  SysScanDesc conscan;
736  ScanKeyData skey[2];
737  bool found;
738  ListCell *l;
739 
740  conDesc = heap_open(ConstraintRelationId, AccessShareLock);
741 
742  /* try the unmodified label first */
743  StrNCpy(modlabel, label, sizeof(modlabel));
744 
745  for (;;)
746  {
747  conname = makeObjectName(name1, name2, modlabel);
748 
749  found = false;
750 
751  foreach(l, others)
752  {
753  if (strcmp((char *) lfirst(l), conname) == 0)
754  {
755  found = true;
756  break;
757  }
758  }
759 
760  if (!found)
761  {
762  ScanKeyInit(&skey[0],
763  Anum_pg_constraint_conname,
764  BTEqualStrategyNumber, F_NAMEEQ,
765  CStringGetDatum(conname));
766 
767  ScanKeyInit(&skey[1],
768  Anum_pg_constraint_connamespace,
769  BTEqualStrategyNumber, F_OIDEQ,
770  ObjectIdGetDatum(namespaceid));
771 
772  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
773  NULL, 2, skey);
774 
775  found = (HeapTupleIsValid(systable_getnext(conscan)));
776 
777  systable_endscan(conscan);
778  }
779 
780  if (!found)
781  break;
782 
783  /* found a conflict, so try a new name component */
784  pfree(conname);
785  snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
786  }
787 
788  heap_close(conDesc, AccessShareLock);
789 
790  return conname;
791 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#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
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
char * makeObjectName(const char *name1, const char *name2, const char *label)
Definition: indexcmds.c:1907
#define NAMEDATALEN
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define CStringGetDatum(X)
Definition: postgres.h:561
static char * label
Definition: pg_basebackup.c:84
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define ConstraintNameNspIndexId
Definition: indexing.h:123
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define lfirst(lc)
Definition: pg_list.h:106
#define StrNCpy(dst, src, len)
Definition: c.h:881
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ CloneForeignKeyConstraints()

void CloneForeignKeyConstraints ( Oid  parentId,
Oid  relationId,
List **  cloned 
)

Definition at line 417 of file pg_constraint.c.

References AccessExclusiveLock, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, BTEqualStrategyNumber, CloneForeignKeyConstraints(), ClonedConstraint::conid, ClonedConstraint::conindid, ClonedConstraint::constraint, ConstraintRelidIndexId, convert_tuples_by_name_map(), CreateConstraintEntry(), createForeignKeyTriggers(), DatumGetArrayTypeP, Constraint::deferrable, DEPENDENCY_INTERNAL_AUTO, elog, ERROR, fastgetattr, Constraint::fk_del_action, Constraint::fk_upd_action, GETSTRUCT, gettext_noop, heap_close, heap_open(), HeapTupleGetOid, i, INDEX_MAX_KEYS, Constraint::initdeferred, InvalidOid, lappend(), makeNode, NameStr, NoLock, PartitionDescData::nparts, ObjectAddressSet, ObjectIdGetDatum, PartitionDescData::oids, palloc(), pfree(), RelationData::rd_rel, recordDependencyOn(), ClonedConstraint::refrelid, RelationGetDescr, RelationGetPartitionDesc, RelationGetRelid, ClonedConstraint::relid, RowShareLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by ATExecAttachPartition(), CloneForeignKeyConstraints(), and DefineRelation().

418 {
419  Relation pg_constraint;
420  Relation parentRel;
421  Relation rel;
422  ScanKeyData key;
423  SysScanDesc scan;
424  TupleDesc tupdesc;
425  HeapTuple tuple;
426  AttrNumber *attmap;
427 
428  parentRel = heap_open(parentId, NoLock); /* already got lock */
429  /* see ATAddForeignKeyConstraint about lock level */
430  rel = heap_open(relationId, AccessExclusiveLock);
431 
432  pg_constraint = heap_open(ConstraintRelationId, RowShareLock);
433  tupdesc = RelationGetDescr(pg_constraint);
434 
435  /*
436  * The constraint key may differ, if the columns in the partition are
437  * different. This map is used to convert them.
438  */
440  RelationGetDescr(parentRel),
441  gettext_noop("could not convert row type"));
442 
443  ScanKeyInit(&key,
444  Anum_pg_constraint_conrelid, BTEqualStrategyNumber,
445  F_OIDEQ, ObjectIdGetDatum(parentId));
446  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
447  NULL, 1, &key);
448 
449  while ((tuple = systable_getnext(scan)) != NULL)
450  {
451  Form_pg_constraint constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
452  AttrNumber conkey[INDEX_MAX_KEYS];
453  AttrNumber mapped_conkey[INDEX_MAX_KEYS];
454  AttrNumber confkey[INDEX_MAX_KEYS];
455  Oid conpfeqop[INDEX_MAX_KEYS];
456  Oid conppeqop[INDEX_MAX_KEYS];
457  Oid conffeqop[INDEX_MAX_KEYS];
458  Constraint *fkconstraint;
459  ClonedConstraint *newc;
460  Oid constrOid;
461  ObjectAddress parentAddr,
462  childAddr;
463  int nelem;
464  int i;
465  ArrayType *arr;
466  Datum datum;
467  bool isnull;
468 
469  /* only foreign keys */
470  if (constrForm->contype != CONSTRAINT_FOREIGN)
471  continue;
472 
473  ObjectAddressSet(parentAddr, ConstraintRelationId,
474  HeapTupleGetOid(tuple));
475 
476  datum = fastgetattr(tuple, Anum_pg_constraint_conkey,
477  tupdesc, &isnull);
478  if (isnull)
479  elog(ERROR, "null conkey");
480  arr = DatumGetArrayTypeP(datum);
481  nelem = ARR_DIMS(arr)[0];
482  if (ARR_NDIM(arr) != 1 ||
483  nelem < 1 ||
484  nelem > INDEX_MAX_KEYS ||
485  ARR_HASNULL(arr) ||
486  ARR_ELEMTYPE(arr) != INT2OID)
487  elog(ERROR, "conkey is not a 1-D smallint array");
488  memcpy(conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
489 
490  for (i = 0; i < nelem; i++)
491  mapped_conkey[i] = attmap[conkey[i] - 1];
492 
493  datum = fastgetattr(tuple, Anum_pg_constraint_confkey,
494  tupdesc, &isnull);
495  if (isnull)
496  elog(ERROR, "null confkey");
497  arr = DatumGetArrayTypeP(datum);
498  nelem = ARR_DIMS(arr)[0];
499  if (ARR_NDIM(arr) != 1 ||
500  nelem < 1 ||
501  nelem > INDEX_MAX_KEYS ||
502  ARR_HASNULL(arr) ||
503  ARR_ELEMTYPE(arr) != INT2OID)
504  elog(ERROR, "confkey is not a 1-D smallint array");
505  memcpy(confkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
506 
507  datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop,
508  tupdesc, &isnull);
509  if (isnull)
510  elog(ERROR, "null conpfeqop");
511  arr = DatumGetArrayTypeP(datum);
512  nelem = ARR_DIMS(arr)[0];
513  if (ARR_NDIM(arr) != 1 ||
514  nelem < 1 ||
515  nelem > INDEX_MAX_KEYS ||
516  ARR_HASNULL(arr) ||
517  ARR_ELEMTYPE(arr) != OIDOID)
518  elog(ERROR, "conpfeqop is not a 1-D OID array");
519  memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
520 
521  datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop,
522  tupdesc, &isnull);
523  if (isnull)
524  elog(ERROR, "null conpfeqop");
525  arr = DatumGetArrayTypeP(datum);
526  nelem = ARR_DIMS(arr)[0];
527  if (ARR_NDIM(arr) != 1 ||
528  nelem < 1 ||
529  nelem > INDEX_MAX_KEYS ||
530  ARR_HASNULL(arr) ||
531  ARR_ELEMTYPE(arr) != OIDOID)
532  elog(ERROR, "conpfeqop is not a 1-D OID array");
533  memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
534 
535  datum = fastgetattr(tuple, Anum_pg_constraint_conppeqop,
536  tupdesc, &isnull);
537  if (isnull)
538  elog(ERROR, "null conppeqop");
539  arr = DatumGetArrayTypeP(datum);
540  nelem = ARR_DIMS(arr)[0];
541  if (ARR_NDIM(arr) != 1 ||
542  nelem < 1 ||
543  nelem > INDEX_MAX_KEYS ||
544  ARR_HASNULL(arr) ||
545  ARR_ELEMTYPE(arr) != OIDOID)
546  elog(ERROR, "conppeqop is not a 1-D OID array");
547  memcpy(conppeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
548 
549  datum = fastgetattr(tuple, Anum_pg_constraint_conffeqop,
550  tupdesc, &isnull);
551  if (isnull)
552  elog(ERROR, "null conffeqop");
553  arr = DatumGetArrayTypeP(datum);
554  nelem = ARR_DIMS(arr)[0];
555  if (ARR_NDIM(arr) != 1 ||
556  nelem < 1 ||
557  nelem > INDEX_MAX_KEYS ||
558  ARR_HASNULL(arr) ||
559  ARR_ELEMTYPE(arr) != OIDOID)
560  elog(ERROR, "conffeqop is not a 1-D OID array");
561  memcpy(conffeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
562 
563  constrOid =
564  CreateConstraintEntry(NameStr(constrForm->conname),
565  constrForm->connamespace,
566  CONSTRAINT_FOREIGN,
567  constrForm->condeferrable,
568  constrForm->condeferred,
569  constrForm->convalidated,
570  HeapTupleGetOid(tuple),
571  relationId,
572  mapped_conkey,
573  nelem,
574  nelem,
575  InvalidOid, /* not a domain constraint */
576  constrForm->conindid, /* same index */
577  constrForm->confrelid, /* same foreign rel */
578  confkey,
579  conpfeqop,
580  conppeqop,
581  conffeqop,
582  nelem,
583  constrForm->confupdtype,
584  constrForm->confdeltype,
585  constrForm->confmatchtype,
586  NULL,
587  NULL,
588  NULL,
589  NULL,
590  false,
591  1, false, true);
592 
593  ObjectAddressSet(childAddr, ConstraintRelationId, constrOid);
594  recordDependencyOn(&childAddr, &parentAddr, DEPENDENCY_INTERNAL_AUTO);
595 
596  fkconstraint = makeNode(Constraint);
597  /* for now this is all we need */
598  fkconstraint->fk_upd_action = constrForm->confupdtype;
599  fkconstraint->fk_del_action = constrForm->confdeltype;
600  fkconstraint->deferrable = constrForm->condeferrable;
601  fkconstraint->initdeferred = constrForm->condeferred;
602 
603  createForeignKeyTriggers(rel, constrForm->confrelid, fkconstraint,
604  constrOid, constrForm->conindid, false);
605 
606  if (cloned)
607  {
608  /*
609  * Feed back caller about the constraints we created, so that they
610  * can set up constraint verification.
611  */
612  newc = palloc(sizeof(ClonedConstraint));
613  newc->relid = relationId;
614  newc->refrelid = constrForm->confrelid;
615  newc->conindid = constrForm->conindid;
616  newc->conid = constrOid;
617  newc->constraint = fkconstraint;
618 
619  *cloned = lappend(*cloned, newc);
620  }
621  }
622  systable_endscan(scan);
623 
624  pfree(attmap);
625 
626  if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
627  {
628  PartitionDesc partdesc = RelationGetPartitionDesc(rel);
629  int i;
630 
631  for (i = 0; i < partdesc->nparts; i++)
633  partdesc->oids[i],
634  cloned);
635  }
636 
637  heap_close(rel, NoLock); /* keep lock till commit */
638  heap_close(parentRel, NoLock);
639  heap_close(pg_constraint, RowShareLock);
640 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define fastgetattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:736
void CloneForeignKeyConstraints(Oid parentId, Oid relationId, List **cloned)
#define RelationGetDescr(relation)
Definition: rel.h:433
#define gettext_noop(x)
Definition: c.h:1036
bool initdeferred
Definition: parsenodes.h:2097
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
Form_pg_class rd_rel
Definition: rel.h:84
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:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
bool deferrable
Definition: parsenodes.h:2096
#define ARR_DIMS(a)
Definition: array.h:279
#define ARR_DATA_PTR(a)
Definition: array.h:307
#define NoLock
Definition: lockdefs.h:34
Constraint * constraint
#define ARR_HASNULL(a)
Definition: array.h:276
List * lappend(List *list, void *datum)
Definition: list.c:128
AttrNumber * convert_tuples_by_name_map(TupleDesc indesc, TupleDesc outdesc, const char *msg)
Definition: tupconvert.c:293
#define RowShareLock
Definition: lockdefs.h:37
uintptr_t Datum
Definition: postgres.h:365
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
#define makeNode(_type_)
Definition: nodes.h:565
FormData_pg_constraint * Form_pg_constraint
char fk_del_action
Definition: parsenodes.h:2129
void createForeignKeyTriggers(Relation rel, Oid refRelOid, Constraint *fkconstraint, Oid constraintOid, Oid indexOid, bool create_action)
Definition: tablecmds.c:8783
#define INDEX_MAX_KEYS
#define ARR_NDIM(a)
Definition: array.h:275
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define AccessExclusiveLock
Definition: lockdefs.h:45
void * palloc(Size size)
Definition: mcxt.c:924
int i
#define NameStr(name)
Definition: c.h:576
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, const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal)
Definition: pg_constraint.c:51
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define ARR_ELEMTYPE(a)
Definition: array.h:277
int16 AttrNumber
Definition: attnum.h:21
#define RelationGetRelid(relation)
Definition: rel.h:407
#define BTEqualStrategyNumber
Definition: stratnum.h:31
char fk_upd_action
Definition: parsenodes.h:2128
#define ConstraintRelidIndexId
Definition: indexing.h:125
#define RelationGetPartitionDesc(relation)
Definition: rel.h:595
#define DatumGetArrayTypeP(X)
Definition: array.h:246

◆ ConstraintNameIsUsed()

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

Definition at line 655 of file pg_constraint.c.

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

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

657 {
658  bool found;
659  Relation conDesc;
660  SysScanDesc conscan;
661  ScanKeyData skey[2];
662  HeapTuple tup;
663 
664  conDesc = heap_open(ConstraintRelationId, AccessShareLock);
665 
666  found = false;
667 
668  ScanKeyInit(&skey[0],
669  Anum_pg_constraint_conname,
670  BTEqualStrategyNumber, F_NAMEEQ,
671  CStringGetDatum(conname));
672 
673  ScanKeyInit(&skey[1],
674  Anum_pg_constraint_connamespace,
675  BTEqualStrategyNumber, F_OIDEQ,
676  ObjectIdGetDatum(objNamespace));
677 
678  conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
679  NULL, 2, skey);
680 
681  while (HeapTupleIsValid(tup = systable_getnext(conscan)))
682  {
684 
685  if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)
686  {
687  found = true;
688  break;
689  }
690  else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)
691  {
692  found = true;
693  break;
694  }
695  }
696 
697  systable_endscan(conscan);
698  heap_close(conDesc, AccessShareLock);
699 
700  return found;
701 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define AccessShareLock
Definition: lockdefs.h:36
#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:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define CStringGetDatum(X)
Definition: postgres.h:561
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define ConstraintNameNspIndexId
Definition: indexing.h:123
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ ConstraintSetParentConstraint()

void ConstraintSetParentConstraint ( Oid  childConstrId,
Oid  parentConstrId 
)

Definition at line 1021 of file pg_constraint.c.

References CatalogTupleUpdate(), CONSTROID, DEPENDENCY_INTERNAL_AUTO, elog, ERROR, GETSTRUCT, heap_close, heap_copytuple(), heap_open(), HeapTupleIsValid, ObjectAddressSet, ObjectIdGetDatum, recordDependencyOn(), ReleaseSysCache(), RowExclusiveLock, SearchSysCache1(), and HeapTupleData::t_self.

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

1022 {
1023  Relation constrRel;
1024  Form_pg_constraint constrForm;
1025  HeapTuple tuple,
1026  newtup;
1027  ObjectAddress depender;
1028  ObjectAddress referenced;
1029 
1030  constrRel = heap_open(ConstraintRelationId, RowExclusiveLock);
1031  tuple = SearchSysCache1(CONSTROID, ObjectIdGetDatum(childConstrId));
1032  if (!HeapTupleIsValid(tuple))
1033  elog(ERROR, "cache lookup failed for constraint %u", childConstrId);
1034  newtup = heap_copytuple(tuple);
1035  constrForm = (Form_pg_constraint) GETSTRUCT(newtup);
1036  constrForm->conislocal = false;
1037  constrForm->coninhcount++;
1038  constrForm->conparentid = parentConstrId;
1039  CatalogTupleUpdate(constrRel, &tuple->t_self, newtup);
1040  ReleaseSysCache(tuple);
1041 
1042  ObjectAddressSet(referenced, ConstraintRelationId, parentConstrId);
1043  ObjectAddressSet(depender, ConstraintRelationId, childConstrId);
1044 
1045  recordDependencyOn(&depender, &referenced, DEPENDENCY_INTERNAL_AUTO);
1046 
1047  heap_close(constrRel, RowExclusiveLock);
1048 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:722
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
void recordDependencyOn(const ObjectAddress *depender, const ObjectAddress *referenced, DependencyType behavior)
Definition: pg_depend.c:44
#define heap_close(r, l)
Definition: heapam.h:97
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#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:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
#define elog
Definition: elog.h:219

◆ 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,
const char *  conSrc,
bool  conIsLocal,
int  conInhCount,
bool  conNoInherit,
bool  is_internal 
)

Definition at line 51 of file pg_constraint.c.

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

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

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

◆ get_domain_constraint_oid()

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

Definition at line 1252 of file pg_constraint.c.

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

Referenced by get_object_address(), and rename_constraint_internal().

1253 {
1254  Relation pg_constraint;
1255  HeapTuple tuple;
1256  SysScanDesc scan;
1257  ScanKeyData skey[1];
1258  Oid conOid = InvalidOid;
1259 
1260  /*
1261  * Fetch the constraint tuple from pg_constraint. There may be more than
1262  * one match, because constraints are not required to have unique names;
1263  * if so, error out.
1264  */
1265  pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
1266 
1267  ScanKeyInit(&skey[0],
1268  Anum_pg_constraint_contypid,
1269  BTEqualStrategyNumber, F_OIDEQ,
1270  ObjectIdGetDatum(typid));
1271 
1272  scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true,
1273  NULL, 1, skey);
1274 
1275  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1276  {
1278 
1279  if (strcmp(NameStr(con->conname), conname) == 0)
1280  {
1281  if (OidIsValid(conOid))
1282  ereport(ERROR,
1284  errmsg("domain %s has multiple constraints named \"%s\"",
1285  format_type_be(typid), conname)));
1286  conOid = HeapTupleGetOid(tuple);
1287  }
1288  }
1289 
1290  systable_endscan(scan);
1291 
1292  /* If no such constraint exists, complain */
1293  if (!OidIsValid(conOid) && !missing_ok)
1294  ereport(ERROR,
1295  (errcode(ERRCODE_UNDEFINED_OBJECT),
1296  errmsg("constraint \"%s\" for domain %s does not exist",
1297  conname, format_type_be(typid))));
1298 
1299  heap_close(pg_constraint, AccessShareLock);
1300 
1301  return conOid;
1302 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#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:328
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:605
#define ConstraintTypidIndexId
Definition: indexing.h:127
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:576
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ get_primary_key_attnos()

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

Definition at line 1319 of file pg_constraint.c.

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

Referenced by check_functional_grouping(), and remove_useless_groupby_columns().

1320 {
1321  Bitmapset *pkattnos = NULL;
1322  Relation pg_constraint;
1323  HeapTuple tuple;
1324  SysScanDesc scan;
1325  ScanKeyData skey[1];
1326 
1327  /* Set *constraintOid, to avoid complaints about uninitialized vars */
1328  *constraintOid = InvalidOid;
1329 
1330  /* Scan pg_constraint for constraints of the target rel */
1331  pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
1332 
1333  ScanKeyInit(&skey[0],
1334  Anum_pg_constraint_conrelid,
1335  BTEqualStrategyNumber, F_OIDEQ,
1336  ObjectIdGetDatum(relid));
1337 
1338  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
1339  NULL, 1, skey);
1340 
1341  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1342  {
1344  Datum adatum;
1345  bool isNull;
1346  ArrayType *arr;
1347  int16 *attnums;
1348  int numkeys;
1349  int i;
1350 
1351  /* Skip constraints that are not PRIMARY KEYs */
1352  if (con->contype != CONSTRAINT_PRIMARY)
1353  continue;
1354 
1355  /*
1356  * If the primary key is deferrable, but we've been instructed to
1357  * ignore deferrable constraints, then we might as well give up
1358  * searching, since there can only be a single primary key on a table.
1359  */
1360  if (con->condeferrable && !deferrableOk)
1361  break;
1362 
1363  /* Extract the conkey array, ie, attnums of PK's columns */
1364  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
1365  RelationGetDescr(pg_constraint), &isNull);
1366  if (isNull)
1367  elog(ERROR, "null conkey for constraint %u",
1368  HeapTupleGetOid(tuple));
1369  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1370  numkeys = ARR_DIMS(arr)[0];
1371  if (ARR_NDIM(arr) != 1 ||
1372  numkeys < 0 ||
1373  ARR_HASNULL(arr) ||
1374  ARR_ELEMTYPE(arr) != INT2OID)
1375  elog(ERROR, "conkey is not a 1-D smallint array");
1376  attnums = (int16 *) ARR_DATA_PTR(arr);
1377 
1378  /* Construct the result value */
1379  for (i = 0; i < numkeys; i++)
1380  {
1381  pkattnos = bms_add_member(pkattnos,
1382  attnums[i] - FirstLowInvalidHeapAttributeNumber);
1383  }
1384  *constraintOid = HeapTupleGetOid(tuple);
1385 
1386  /* No need to search further */
1387  break;
1388  }
1389 
1390  systable_endscan(scan);
1391 
1392  heap_close(pg_constraint, AccessShareLock);
1393 
1394  return pkattnos;
1395 }
signed short int16
Definition: c.h:312
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define RelationGetDescr(relation)
Definition: rel.h:433
#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:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:279
#define ARR_DATA_PTR(a)
Definition: array.h:307
#define ARR_HASNULL(a)
Definition: array.h:276
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:786
uintptr_t Datum
Definition: postgres.h:365
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#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:764
#define ARR_NDIM(a)
Definition: array.h:275
int i
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define ARR_ELEMTYPE(a)
Definition: array.h:277
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:125
#define DatumGetArrayTypeP(X)
Definition: array.h:246

◆ get_relation_constraint_attnos()

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

Definition at line 1122 of file pg_constraint.c.

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

Referenced by transformOnConflictArbiter().

1124 {
1125  Bitmapset *conattnos = NULL;
1126  Relation pg_constraint;
1127  HeapTuple tuple;
1128  SysScanDesc scan;
1129  ScanKeyData skey[1];
1130 
1131  /* Set *constraintOid, to avoid complaints about uninitialized vars */
1132  *constraintOid = InvalidOid;
1133 
1134  /*
1135  * Fetch the constraint tuple from pg_constraint. There may be more than
1136  * one match, because constraints are not required to have unique names;
1137  * if so, error out.
1138  */
1139  pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
1140 
1141  ScanKeyInit(&skey[0],
1142  Anum_pg_constraint_conrelid,
1143  BTEqualStrategyNumber, F_OIDEQ,
1144  ObjectIdGetDatum(relid));
1145 
1146  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
1147  NULL, 1, skey);
1148 
1149  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1150  {
1152  Datum adatum;
1153  bool isNull;
1154  ArrayType *arr;
1155  int16 *attnums;
1156  int numcols;
1157  int i;
1158 
1159  /* Check the constraint name */
1160  if (strcmp(NameStr(con->conname), conname) != 0)
1161  continue;
1162  if (OidIsValid(*constraintOid))
1163  ereport(ERROR,
1165  errmsg("table \"%s\" has multiple constraints named \"%s\"",
1166  get_rel_name(relid), conname)));
1167 
1168  *constraintOid = HeapTupleGetOid(tuple);
1169 
1170  /* Extract the conkey array, ie, attnums of constrained columns */
1171  adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
1172  RelationGetDescr(pg_constraint), &isNull);
1173  if (isNull)
1174  continue; /* no constrained columns */
1175 
1176  arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1177  numcols = ARR_DIMS(arr)[0];
1178  if (ARR_NDIM(arr) != 1 ||
1179  numcols < 0 ||
1180  ARR_HASNULL(arr) ||
1181  ARR_ELEMTYPE(arr) != INT2OID)
1182  elog(ERROR, "conkey is not a 1-D smallint array");
1183  attnums = (int16 *) ARR_DATA_PTR(arr);
1184 
1185  /* Construct the result value */
1186  for (i = 0; i < numcols; i++)
1187  {
1188  conattnos = bms_add_member(conattnos,
1189  attnums[i] - FirstLowInvalidHeapAttributeNumber);
1190  }
1191  }
1192 
1193  systable_endscan(scan);
1194 
1195  /* If no such constraint exists, complain */
1196  if (!OidIsValid(*constraintOid) && !missing_ok)
1197  ereport(ERROR,
1198  (errcode(ERRCODE_UNDEFINED_OBJECT),
1199  errmsg("constraint \"%s\" for table \"%s\" does not exist",
1200  conname, get_rel_name(relid))));
1201 
1202  heap_close(pg_constraint, AccessShareLock);
1203 
1204  return conattnos;
1205 }
signed short int16
Definition: c.h:312
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define RelationGetDescr(relation)
Definition: rel.h:433
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define FirstLowInvalidHeapAttributeNumber
Definition: sysattr.h:28
#define heap_close(r, l)
Definition: heapam.h:97
#define OidIsValid(objectId)
Definition: c.h:605
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define ARR_DIMS(a)
Definition: array.h:279
#define ARR_DATA_PTR(a)
Definition: array.h:307
#define ARR_HASNULL(a)
Definition: array.h:276
#define ereport(elevel, rest)
Definition: elog.h:122
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:786
uintptr_t Datum
Definition: postgres.h:365
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#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:764
#define ARR_NDIM(a)
Definition: array.h:275
int errmsg(const char *fmt,...)
Definition: elog.c:797
int i
#define NameStr(name)
Definition: c.h:576
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
#define ARR_ELEMTYPE(a)
Definition: array.h:277
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:125
#define DatumGetArrayTypeP(X)
Definition: array.h:246

◆ get_relation_constraint_oid()

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

Definition at line 1057 of file pg_constraint.c.

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

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

1058 {
1059  Relation pg_constraint;
1060  HeapTuple tuple;
1061  SysScanDesc scan;
1062  ScanKeyData skey[1];
1063  Oid conOid = InvalidOid;
1064 
1065  /*
1066  * Fetch the constraint tuple from pg_constraint. There may be more than
1067  * one match, because constraints are not required to have unique names;
1068  * if so, error out.
1069  */
1070  pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
1071 
1072  ScanKeyInit(&skey[0],
1073  Anum_pg_constraint_conrelid,
1074  BTEqualStrategyNumber, F_OIDEQ,
1075  ObjectIdGetDatum(relid));
1076 
1077  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
1078  NULL, 1, skey);
1079 
1080  while (HeapTupleIsValid(tuple = systable_getnext(scan)))
1081  {
1083 
1084  if (strcmp(NameStr(con->conname), conname) == 0)
1085  {
1086  if (OidIsValid(conOid))
1087  ereport(ERROR,
1089  errmsg("table \"%s\" has multiple constraints named \"%s\"",
1090  get_rel_name(relid), conname)));
1091  conOid = HeapTupleGetOid(tuple);
1092  }
1093  }
1094 
1095  systable_endscan(scan);
1096 
1097  /* If no such constraint exists, complain */
1098  if (!OidIsValid(conOid) && !missing_ok)
1099  ereport(ERROR,
1100  (errcode(ERRCODE_UNDEFINED_OBJECT),
1101  errmsg("constraint \"%s\" for table \"%s\" does not exist",
1102  conname, get_rel_name(relid))));
1103 
1104  heap_close(pg_constraint, AccessShareLock);
1105 
1106  return conOid;
1107 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#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:605
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:576
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:125

◆ get_relation_idx_constraint_oid()

Oid get_relation_idx_constraint_oid ( Oid  relationId,
Oid  indexId 
)

Definition at line 1212 of file pg_constraint.c.

References AccessShareLock, BTEqualStrategyNumber, ConstraintRelidIndexId, GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, InvalidOid, ObjectIdGetDatum, ScanKeyInit(), systable_beginscan(), systable_endscan(), and systable_getnext().

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

1213 {
1214  Relation pg_constraint;
1215  SysScanDesc scan;
1216  ScanKeyData key;
1217  HeapTuple tuple;
1218  Oid constraintId = InvalidOid;
1219 
1220  pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
1221 
1222  ScanKeyInit(&key,
1223  Anum_pg_constraint_conrelid,
1225  F_OIDEQ,
1226  ObjectIdGetDatum(relationId));
1227  scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId,
1228  true, NULL, 1, &key);
1229  while ((tuple = systable_getnext(scan)) != NULL)
1230  {
1231  Form_pg_constraint constrForm;
1232 
1233  constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
1234  if (constrForm->conindid == indexId)
1235  {
1236  constraintId = HeapTupleGetOid(tuple);
1237  break;
1238  }
1239  }
1240  systable_endscan(scan);
1241 
1242  heap_close(pg_constraint, AccessShareLock);
1243  return constraintId;
1244 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
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:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
#define InvalidOid
Definition: postgres_ext.h:36
FormData_pg_constraint * Form_pg_constraint
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:712
#define BTEqualStrategyNumber
Definition: stratnum.h:31
#define ConstraintRelidIndexId
Definition: indexing.h:125

◆ RemoveConstraintById()

void RemoveConstraintById ( Oid  conId)

Definition at line 797 of file pg_constraint.c.

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

Referenced by doDeletion().

798 {
799  Relation conDesc;
800  HeapTuple tup;
801  Form_pg_constraint con;
802 
803  conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
804 
806  if (!HeapTupleIsValid(tup)) /* should not happen */
807  elog(ERROR, "cache lookup failed for constraint %u", conId);
808  con = (Form_pg_constraint) GETSTRUCT(tup);
809 
810  /*
811  * Special processing depending on what the constraint is for.
812  */
813  if (OidIsValid(con->conrelid))
814  {
815  Relation rel;
816 
817  /*
818  * If the constraint is for a relation, open and exclusive-lock the
819  * relation it's for.
820  */
821  rel = heap_open(con->conrelid, AccessExclusiveLock);
822 
823  /*
824  * We need to update the relcheck count if it is a check constraint
825  * being dropped. This update will force backends to rebuild relcache
826  * entries when we commit.
827  */
828  if (con->contype == CONSTRAINT_CHECK)
829  {
830  Relation pgrel;
831  HeapTuple relTup;
832  Form_pg_class classForm;
833 
834  pgrel = heap_open(RelationRelationId, RowExclusiveLock);
835  relTup = SearchSysCacheCopy1(RELOID,
836  ObjectIdGetDatum(con->conrelid));
837  if (!HeapTupleIsValid(relTup))
838  elog(ERROR, "cache lookup failed for relation %u",
839  con->conrelid);
840  classForm = (Form_pg_class) GETSTRUCT(relTup);
841 
842  if (classForm->relchecks == 0) /* should not happen */
843  elog(ERROR, "relation \"%s\" has relchecks = 0",
845  classForm->relchecks--;
846 
847  CatalogTupleUpdate(pgrel, &relTup->t_self, relTup);
848 
849  heap_freetuple(relTup);
850 
852  }
853 
854  /* Keep lock on constraint's rel until end of xact */
855  heap_close(rel, NoLock);
856  }
857  else if (OidIsValid(con->contypid))
858  {
859  /*
860  * XXX for now, do nothing special when dropping a domain constraint
861  *
862  * Probably there should be some form of locking on the domain type,
863  * but we have no such concept at the moment.
864  */
865  }
866  else
867  elog(ERROR, "constraint %u is not of a known type", conId);
868 
869  /* Fry the constraint itself */
870  CatalogTupleDelete(conDesc, &tup->t_self);
871 
872  /* Clean up */
873  ReleaseSysCache(tup);
874  heap_close(conDesc, RowExclusiveLock);
875 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
void CatalogTupleDelete(Relation heapRel, ItemPointer tid)
Definition: indexing.c:256
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
#define OidIsValid(objectId)
Definition: c.h:605
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#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:441
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1112
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1160
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
FormData_pg_class * Form_pg_class
Definition: pg_class.h:93
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
#define AccessExclusiveLock
Definition: lockdefs.h:45
#define elog
Definition: elog.h:219

◆ RenameConstraintById()

void RenameConstraintById ( Oid  conId,
const char *  newname 
)

Definition at line 888 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_close, heap_freetuple(), heap_open(), HeapTupleIsValid, InvokeObjectPostAlterHook, namestrcpy(), ObjectIdGetDatum, OidIsValid, RowExclusiveLock, SearchSysCacheCopy1, and HeapTupleData::t_self.

Referenced by rename_constraint_internal(), and RenameRelationInternal().

889 {
890  Relation conDesc;
891  HeapTuple tuple;
892  Form_pg_constraint con;
893 
894  conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
895 
897  if (!HeapTupleIsValid(tuple))
898  elog(ERROR, "cache lookup failed for constraint %u", conId);
899  con = (Form_pg_constraint) GETSTRUCT(tuple);
900 
901  /*
902  * We need to check whether the name is already in use --- note that there
903  * currently is not a unique index that would catch this.
904  */
905  if (OidIsValid(con->conrelid) &&
907  con->conrelid,
908  con->connamespace,
909  newname))
910  ereport(ERROR,
912  errmsg("constraint \"%s\" for relation \"%s\" already exists",
913  newname, get_rel_name(con->conrelid))));
914  if (OidIsValid(con->contypid) &&
916  con->contypid,
917  con->connamespace,
918  newname))
919  ereport(ERROR,
921  errmsg("constraint \"%s\" for domain %s already exists",
922  newname, format_type_be(con->contypid))));
923 
924  /* OK, do the rename --- tuple is a copy, so OK to scribble on it */
925  namestrcpy(&(con->conname), newname);
926 
927  CatalogTupleUpdate(conDesc, &tuple->t_self, tuple);
928 
929  InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0);
930 
931  heap_freetuple(tuple);
932  heap_close(conDesc, RowExclusiveLock);
933 }
#define GETSTRUCT(TUP)
Definition: htup_details.h:673
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:328
#define heap_close(r, l)
Definition: heapam.h:97
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1773
int namestrcpy(Name name, const char *str)
Definition: name.c:216
#define OidIsValid(objectId)
Definition: c.h:605
#define ObjectIdGetDatum(X)
Definition: postgres.h:490
#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:1294
FormData_pg_constraint * Form_pg_constraint
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:211
bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId, Oid objNamespace, const char *conname)
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:173
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730