mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Implement operators for checking if the range contains a multirange
We have operators for checking if the multirange contains a range but don't have the opposite. This commit improves completeness of the operator set by adding two new operators: @> (anyrange,anymultirange) and <@(anymultirange,anyrange). Catversion is bumped.
This commit is contained in:
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Reference in New Issue
Block a user