#include "catalog/genbki.h"
#include "catalog/dependency.h"
#include "nodes/pg_list.h"
Go to the source code of this file.
#define Anum_pg_constraint_conbin 23 |
Definition at line 178 of file pg_constraint.h.
Referenced by AlterDomainValidateConstraint(), CheckConstraintFetch(), CreateConstraintEntry(), decompile_conbin(), GetDomainConstraints(), MergeWithExistingConstraint(), pg_get_constraintdef_worker(), and validateCheckConstraint().
#define Anum_pg_constraint_condeferrable 4 |
Definition at line 159 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_condeferred 5 |
Definition at line 160 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_conexclop 22 |
Definition at line 177 of file pg_constraint.h.
Referenced by CreateConstraintEntry(), generateClonedIndexStmt(), pg_get_constraintdef_worker(), and RelationGetExclusionInfo().
#define Anum_pg_constraint_confdeltype 12 |
Definition at line 167 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_conffeqop 21 |
Definition at line 176 of file pg_constraint.h.
Referenced by CreateConstraintEntry(), and ri_LoadConstraintInfo().
#define Anum_pg_constraint_confkey 18 |
Definition at line 173 of file pg_constraint.h.
Referenced by CreateConstraintEntry(), pg_get_constraintdef_worker(), and ri_LoadConstraintInfo().
#define Anum_pg_constraint_confmatchtype 13 |
Definition at line 168 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_confrelid 10 |
Definition at line 165 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_confupdtype 11 |
Definition at line 166 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_conindid 9 |
Definition at line 164 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_coninhcount 15 |
Definition at line 170 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_conislocal 14 |
Definition at line 169 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_conkey 17 |
Definition at line 172 of file pg_constraint.h.
Referenced by check_functional_grouping(), CreateConstraintEntry(), pg_get_constraintdef_worker(), and ri_LoadConstraintInfo().
#define Anum_pg_constraint_conname 1 |
Definition at line 156 of file pg_constraint.h.
Referenced by AfterTriggerSetState(), ChooseConstraintName(), ConstraintNameIsUsed(), CreateConstraintEntry(), and MergeWithExistingConstraint().
#define Anum_pg_constraint_connamespace 2 |
Definition at line 157 of file pg_constraint.h.
Referenced by AfterTriggerSetState(), ChooseConstraintName(), ConstraintNameIsUsed(), CreateConstraintEntry(), and MergeWithExistingConstraint().
#define Anum_pg_constraint_connoinherit 16 |
Definition at line 171 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_conpfeqop 19 |
Definition at line 174 of file pg_constraint.h.
Referenced by CreateConstraintEntry(), ri_LoadConstraintInfo(), and TryReuseForeignKey().
#define Anum_pg_constraint_conppeqop 20 |
Definition at line 175 of file pg_constraint.h.
Referenced by CreateConstraintEntry(), and ri_LoadConstraintInfo().
#define Anum_pg_constraint_conrelid 7 |
Definition at line 162 of file pg_constraint.h.
Referenced by AlterConstraintNamespaces(), ATExecDropConstraint(), ATExecDropInherit(), ATExecValidateConstraint(), check_functional_grouping(), CheckConstraintFetch(), CreateConstraintEntry(), get_relation_constraint_oid(), MergeConstraintsIntoExisting(), and RelationGetExclusionInfo().
#define Anum_pg_constraint_consrc 24 |
Definition at line 179 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_contype 3 |
Definition at line 158 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define Anum_pg_constraint_contypid 8 |
Definition at line 163 of file pg_constraint.h.
Referenced by AlterConstraintNamespaces(), AlterDomainDropConstraint(), AlterDomainValidateConstraint(), CreateConstraintEntry(), get_domain_constraint_oid(), and GetDomainConstraints().
#define Anum_pg_constraint_convalidated 6 |
Definition at line 161 of file pg_constraint.h.
Referenced by CreateConstraintEntry().
#define CONSTRAINT_CHECK 'c' |
Definition at line 183 of file pg_constraint.h.
Referenced by AlterDomainValidateConstraint(), ATExecDropConstraint(), ATExecDropInherit(), ATExecValidateConstraint(), CheckConstraintFetch(), domainAddConstraint(), GetDomainConstraints(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), pg_get_constraintdef_worker(), RemoveConstraintById(), rename_constraint_internal(), and StoreRelCheck().
#define CONSTRAINT_EXCLUSION 'x' |
Definition at line 188 of file pg_constraint.h.
Referenced by generateClonedIndexStmt(), index_constraint_create(), pg_get_constraintdef_worker(), RelationGetExclusionInfo(), and rename_constraint_internal().
#define CONSTRAINT_FOREIGN 'f' |
Definition at line 184 of file pg_constraint.h.
Referenced by ATAddForeignKeyConstraint(), ATExecValidateConstraint(), CreateConstraintEntry(), heap_truncate_find_FKs(), pg_get_constraintdef_worker(), and ri_LoadConstraintInfo().
#define CONSTRAINT_PRIMARY 'p' |
Definition at line 185 of file pg_constraint.h.
Referenced by check_functional_grouping(), pg_get_constraintdef_worker(), and rename_constraint_internal().
#define CONSTRAINT_TRIGGER 't' |
Definition at line 187 of file pg_constraint.h.
Referenced by CreateTrigger(), and pg_get_constraintdef_worker().
#define CONSTRAINT_UNIQUE 'u' |
Definition at line 186 of file pg_constraint.h.
Referenced by pg_get_constraintdef_worker(), and rename_constraint_internal().
#define ConstraintRelationId 2606 |
Definition at line 31 of file pg_constraint.h.
Referenced by AfterTriggerSetState(), AlterConstraintNamespaces(), AlterDomainDropConstraint(), AlterDomainValidateConstraint(), ATExecDropConstraint(), ATExecDropInherit(), ATExecValidateConstraint(), check_functional_grouping(), CheckConstraintFetch(), ChooseConstraintName(), ConstraintNameIsUsed(), CreateConstraintEntry(), get_constraint_index(), get_domain_constraint_oid(), get_index_constraint(), get_relation_constraint_oid(), getConstraintTypeDescription(), GetDomainConstraints(), getObjectClass(), heap_truncate_find_FKs(), MergeConstraintsIntoExisting(), MergeWithExistingConstraint(), RelationGetExclusionInfo(), RemoveConstraintById(), RenameConstraintById(), and transformTableLikeClause().
#define Natts_pg_constraint 24 |
Definition at line 155 of file pg_constraint.h.
typedef enum ConstraintCategory ConstraintCategory |
typedef FormData_pg_constraint* Form_pg_constraint |
Definition at line 149 of file pg_constraint.h.
enum ConstraintCategory |
Definition at line 199 of file pg_constraint.h.
{ CONSTRAINT_RELATION, CONSTRAINT_DOMAIN, CONSTRAINT_ASSERTION /* for future expansion */ } ConstraintCategory;
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); }
CATALOG | ( | pg_constraint | , | |
2606 | ||||
) |
Definition at line 33 of file pg_constraint.h.
{ /* * conname + connamespace is deliberately not unique; we allow, for * example, the same name to be used for constraints of different * relations. This is partly for backwards compatibility with past * Postgres practice, and partly because we don't want to have to obtain a * global lock to generate a globally unique name for a nameless * constraint. We associate a namespace with constraint names only for * SQL-spec compatibility. */ NameData conname; /* name of this constraint */ Oid connamespace; /* OID of namespace containing constraint */ char contype; /* constraint type; see codes below */ bool condeferrable; /* deferrable constraint? */ bool condeferred; /* deferred by default? */ bool convalidated; /* constraint has been validated? */ /* * conrelid and conkey are only meaningful if the constraint applies to a * specific relation (this excludes domain constraints and assertions). * Otherwise conrelid is 0 and conkey is NULL. */ Oid conrelid; /* relation this constraint constrains */ /* * contypid links to the pg_type row for a domain if this is a domain * constraint. Otherwise it's 0. * * For SQL-style global ASSERTIONs, both conrelid and contypid would be * zero. This is not presently supported, however. */ Oid contypid; /* domain this constraint constrains */ /* * conindid links to the index supporting the constraint, if any; * otherwise it's 0. This is used for unique, primary-key, and exclusion * constraints, and less obviously for foreign-key constraints (where the * index is a unique index on the referenced relation's referenced * columns). Notice that the index is on conrelid in the first case but * confrelid in the second. */ Oid conindid; /* index supporting this constraint */ /* * These fields, plus confkey, are only meaningful for a foreign-key * constraint. Otherwise confrelid is 0 and the char fields are spaces. */ Oid confrelid; /* relation referenced by foreign key */ char confupdtype; /* foreign key's ON UPDATE action */ char confdeltype; /* foreign key's ON DELETE action */ char confmatchtype; /* foreign key's match type */ /* Has a local definition (hence, do not drop when coninhcount is 0) */ bool conislocal; /* Number of times inherited from direct parent relation(s) */ int32 coninhcount; /* Has a local definition and cannot be inherited */ bool connoinherit; #ifdef CATALOG_VARLEN /* variable-length fields start here */ /* * Columns of conrelid that the constraint applies to, if known (this is * NULL for trigger constraints) */ int16 conkey[1]; /* * If a foreign key, the referenced columns of confrelid */ int16 confkey[1]; /* * If a foreign key, the OIDs of the PK = FK equality operators for each * column of the constraint */ Oid conpfeqop[1]; /* * If a foreign key, the OIDs of the PK = PK equality operators for each * column of the constraint (i.e., equality for the referenced columns) */ Oid conppeqop[1]; /* * If a foreign key, the OIDs of the FK = FK equality operators for each * column of the constraint (i.e., equality for the referencing columns) */ Oid conffeqop[1]; /* * If an exclusion constraint, the OIDs of the exclusion operators for * each column of the constraint */ Oid conexclop[1]; /* * If a check constraint, nodeToString representation of expression */ pg_node_tree conbin; /* * If a check constraint, source-text representation of expression */ text consrc; #endif } FormData_pg_constraint;
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); }
void SetValidatedConstraintById | ( | Oid | conId | ) |
Definition at line 142 of file pg_constraint.h.