aboutsummaryrefslogtreecommitdiff
path: root/src/backend/catalog/pg_constraint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/catalog/pg_constraint.c')
-rw-r--r--src/backend/catalog/pg_constraint.c58
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.