aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/utils/adt/multirangetypes.c60
-rw-r--r--src/backend/utils/adt/multirangetypes_selfuncs.c6
2 files changed, 65 insertions, 1 deletions
diff --git a/src/backend/utils/adt/multirangetypes.c b/src/backend/utils/adt/multirangetypes.c
index 46f661fee49..4b86be583ef 100644
--- a/src/backend/utils/adt/multirangetypes.c
+++ b/src/backend/utils/adt/multirangetypes.c
@@ -1631,6 +1631,18 @@ multirange_contains_range(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(multirange_contains_range_internal(typcache, mr, r));
}
+Datum
+range_contains_multirange(PG_FUNCTION_ARGS)
+{
+ RangeType *r = PG_GETARG_RANGE_P(0);
+ MultirangeType *mr = PG_GETARG_MULTIRANGE_P(1);
+ TypeCacheEntry *typcache;
+
+ typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
+
+ PG_RETURN_BOOL(range_contains_multirange_internal(typcache, r, mr));
+}
+
/* contained by? */
Datum
range_contained_by_multirange(PG_FUNCTION_ARGS)
@@ -1644,6 +1656,18 @@ range_contained_by_multirange(PG_FUNCTION_ARGS)
PG_RETURN_BOOL(multirange_contains_range_internal(typcache, mr, r));
}
+Datum
+multirange_contained_by_range(PG_FUNCTION_ARGS)
+{
+ MultirangeType *mr = PG_GETARG_MULTIRANGE_P(0);
+ RangeType *r = PG_GETARG_RANGE_P(1);
+ TypeCacheEntry *typcache;
+
+ typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
+
+ PG_RETURN_BOOL(range_contains_multirange_internal(typcache, r, mr));
+}
+
/*
* Comparison function for checking if any range of multirange contains given
* key range using binary search.
@@ -1701,6 +1725,42 @@ multirange_contains_range_internal(TypeCacheEntry *typcache, MultirangeType *mr,
multirange_range_contains_bsearch_comparison);
}
+/*
+ * Test whether range r contains a multirange mr.
+ */
+bool
+range_contains_multirange_internal(TypeCacheEntry *typcache, RangeType *r,
+ MultirangeType *mr)
+{
+ TypeCacheEntry *rangetyp;
+ RangeBound lower1,
+ upper1,
+ lower2,
+ upper2,
+ tmp;
+ bool empty;
+
+ rangetyp = typcache->rngtype;
+
+ /*
+ * Every range contains an infinite number of empty multiranges, even an
+ * empty one.
+ */
+ if (MultirangeIsEmpty(mr))
+ return true;
+
+ if (RangeIsEmpty(r))
+ return false;
+
+ /* Range contains multirange iff it contains its union range. */
+ range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
+ Assert(!empty);
+ multirange_get_bounds(rangetyp, mr, 0, &lower2, &tmp);
+ multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper2);
+
+ return range_bounds_contains(rangetyp, &lower1, &upper1, &lower2, &upper2);
+}
+
/* multirange, multirange -> bool functions */
diff --git a/src/backend/utils/adt/multirangetypes_selfuncs.c b/src/backend/utils/adt/multirangetypes_selfuncs.c
index 7259af0b853..bb016b6e987 100644
--- a/src/backend/utils/adt/multirangetypes_selfuncs.c
+++ b/src/backend/utils/adt/multirangetypes_selfuncs.c
@@ -86,6 +86,8 @@ default_multirange_selectivity(Oid operator)
case OID_RANGE_OVERLAPS_MULTIRANGE_OP:
return 0.01;
+ case OID_RANGE_CONTAINS_MULTIRANGE_OP:
+ case OID_RANGE_MULTIRANGE_CONTAINED_OP:
case OID_MULTIRANGE_CONTAINS_RANGE_OP:
case OID_MULTIRANGE_CONTAINS_MULTIRANGE_OP:
case OID_MULTIRANGE_RANGE_CONTAINED_OP:
@@ -224,7 +226,8 @@ multirangesel(PG_FUNCTION_ARGS)
1, &constrange);
}
}
- else if (operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
+ else if (operator == OID_RANGE_MULTIRANGE_CONTAINED_OP ||
+ operator == OID_MULTIRANGE_CONTAINS_RANGE_OP ||
operator == OID_MULTIRANGE_OVERLAPS_RANGE_OP ||
operator == OID_MULTIRANGE_OVERLAPS_LEFT_RANGE_OP ||
operator == OID_MULTIRANGE_OVERLAPS_RIGHT_RANGE_OP ||
@@ -248,6 +251,7 @@ multirangesel(PG_FUNCTION_ARGS)
operator == OID_RANGE_OVERLAPS_RIGHT_MULTIRANGE_OP ||
operator == OID_RANGE_LEFT_MULTIRANGE_OP ||
operator == OID_RANGE_RIGHT_MULTIRANGE_OP ||
+ operator == OID_RANGE_CONTAINS_MULTIRANGE_OP ||
operator == OID_MULTIRANGE_ELEM_CONTAINED_OP ||
operator == OID_MULTIRANGE_RANGE_CONTAINED_OP)
{