#include "postgres.h"#include "access/genam.h"#include "access/heapam.h"#include "access/htup_details.h"#include "catalog/dependency.h"#include "catalog/indexing.h"#include "catalog/objectaccess.h"#include "catalog/pg_constraint.h"#include "catalog/pg_operator.h"#include "catalog/pg_type.h"#include "commands/defrem.h"#include "utils/array.h"#include "utils/builtins.h"#include "utils/fmgroids.h"#include "utils/lsyscache.h"#include "utils/rel.h"#include "utils/syscache.h"#include "utils/tqual.h"
Go to the source code of this file.
Functions | |
| Oid | CreateConstraintEntry (const char *constraintName, Oid constraintNamespace, char constraintType, bool isDeferrable, bool isDeferred, bool isValidated, Oid relId, const int16 *constraintKey, int constraintNKeys, Oid domainId, Oid indexRelId, Oid foreignRelId, const int16 *foreignKey, const Oid *pfEqOp, const Oid *ppEqOp, const Oid *ffEqOp, int foreignNKeys, char foreignUpdateType, char foreignDeleteType, char foreignMatchType, const Oid *exclOp, Node *conExpr, const char *conBin, const char *conSrc, bool conIsLocal, int conInhCount, bool conNoInherit, bool is_internal) |
| bool | ConstraintNameIsUsed (ConstraintCategory conCat, Oid objId, Oid objNamespace, const char *conname) |
| char * | ChooseConstraintName (const char *name1, const char *name2, const char *label, Oid namespaceid, List *others) |
| void | RemoveConstraintById (Oid conId) |
| void | RenameConstraintById (Oid conId, const char *newname) |
| void | AlterConstraintNamespaces (Oid ownerId, Oid oldNspId, Oid newNspId, bool isType, ObjectAddresses *objsMoved) |
| Oid | get_relation_constraint_oid (Oid relid, const char *conname, bool missing_ok) |
| Oid | get_domain_constraint_oid (Oid typid, const char *conname, bool missing_ok) |
| bool | check_functional_grouping (Oid relid, Index varno, Index varlevelsup, List *grouping_columns, List **constraintDeps) |
| 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(), Anum_pg_constraint_conrelid, Anum_pg_constraint_contypid, BTEqualStrategyNumber, CatalogUpdateIndexes(), ObjectAddress::classId, ConstraintRelationId, ConstraintRelidIndexId, ConstraintTypidIndexId, GETSTRUCT, heap_close, heap_copytuple(), heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvokeObjectPostAlterHook, object_address_present(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), simple_heap_update(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.
Referenced by AlterTableNamespaceInternal(), and AlterTypeNamespaceInternal().
{
Relation conRel;
ScanKeyData key[1];
SysScanDesc scan;
HeapTuple tup;
conRel = heap_open(ConstraintRelationId, RowExclusiveLock);
if (isType)
{
ScanKeyInit(&key[0],
Anum_pg_constraint_contypid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(ownerId));
scan = systable_beginscan(conRel, ConstraintTypidIndexId, true,
SnapshotNow, 1, key);
}
else
{
ScanKeyInit(&key[0],
Anum_pg_constraint_conrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(ownerId));
scan = systable_beginscan(conRel, ConstraintRelidIndexId, true,
SnapshotNow, 1, key);
}
while (HeapTupleIsValid((tup = systable_getnext(scan))))
{
Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(tup);
ObjectAddress thisobj;
thisobj.classId = ConstraintRelationId;
thisobj.objectId = HeapTupleGetOid(tup);
thisobj.objectSubId = 0;
if (object_address_present(&thisobj, objsMoved))
continue;
if (conform->connamespace == oldNspId)
{
tup = heap_copytuple(tup);
conform = (Form_pg_constraint) GETSTRUCT(tup);
conform->connamespace = newNspId;
simple_heap_update(conRel, &tup->t_self, tup);
CatalogUpdateIndexes(conRel, tup);
/*
* Note: currently, the constraint will not have its own
* dependency on the namespace, so we don't need to do
* changeDependencyFor().
*/
}
InvokeObjectPostAlterHook(ConstraintRelationId, thisobj.objectId, 0);
add_exact_object_address(&thisobj, objsMoved);
}
systable_endscan(scan);
heap_close(conRel, RowExclusiveLock);
}
| bool check_functional_grouping | ( | Oid | relid, | |
| Index | varno, | |||
| Index | varlevelsup, | |||
| List * | grouping_columns, | |||
| List ** | constraintDeps | |||
| ) |
Definition at line 886 of file pg_constraint.c.
References AccessShareLock, Anum_pg_constraint_conkey, Anum_pg_constraint_conrelid, ARR_DATA_PTR, ARR_DIMS, ARR_ELEMTYPE, ARR_HASNULL, ARR_NDIM, BTEqualStrategyNumber, CONSTRAINT_PRIMARY, ConstraintRelationId, ConstraintRelidIndexId, DatumGetArrayTypeP, elog, ERROR, GETSTRUCT, heap_close, heap_getattr, heap_open(), HeapTupleGetOid, HeapTupleIsValid, i, INT2OID, IsA, lappend_oid(), lfirst, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), Var::varattno, Var::varlevelsup, and Var::varno.
Referenced by check_ungrouped_columns_walker().
{
bool result = false;
Relation pg_constraint;
HeapTuple tuple;
SysScanDesc scan;
ScanKeyData skey[1];
/* Scan pg_constraint for constraints of the target rel */
pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
ScanKeyInit(&skey[0],
Anum_pg_constraint_conrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
SnapshotNow, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
{
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
Datum adatum;
bool isNull;
ArrayType *arr;
int16 *attnums;
int numkeys;
int i;
bool found_col;
/* Only PK constraints are of interest for now, see comment above */
if (con->contype != CONSTRAINT_PRIMARY)
continue;
/* Constraint must be non-deferrable */
if (con->condeferrable)
continue;
/* Extract the conkey array, ie, attnums of PK's columns */
adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
RelationGetDescr(pg_constraint), &isNull);
if (isNull)
elog(ERROR, "null conkey for constraint %u",
HeapTupleGetOid(tuple));
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
numkeys = ARR_DIMS(arr)[0];
if (ARR_NDIM(arr) != 1 ||
numkeys < 0 ||
ARR_HASNULL(arr) ||
ARR_ELEMTYPE(arr) != INT2OID)
elog(ERROR, "conkey is not a 1-D smallint array");
attnums = (int16 *) ARR_DATA_PTR(arr);
found_col = false;
for (i = 0; i < numkeys; i++)
{
AttrNumber attnum = attnums[i];
ListCell *gl;
found_col = false;
foreach(gl, grouping_columns)
{
Var *gvar = (Var *) lfirst(gl);
if (IsA(gvar, Var) &&
gvar->varno == varno &&
gvar->varlevelsup == varlevelsup &&
gvar->varattno == attnum)
{
found_col = true;
break;
}
}
if (!found_col)
break;
}
if (found_col)
{
/* The PK is a subset of grouping_columns, so we win */
*constraintDeps = lappend_oid(*constraintDeps,
HeapTupleGetOid(tuple));
result = true;
break;
}
}
systable_endscan(scan);
heap_close(pg_constraint, AccessShareLock);
return result;
}
| char* ChooseConstraintName | ( | const char * | name1, | |
| const char * | name2, | |||
| const char * | label, | |||
| Oid | namespaceid, | |||
| List * | others | |||
| ) |
Definition at line 463 of file pg_constraint.c.
References AccessShareLock, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, BTEqualStrategyNumber, ConstraintNameNspIndexId, ConstraintRelationId, CStringGetDatum, heap_close, heap_open(), HeapTupleIsValid, lfirst, makeObjectName(), ObjectIdGetDatum, pfree(), ScanKeyInit(), SnapshotNow, snprintf(), StrNCpy, systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by AddRelationNewConstraints(), ATExecAddConstraint(), and domainAddConstraint().
{
int pass = 0;
char *conname = NULL;
char modlabel[NAMEDATALEN];
Relation conDesc;
SysScanDesc conscan;
ScanKeyData skey[2];
bool found;
ListCell *l;
conDesc = heap_open(ConstraintRelationId, AccessShareLock);
/* try the unmodified label first */
StrNCpy(modlabel, label, sizeof(modlabel));
for (;;)
{
conname = makeObjectName(name1, name2, modlabel);
found = false;
foreach(l, others)
{
if (strcmp((char *) lfirst(l), conname) == 0)
{
found = true;
break;
}
}
if (!found)
{
ScanKeyInit(&skey[0],
Anum_pg_constraint_conname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(conname));
ScanKeyInit(&skey[1],
Anum_pg_constraint_connamespace,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(namespaceid));
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
SnapshotNow, 2, skey);
found = (HeapTupleIsValid(systable_getnext(conscan)));
systable_endscan(conscan);
}
if (!found)
break;
/* found a conflict, so try a new name component */
pfree(conname);
snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
}
heap_close(conDesc, AccessShareLock);
return conname;
}
| bool ConstraintNameIsUsed | ( | ConstraintCategory | conCat, | |
| Oid | objId, | |||
| Oid | objNamespace, | |||
| const char * | conname | |||
| ) |
Definition at line 391 of file pg_constraint.c.
References AccessShareLock, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, BTEqualStrategyNumber, CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameNspIndexId, ConstraintRelationId, CStringGetDatum, GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, ScanKeyInit(), SnapshotNow, systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by ATExecAddConstraint(), domainAddConstraint(), and RenameConstraintById().
{
bool found;
Relation conDesc;
SysScanDesc conscan;
ScanKeyData skey[2];
HeapTuple tup;
conDesc = heap_open(ConstraintRelationId, AccessShareLock);
found = false;
ScanKeyInit(&skey[0],
Anum_pg_constraint_conname,
BTEqualStrategyNumber, F_NAMEEQ,
CStringGetDatum(conname));
ScanKeyInit(&skey[1],
Anum_pg_constraint_connamespace,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(objNamespace));
conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,
SnapshotNow, 2, skey);
while (HeapTupleIsValid(tup = systable_getnext(conscan)))
{
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)
{
found = true;
break;
}
else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)
{
found = true;
break;
}
}
systable_endscan(conscan);
heap_close(conDesc, AccessShareLock);
return found;
}
| Oid CreateConstraintEntry | ( | const char * | constraintName, | |
| Oid | constraintNamespace, | |||
| char | constraintType, | |||
| bool | isDeferrable, | |||
| bool | isDeferred, | |||
| bool | isValidated, | |||
| Oid | relId, | |||
| const int16 * | constraintKey, | |||
| int | constraintNKeys, | |||
| Oid | domainId, | |||
| Oid | indexRelId, | |||
| Oid | foreignRelId, | |||
| const int16 * | foreignKey, | |||
| const Oid * | pfEqOp, | |||
| const Oid * | ppEqOp, | |||
| const Oid * | ffEqOp, | |||
| int | foreignNKeys, | |||
| char | foreignUpdateType, | |||
| char | foreignDeleteType, | |||
| char | foreignMatchType, | |||
| const Oid * | exclOp, | |||
| Node * | conExpr, | |||
| const char * | conBin, | |||
| const char * | conSrc, | |||
| bool | conIsLocal, | |||
| int | conInhCount, | |||
| bool | conNoInherit, | |||
| bool | is_internal | |||
| ) |
Definition at line 45 of file pg_constraint.c.
References Anum_pg_constraint_conbin, Anum_pg_constraint_condeferrable, Anum_pg_constraint_condeferred, Anum_pg_constraint_conexclop, Anum_pg_constraint_confdeltype, Anum_pg_constraint_conffeqop, Anum_pg_constraint_confkey, Anum_pg_constraint_confmatchtype, Anum_pg_constraint_confrelid, Anum_pg_constraint_confupdtype, Anum_pg_constraint_conindid, Anum_pg_constraint_coninhcount, Anum_pg_constraint_conislocal, Anum_pg_constraint_conkey, Anum_pg_constraint_conname, Anum_pg_constraint_connamespace, Anum_pg_constraint_connoinherit, Anum_pg_constraint_conpfeqop, Anum_pg_constraint_conppeqop, Anum_pg_constraint_conrelid, Anum_pg_constraint_consrc, Anum_pg_constraint_contype, Anum_pg_constraint_contypid, Anum_pg_constraint_convalidated, Assert, BoolGetDatum, CatalogUpdateIndexes(), CharGetDatum, ObjectAddress::classId, CONSTRAINT_FOREIGN, ConstraintRelationId, construct_array(), CStringGetTextDatum, DEPENDENCY_AUTO, DEPENDENCY_NORMAL, heap_close, heap_form_tuple(), heap_open(), i, Int16GetDatum, INT2OID, Int32GetDatum, InvokeObjectPostCreateHookArg, NameGetDatum, namestrcpy(), NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, OidIsValid, OIDOID, palloc(), PointerGetDatum, recordDependencyOn(), recordDependencyOnSingleRelExpr(), RelationGetDescr, RowExclusiveLock, simple_heap_insert(), and values.
Referenced by ATAddForeignKeyConstraint(), CreateTrigger(), domainAddConstraint(), index_constraint_create(), and StoreRelCheck().
{
Relation conDesc;
Oid conOid;
HeapTuple tup;
bool nulls[Natts_pg_constraint];
Datum values[Natts_pg_constraint];
ArrayType *conkeyArray;
ArrayType *confkeyArray;
ArrayType *conpfeqopArray;
ArrayType *conppeqopArray;
ArrayType *conffeqopArray;
ArrayType *conexclopArray;
NameData cname;
int i;
ObjectAddress conobject;
conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
Assert(constraintName);
namestrcpy(&cname, constraintName);
/*
* Convert C arrays into Postgres arrays.
*/
if (constraintNKeys > 0)
{
Datum *conkey;
conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));
for (i = 0; i < constraintNKeys; i++)
conkey[i] = Int16GetDatum(constraintKey[i]);
conkeyArray = construct_array(conkey, constraintNKeys,
INT2OID, 2, true, 's');
}
else
conkeyArray = NULL;
if (foreignNKeys > 0)
{
Datum *fkdatums;
fkdatums = (Datum *) palloc(foreignNKeys * sizeof(Datum));
for (i = 0; i < foreignNKeys; i++)
fkdatums[i] = Int16GetDatum(foreignKey[i]);
confkeyArray = construct_array(fkdatums, foreignNKeys,
INT2OID, 2, true, 's');
for (i = 0; i < foreignNKeys; i++)
fkdatums[i] = ObjectIdGetDatum(pfEqOp[i]);
conpfeqopArray = construct_array(fkdatums, foreignNKeys,
OIDOID, sizeof(Oid), true, 'i');
for (i = 0; i < foreignNKeys; i++)
fkdatums[i] = ObjectIdGetDatum(ppEqOp[i]);
conppeqopArray = construct_array(fkdatums, foreignNKeys,
OIDOID, sizeof(Oid), true, 'i');
for (i = 0; i < foreignNKeys; i++)
fkdatums[i] = ObjectIdGetDatum(ffEqOp[i]);
conffeqopArray = construct_array(fkdatums, foreignNKeys,
OIDOID, sizeof(Oid), true, 'i');
}
else
{
confkeyArray = NULL;
conpfeqopArray = NULL;
conppeqopArray = NULL;
conffeqopArray = NULL;
}
if (exclOp != NULL)
{
Datum *opdatums;
opdatums = (Datum *) palloc(constraintNKeys * sizeof(Datum));
for (i = 0; i < constraintNKeys; i++)
opdatums[i] = ObjectIdGetDatum(exclOp[i]);
conexclopArray = construct_array(opdatums, constraintNKeys,
OIDOID, sizeof(Oid), true, 'i');
}
else
conexclopArray = NULL;
/* initialize nulls and values */
for (i = 0; i < Natts_pg_constraint; i++)
{
nulls[i] = false;
values[i] = (Datum) NULL;
}
values[Anum_pg_constraint_conname - 1] = NameGetDatum(&cname);
values[Anum_pg_constraint_connamespace - 1] = ObjectIdGetDatum(constraintNamespace);
values[Anum_pg_constraint_contype - 1] = CharGetDatum(constraintType);
values[Anum_pg_constraint_condeferrable - 1] = BoolGetDatum(isDeferrable);
values[Anum_pg_constraint_condeferred - 1] = BoolGetDatum(isDeferred);
values[Anum_pg_constraint_convalidated - 1] = BoolGetDatum(isValidated);
values[Anum_pg_constraint_conrelid - 1] = ObjectIdGetDatum(relId);
values[Anum_pg_constraint_contypid - 1] = ObjectIdGetDatum(domainId);
values[Anum_pg_constraint_conindid - 1] = ObjectIdGetDatum(indexRelId);
values[Anum_pg_constraint_confrelid - 1] = ObjectIdGetDatum(foreignRelId);
values[Anum_pg_constraint_confupdtype - 1] = CharGetDatum(foreignUpdateType);
values[Anum_pg_constraint_confdeltype - 1] = CharGetDatum(foreignDeleteType);
values[Anum_pg_constraint_confmatchtype - 1] = CharGetDatum(foreignMatchType);
values[Anum_pg_constraint_conislocal - 1] = BoolGetDatum(conIsLocal);
values[Anum_pg_constraint_coninhcount - 1] = Int32GetDatum(conInhCount);
values[Anum_pg_constraint_connoinherit - 1] = BoolGetDatum(conNoInherit);
if (conkeyArray)
values[Anum_pg_constraint_conkey - 1] = PointerGetDatum(conkeyArray);
else
nulls[Anum_pg_constraint_conkey - 1] = true;
if (confkeyArray)
values[Anum_pg_constraint_confkey - 1] = PointerGetDatum(confkeyArray);
else
nulls[Anum_pg_constraint_confkey - 1] = true;
if (conpfeqopArray)
values[Anum_pg_constraint_conpfeqop - 1] = PointerGetDatum(conpfeqopArray);
else
nulls[Anum_pg_constraint_conpfeqop - 1] = true;
if (conppeqopArray)
values[Anum_pg_constraint_conppeqop - 1] = PointerGetDatum(conppeqopArray);
else
nulls[Anum_pg_constraint_conppeqop - 1] = true;
if (conffeqopArray)
values[Anum_pg_constraint_conffeqop - 1] = PointerGetDatum(conffeqopArray);
else
nulls[Anum_pg_constraint_conffeqop - 1] = true;
if (conexclopArray)
values[Anum_pg_constraint_conexclop - 1] = PointerGetDatum(conexclopArray);
else
nulls[Anum_pg_constraint_conexclop - 1] = true;
/*
* initialize the binary form of the check constraint.
*/
if (conBin)
values[Anum_pg_constraint_conbin - 1] = CStringGetTextDatum(conBin);
else
nulls[Anum_pg_constraint_conbin - 1] = true;
/*
* initialize the text form of the check constraint
*/
if (conSrc)
values[Anum_pg_constraint_consrc - 1] = CStringGetTextDatum(conSrc);
else
nulls[Anum_pg_constraint_consrc - 1] = true;
tup = heap_form_tuple(RelationGetDescr(conDesc), values, nulls);
conOid = simple_heap_insert(conDesc, tup);
/* update catalog indexes */
CatalogUpdateIndexes(conDesc, tup);
conobject.classId = ConstraintRelationId;
conobject.objectId = conOid;
conobject.objectSubId = 0;
heap_close(conDesc, RowExclusiveLock);
if (OidIsValid(relId))
{
/*
* Register auto dependency from constraint to owning relation, or to
* specific column(s) if any are mentioned.
*/
ObjectAddress relobject;
relobject.classId = RelationRelationId;
relobject.objectId = relId;
if (constraintNKeys > 0)
{
for (i = 0; i < constraintNKeys; i++)
{
relobject.objectSubId = constraintKey[i];
recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO);
}
}
else
{
relobject.objectSubId = 0;
recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO);
}
}
if (OidIsValid(domainId))
{
/*
* Register auto dependency from constraint to owning domain
*/
ObjectAddress domobject;
domobject.classId = TypeRelationId;
domobject.objectId = domainId;
domobject.objectSubId = 0;
recordDependencyOn(&conobject, &domobject, DEPENDENCY_AUTO);
}
if (OidIsValid(foreignRelId))
{
/*
* Register normal dependency from constraint to foreign relation, or
* to specific column(s) if any are mentioned.
*/
ObjectAddress relobject;
relobject.classId = RelationRelationId;
relobject.objectId = foreignRelId;
if (foreignNKeys > 0)
{
for (i = 0; i < foreignNKeys; i++)
{
relobject.objectSubId = foreignKey[i];
recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
}
}
else
{
relobject.objectSubId = 0;
recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
}
}
if (OidIsValid(indexRelId) && constraintType == CONSTRAINT_FOREIGN)
{
/*
* Register normal dependency on the unique index that supports a
* foreign-key constraint. (Note: for indexes associated with unique
* or primary-key constraints, the dependency runs the other way, and
* is not made here.)
*/
ObjectAddress relobject;
relobject.classId = RelationRelationId;
relobject.objectId = indexRelId;
relobject.objectSubId = 0;
recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);
}
if (foreignNKeys > 0)
{
/*
* Register normal dependencies on the equality operators that support
* a foreign-key constraint. If the PK and FK types are the same then
* all three operators for a column are the same; otherwise they are
* different.
*/
ObjectAddress oprobject;
oprobject.classId = OperatorRelationId;
oprobject.objectSubId = 0;
for (i = 0; i < foreignNKeys; i++)
{
oprobject.objectId = pfEqOp[i];
recordDependencyOn(&conobject, &oprobject, DEPENDENCY_NORMAL);
if (ppEqOp[i] != pfEqOp[i])
{
oprobject.objectId = ppEqOp[i];
recordDependencyOn(&conobject, &oprobject, DEPENDENCY_NORMAL);
}
if (ffEqOp[i] != pfEqOp[i])
{
oprobject.objectId = ffEqOp[i];
recordDependencyOn(&conobject, &oprobject, DEPENDENCY_NORMAL);
}
}
}
/*
* We don't bother to register dependencies on the exclusion operators of
* an exclusion constraint. We assume they are members of the opclass
* supporting the index, so there's an indirect dependency via that. (This
* would be pretty dicey for cross-type operators, but exclusion operators
* can never be cross-type.)
*/
if (conExpr != NULL)
{
/*
* Register dependencies from constraint to objects mentioned in CHECK
* expression.
*/
recordDependencyOnSingleRelExpr(&conobject, conExpr, relId,
DEPENDENCY_NORMAL,
DEPENDENCY_NORMAL);
}
/* Post creation hook for new constraint */
InvokeObjectPostCreateHookArg(ConstraintRelationId, conOid, 0,
is_internal);
return conOid;
}
Definition at line 818 of file pg_constraint.c.
References AccessShareLock, Anum_pg_constraint_contypid, BTEqualStrategyNumber, ConstraintRelationId, ConstraintTypidIndexId, ereport, errcode(), errmsg(), ERROR, format_type_be(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, NameStr, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), SnapshotNow, systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by rename_constraint_internal().
{
Relation pg_constraint;
HeapTuple tuple;
SysScanDesc scan;
ScanKeyData skey[1];
Oid conOid = InvalidOid;
/*
* Fetch the constraint tuple from pg_constraint. There may be more than
* one match, because constraints are not required to have unique names;
* if so, error out.
*/
pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
ScanKeyInit(&skey[0],
Anum_pg_constraint_contypid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(typid));
scan = systable_beginscan(pg_constraint, ConstraintTypidIndexId, true,
SnapshotNow, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
{
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
if (strcmp(NameStr(con->conname), conname) == 0)
{
if (OidIsValid(conOid))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("domain \"%s\" has multiple constraints named \"%s\"",
format_type_be(typid), conname)));
conOid = HeapTupleGetOid(tuple);
}
}
systable_endscan(scan);
/* If no such constraint exists, complain */
if (!OidIsValid(conOid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("constraint \"%s\" for domain \"%s\" does not exist",
conname, format_type_be(typid))));
heap_close(pg_constraint, AccessShareLock);
return conOid;
}
Definition at line 760 of file pg_constraint.c.
References AccessShareLock, Anum_pg_constraint_conrelid, BTEqualStrategyNumber, ConstraintRelationId, ConstraintRelidIndexId, ereport, errcode(), errmsg(), ERROR, get_rel_name(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, NameStr, ObjectIdGetDatum, OidIsValid, ScanKeyInit(), SnapshotNow, systable_beginscan(), systable_endscan(), and systable_getnext().
Referenced by get_object_address_relobject(), rename_constraint_internal(), and transformTableLikeClause().
{
Relation pg_constraint;
HeapTuple tuple;
SysScanDesc scan;
ScanKeyData skey[1];
Oid conOid = InvalidOid;
/*
* Fetch the constraint tuple from pg_constraint. There may be more than
* one match, because constraints are not required to have unique names;
* if so, error out.
*/
pg_constraint = heap_open(ConstraintRelationId, AccessShareLock);
ScanKeyInit(&skey[0],
Anum_pg_constraint_conrelid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(relid));
scan = systable_beginscan(pg_constraint, ConstraintRelidIndexId, true,
SnapshotNow, 1, skey);
while (HeapTupleIsValid(tuple = systable_getnext(scan)))
{
Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
if (strcmp(NameStr(con->conname), conname) == 0)
{
if (OidIsValid(conOid))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("table \"%s\" has multiple constraints named \"%s\"",
get_rel_name(relid), conname)));
conOid = HeapTupleGetOid(tuple);
}
}
systable_endscan(scan);
/* If no such constraint exists, complain */
if (!OidIsValid(conOid) && !missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("constraint \"%s\" for table \"%s\" does not exist",
conname, get_rel_name(relid))));
heap_close(pg_constraint, AccessShareLock);
return conOid;
}
| void RemoveConstraintById | ( | Oid | conId | ) |
Definition at line 533 of file pg_constraint.c.
References AccessExclusiveLock, CatalogUpdateIndexes(), CONSTRAINT_CHECK, ConstraintRelationId, CONSTROID, elog, ERROR, GETSTRUCT, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, NoLock, ObjectIdGetDatum, OidIsValid, RelationGetRelationName, RelationRelationId, ReleaseSysCache(), RELOID, RowExclusiveLock, SearchSysCache1, SearchSysCacheCopy1, simple_heap_delete(), simple_heap_update(), and HeapTupleData::t_self.
Referenced by doDeletion().
{
Relation conDesc;
HeapTuple tup;
Form_pg_constraint con;
conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
tup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(conId));
if (!HeapTupleIsValid(tup)) /* should not happen */
elog(ERROR, "cache lookup failed for constraint %u", conId);
con = (Form_pg_constraint) GETSTRUCT(tup);
/*
* Special processing depending on what the constraint is for.
*/
if (OidIsValid(con->conrelid))
{
Relation rel;
/*
* If the constraint is for a relation, open and exclusive-lock the
* relation it's for.
*/
rel = heap_open(con->conrelid, AccessExclusiveLock);
/*
* We need to update the relcheck count if it is a check constraint
* being dropped. This update will force backends to rebuild relcache
* entries when we commit.
*/
if (con->contype == CONSTRAINT_CHECK)
{
Relation pgrel;
HeapTuple relTup;
Form_pg_class classForm;
pgrel = heap_open(RelationRelationId, RowExclusiveLock);
relTup = SearchSysCacheCopy1(RELOID,
ObjectIdGetDatum(con->conrelid));
if (!HeapTupleIsValid(relTup))
elog(ERROR, "cache lookup failed for relation %u",
con->conrelid);
classForm = (Form_pg_class) GETSTRUCT(relTup);
if (classForm->relchecks == 0) /* should not happen */
elog(ERROR, "relation \"%s\" has relchecks = 0",
RelationGetRelationName(rel));
classForm->relchecks--;
simple_heap_update(pgrel, &relTup->t_self, relTup);
CatalogUpdateIndexes(pgrel, relTup);
heap_freetuple(relTup);
heap_close(pgrel, RowExclusiveLock);
}
/* Keep lock on constraint's rel until end of xact */
heap_close(rel, NoLock);
}
else if (OidIsValid(con->contypid))
{
/*
* XXX for now, do nothing special when dropping a domain constraint
*
* Probably there should be some form of locking on the domain type,
* but we have no such concept at the moment.
*/
}
else
elog(ERROR, "constraint %u is not of a known type", conId);
/* Fry the constraint itself */
simple_heap_delete(conDesc, &tup->t_self);
/* Clean up */
ReleaseSysCache(tup);
heap_close(conDesc, RowExclusiveLock);
}
| void RenameConstraintById | ( | Oid | conId, | |
| const char * | newname | |||
| ) |
Definition at line 626 of file pg_constraint.c.
References CatalogUpdateIndexes(), CONSTRAINT_DOMAIN, CONSTRAINT_RELATION, ConstraintNameIsUsed(), ConstraintRelationId, CONSTROID, elog, ereport, errcode(), errmsg(), ERROR, format_type_be(), get_rel_name(), GETSTRUCT, heap_close, heap_freetuple(), heap_open(), HeapTupleIsValid, InvokeObjectPostAlterHook, namestrcpy(), ObjectIdGetDatum, OidIsValid, RowExclusiveLock, SearchSysCacheCopy1, simple_heap_update(), and HeapTupleData::t_self.
Referenced by rename_constraint_internal(), and RenameRelationInternal().
{
Relation conDesc;
HeapTuple tuple;
Form_pg_constraint con;
conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);
tuple = SearchSysCacheCopy1(CONSTROID, ObjectIdGetDatum(conId));
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for constraint %u", conId);
con = (Form_pg_constraint) GETSTRUCT(tuple);
/*
* We need to check whether the name is already in use --- note that there
* currently is not a unique index that would catch this.
*/
if (OidIsValid(con->conrelid) &&
ConstraintNameIsUsed(CONSTRAINT_RELATION,
con->conrelid,
con->connamespace,
newname))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("constraint \"%s\" for relation \"%s\" already exists",
newname, get_rel_name(con->conrelid))));
if (OidIsValid(con->contypid) &&
ConstraintNameIsUsed(CONSTRAINT_DOMAIN,
con->contypid,
con->connamespace,
newname))
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("constraint \"%s\" for domain %s already exists",
newname, format_type_be(con->contypid))));
/* OK, do the rename --- tuple is a copy, so OK to scribble on it */
namestrcpy(&(con->conname), newname);
simple_heap_update(conDesc, &tuple->t_self, tuple);
/* update the system catalog indexes */
CatalogUpdateIndexes(conDesc, tuple);
InvokeObjectPostAlterHook(ConstraintRelationId, conId, 0);
heap_freetuple(tuple);
heap_close(conDesc, RowExclusiveLock);
}
1.7.1