Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Typedefs | Enumerations | Functions | Variables

pg_constraint.h File Reference

#include "catalog/genbki.h"
#include "catalog/dependency.h"
#include "nodes/pg_list.h"
Include dependency graph for pg_constraint.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define ConstraintRelationId   2606
#define Natts_pg_constraint   24
#define Anum_pg_constraint_conname   1
#define Anum_pg_constraint_connamespace   2
#define Anum_pg_constraint_contype   3
#define Anum_pg_constraint_condeferrable   4
#define Anum_pg_constraint_condeferred   5
#define Anum_pg_constraint_convalidated   6
#define Anum_pg_constraint_conrelid   7
#define Anum_pg_constraint_contypid   8
#define Anum_pg_constraint_conindid   9
#define Anum_pg_constraint_confrelid   10
#define Anum_pg_constraint_confupdtype   11
#define Anum_pg_constraint_confdeltype   12
#define Anum_pg_constraint_confmatchtype   13
#define Anum_pg_constraint_conislocal   14
#define Anum_pg_constraint_coninhcount   15
#define Anum_pg_constraint_connoinherit   16
#define Anum_pg_constraint_conkey   17
#define Anum_pg_constraint_confkey   18
#define Anum_pg_constraint_conpfeqop   19
#define Anum_pg_constraint_conppeqop   20
#define Anum_pg_constraint_conffeqop   21
#define Anum_pg_constraint_conexclop   22
#define Anum_pg_constraint_conbin   23
#define Anum_pg_constraint_consrc   24
#define CONSTRAINT_CHECK   'c'
#define CONSTRAINT_FOREIGN   'f'
#define CONSTRAINT_PRIMARY   'p'
#define CONSTRAINT_UNIQUE   'u'
#define CONSTRAINT_TRIGGER   't'
#define CONSTRAINT_EXCLUSION   'x'

Typedefs

typedef FormData_pg_constraintForm_pg_constraint
typedef enum ConstraintCategory ConstraintCategory

Enumerations

enum  ConstraintCategory { CONSTRAINT_RELATION, CONSTRAINT_DOMAIN, CONSTRAINT_ASSERTION }

Functions

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

Variables

 FormData_pg_constraint

Define Documentation

#define Anum_pg_constraint_conbin   23
#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
#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
#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
#define Anum_pg_constraint_conname   1
#define Anum_pg_constraint_connamespace   2
#define Anum_pg_constraint_connoinherit   16

Definition at line 171 of file pg_constraint.h.

Referenced by CreateConstraintEntry().

#define Anum_pg_constraint_conpfeqop   19
#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
#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
#define Anum_pg_constraint_convalidated   6

Definition at line 161 of file pg_constraint.h.

Referenced by CreateConstraintEntry().

#define CONSTRAINT_CHECK   'c'
#define CONSTRAINT_EXCLUSION   'x'
#define CONSTRAINT_FOREIGN   'f'
#define CONSTRAINT_PRIMARY   'p'
#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
#define Natts_pg_constraint   24

Definition at line 155 of file pg_constraint.h.


Typedef Documentation

Definition at line 149 of file pg_constraint.h.


Enumeration Type Documentation

Enumerator:
CONSTRAINT_RELATION 
CONSTRAINT_DOMAIN 
CONSTRAINT_ASSERTION 

Definition at line 199 of file pg_constraint.h.

{
    CONSTRAINT_RELATION,
    CONSTRAINT_DOMAIN,
    CONSTRAINT_ASSERTION        /* for future expansion */
} ConstraintCategory;


Function Documentation

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 
)
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;
}

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

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;
}

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

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  ) 

Variable Documentation

Definition at line 142 of file pg_constraint.h.