1
0
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:
Alvaro Herrera
2015-05-05 15:22:24 -03:00
parent 456ff08638
commit 3b6db1f445
18 changed files with 363 additions and 16 deletions

View File

@@ -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