mirror of
https://github.com/postgres/postgres.git
synced 2025-11-24 00:23:06 +03:00
Add geometry/range functions to support BRIN inclusion
This commit adds the following functions:
box(point) -> box
bound_box(box, box) -> box
inet_same_family(inet, inet) -> bool
inet_merge(inet, inet) -> cidr
range_merge(anyrange, anyrange) -> anyrange
The first of these is also used to implement a new assignment cast from
point to box.
These functions are the first part of a base to implement an "inclusion"
operator class for BRIN, for multidimensional data types.
Author: Emre Hasegeli
Reviewed by: Andreas Karlsson
This commit is contained in:
@@ -887,6 +887,58 @@ network_hostmask(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_INET_P(dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the addresses are from the same family, or false. Used to
|
||||
* check that we can create a network which contains both of the networks.
|
||||
*/
|
||||
Datum
|
||||
inet_same_family(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *a1 = PG_GETARG_INET_PP(0);
|
||||
inet *a2 = PG_GETARG_INET_PP(1);
|
||||
|
||||
PG_RETURN_BOOL(ip_family(a1) == ip_family(a2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the smallest CIDR which contains both of the inputs.
|
||||
*/
|
||||
Datum
|
||||
inet_merge(PG_FUNCTION_ARGS)
|
||||
{
|
||||
inet *a1 = PG_GETARG_INET_PP(0),
|
||||
*a2 = PG_GETARG_INET_PP(1),
|
||||
*result;
|
||||
int commonbits;
|
||||
|
||||
if (ip_family(a1) != ip_family(a2))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("cannot merge addresses from different families")));
|
||||
|
||||
commonbits = bitncommon(ip_addr(a1), ip_addr(a2),
|
||||
Min(ip_bits(a1), ip_bits(a2)));
|
||||
|
||||
/* Make sure any unused bits are zeroed. */
|
||||
result = (inet *) palloc0(sizeof(inet));
|
||||
|
||||
ip_family(result) = ip_family(a1);
|
||||
ip_bits(result) = commonbits;
|
||||
|
||||
/* Clone appropriate bytes of the address. */
|
||||
if (commonbits > 0)
|
||||
memcpy(ip_addr(result), ip_addr(a1), (commonbits + 7) / 8);
|
||||
|
||||
/* Clean any unwanted bits in the last partial byte. */
|
||||
if (commonbits % 8 != 0)
|
||||
ip_addr(result)[commonbits / 8] &= ~(0xFF >> (commonbits % 8));
|
||||
|
||||
/* Set varlena header correctly. */
|
||||
SET_INET_VARSIZE(result);
|
||||
|
||||
PG_RETURN_INET_P(result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a value of a network datatype to an approximate scalar value.
|
||||
* This is used for estimating selectivities of inequality operators
|
||||
|
||||
Reference in New Issue
Block a user