diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/utils/adt/multirangetypes.c | 60 | ||||
-rw-r--r-- | src/backend/utils/adt/multirangetypes_selfuncs.c | 6 |
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) { |