diff options
Diffstat (limited to 'src/backend/catalog/pg_constraint.c')
-rw-r--r-- | src/backend/catalog/pg_constraint.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index f1543ae7d35..604280d322e 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -15,6 +15,7 @@ #include "postgres.h" #include "access/genam.h" +#include "access/gist.h" #include "access/htup_details.h" #include "access/sysattr.h" #include "access/table.h" @@ -1650,6 +1651,63 @@ DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, } /* + * FindFkPeriodOpers - + * + * Looks up the operator oids used for the PERIOD part of a temporal foreign key. + * The opclass should be the opclass of that PERIOD element. + * Everything else is an output: containedbyoperoid is the ContainedBy operator for + * types matching the PERIOD element. + * aggedcontainedbyoperoid is also a ContainedBy operator, + * but one whose rhs is a multirange. + * That way foreign keys can compare fkattr <@ range_agg(pkattr). + */ +void +FindFKPeriodOpers(Oid opclass, + Oid *containedbyoperoid, + Oid *aggedcontainedbyoperoid) +{ + Oid opfamily = InvalidOid; + Oid opcintype = InvalidOid; + StrategyNumber strat; + + /* Make sure we have a range or multirange. */ + if (get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype)) + { + if (opcintype != ANYRANGEOID && opcintype != ANYMULTIRANGEOID) + ereport(ERROR, + errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("invalid type for PERIOD part of foreign key"), + errdetail("Only range and multirange are supported.")); + + } + else + elog(ERROR, "cache lookup failed for opclass %u", opclass); + + /* + * Look up the ContainedBy operator whose lhs and rhs are the opclass's + * type. We use this to optimize RI checks: if the new value includes all + * of the old value, then we can treat the attribute as if it didn't + * change, and skip the RI check. + */ + strat = RTContainedByStrategyNumber; + GetOperatorFromWellKnownStrategy(opclass, + InvalidOid, + containedbyoperoid, + &strat); + + /* + * Now look up the ContainedBy operator. Its left arg must be the type of + * the column (or rather of the opclass). Its right arg must match the + * return type of the support proc. + */ + strat = RTContainedByStrategyNumber; + GetOperatorFromWellKnownStrategy(opclass, + ANYMULTIRANGEOID, + aggedcontainedbyoperoid, + &strat); +} + +/* * Determine whether a relation can be proven functionally dependent on * a set of grouping columns. If so, return true and add the pg_constraint * OIDs of the constraints needed for the proof to the *constraintDeps list. |