diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml index 1ac282c..65bad58 100644 --- a/doc/src/sgml/brin.sgml +++ b/doc/src/sgml/brin.sgml @@ -245,20 +245,36 @@ inet < <= = >= > + inet_inclusion_ops + inet + + && + >> + >>= + << + <<= + < + <= + = + >= + > + + + bpchar_minmax_ops character < <= = >= > @@ -366,30 +382,71 @@ uuid < <= = >= > + range_inclusion_ops + any range type + + && + &> + &< + >> + << + <@ + = + @> + < + <= + = + >= + > + + + + + pg_lsn_minmax_ops pg_lsn < <= = >= > + + box_inclusion_ops + box type + + && + &> + &< + >> + << + <@ + ~= + @> + &>| + |&< + >>| + |<< + + + + Extensibility The BRIN interface has a high level of abstraction, diff --git a/src/backend/access/brin/Makefile b/src/backend/access/brin/Makefile index ac44fcd..fb36882 100644 --- a/src/backend/access/brin/Makefile +++ b/src/backend/access/brin/Makefile @@ -6,13 +6,13 @@ # IDENTIFICATION # src/backend/access/brin/Makefile # #------------------------------------------------------------------------- subdir = src/backend/access/brin top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global OBJS = brin.o brin_pageops.o brin_revmap.o brin_tuple.o brin_xlog.o \ - brin_minmax.o + brin_minmax.o brin_inclusion.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c new file mode 100644 index 0000000..90616fc --- /dev/null +++ b/src/backend/access/brin/brin_inclusion.c @@ -0,0 +1,369 @@ +/* + * brin_inclusion.c + * Implementation of inclusion opclasses for BRIN + * + * This module provides C level BRIN support functions for the *_inclusion_ops + * operator classes. SQL level support functions are also required to + * the opclasses. + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * src/backend/access/brin/brin_inclusion.c + */ +#include "postgres.h" + +#include "access/genam.h" +#include "access/brin_internal.h" +#include "access/brin_tuple.h" +#include "access/skey.h" +#include "catalog/pg_type.h" +#include "utils/datum.h" +#include "utils/lsyscache.h" +#include "utils/syscache.h" + + +/* + * We need operator functions of the strategies and a union function in + * addition to the standard BRIN support functions. To be able to lookup + * the functions with the strategy numbers, we will give number 0 to + * the union function. + * + * Procedure numbers must not collide with BRIN_PROCNUM defines in + * brin_internal.h. So, we will give the procedure number, + * BRIN_RESERVED_PROCNUM + 1 to the union function, and we will add + * BRIN_RESERVED_PROCNUM + 1 the procedure numbers of the operator functions + * of the strategies. + * + * Note that the not all of the operator functions are required as support + * functions. Procedures of of the contained by and basic comparison + * operators, the deprecated ones, the ones for KNN search has no use. So, + * don't add procedures number 17, 19, 24, 25, 29, 30, 31, 32, 33, 34, 37. + * See the consistent function for the usages of the required ones. + */ +#define INCLUSION_MIN_PROCNUM BRIN_RESERVED_PROCNUM + 1 +#define INCLUSION_PROC_COUNT RTMaxStrategyNumber + 1 +#define INCLUSION_UNION_NUM 0 + +typedef struct RangeOpaque +{ + FmgrInfo operators[INCLUSION_PROC_COUNT]; + bool inited[INCLUSION_PROC_COUNT]; +} RangeOpaque; + +static FmgrInfo *inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, + uint16 procnum); + + +/* + * BRIN inclusion OpcInfo function + */ +Datum +brin_inclusion_opcinfo(PG_FUNCTION_ARGS) +{ + Oid typoid = PG_GETARG_OID(0); + BrinOpcInfo *result; + + /* + * opaque->operators is initialized lazily, as indicated by 'inited' + * which is initialized to all false by palloc0. + */ + result = palloc0(MAXALIGN(SizeofBrinOpcInfo(1)) + sizeof(RangeOpaque)); + result->oi_nstored = 1; + result->oi_opaque = (RangeOpaque *) + MAXALIGN((char *) result + SizeofBrinOpcInfo(1)); + result->oi_typids[0] = typoid; + + PG_RETURN_POINTER(result); +} + +/* + * BRIN inclusion add value function + * + * Examine the given index tuple (which contains partial status of a certain + * page range) by comparing it to the given value that comes from another heap + * tuple. If the new value is outside the min/max range specified by the + * existing tuple values, update the index tuple and return true. Otherwise, + * return false and do not modify in this case. + */ +Datum +brin_inclusion_add_value(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + Datum newval = PG_GETARG_DATUM(2); + bool isnull = PG_GETARG_BOOL(3); + Oid colloid = PG_GET_COLLATION(); + FmgrInfo *frmg; + Datum result; + AttrNumber attno; + Form_pg_attribute attr; + + /* + * If the new value is null, we record that we saw it if it's the first + * one; otherwise, there's nothing to do. + */ + if (isnull) + { + if (column->bv_hasnulls) + PG_RETURN_BOOL(false); + + column->bv_hasnulls = true; + PG_RETURN_BOOL(true); + } + + attno = column->bv_attno; + attr = bdesc->bd_tupdesc->attrs[attno - 1]; + + /* + * If the recorded value is null, store the new value (which we know to be + * not null), and we're done. + */ + if (column->bv_allnulls) + { + column->bv_values[0] = datumCopy(newval, attr->attbyval, attr->attlen); + column->bv_allnulls = false; + PG_RETURN_BOOL(true); + } + + frmg = inclusion_get_procinfo(bdesc, attno, RTContainsStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], newval); + if (DatumGetBool(result)) + PG_RETURN_BOOL(false); + + frmg = inclusion_get_procinfo(bdesc, attno, INCLUSION_UNION_NUM); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], newval); + + if (!attr->attbyval) + pfree(DatumGetPointer(column->bv_values[0])); + + column->bv_values[0] = result; + + PG_RETURN_BOOL(true); +} + +/* + * BRIN inclusion consistent function + */ +Datum +brin_inclusion_consistent(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + ScanKey key = (ScanKey) PG_GETARG_POINTER(2); + Oid colloid = PG_GET_COLLATION(); + AttrNumber attno; + Datum query; + FmgrInfo *frmg; + Datum result; + + Assert(key->sk_attno == column->bv_attno); + + /* Handle IS NULL/IS NOT NULL tests. */ + if (key->sk_flags & SK_ISNULL) + { + if (key->sk_flags & SK_SEARCHNULL) + { + if (column->bv_allnulls || column->bv_hasnulls) + PG_RETURN_BOOL(true); + PG_RETURN_BOOL(false); + } + + /* + * For IS NOT NULL, we can only skip ranges that are known to have + * only nulls. + */ + Assert(key->sk_flags & SK_SEARCHNOTNULL); + PG_RETURN_BOOL(!column->bv_allnulls); + } + + /* If the it is all nulls, it cannot possibly be consistent. */ + if (column->bv_allnulls) + PG_RETURN_BOOL(false); + + attno = key->sk_attno; + query = key->sk_argument; + switch (key->sk_strategy) + { + case RTSameStrategyNumber: + case RTContainsStrategyNumber: + case RTOldContainsStrategyNumber: + case RTEqualStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTContainsStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_DATUM(result); + + /* All of the remaining are optional. */ + + case RTLeftStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverRightStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTOverLeftStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTRightStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTOverlapStrategyNumber: + case RTContainedByStrategyNumber: + case RTOldContainedByStrategyNumber: + case RTContainedByNotEqualStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverlapStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_DATUM(result); + + case RTOverRightStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTLeftStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTRightStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverLeftStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTBelowStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverAboveStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTOverBelowStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTAboveStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTOverAboveStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTBelowStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTAboveStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverBelowStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(!DatumGetBool(result)); + + case RTContainsElemStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTContainsElemStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_DATUM(result); + + case RTAdjacentStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverlapStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + if (DatumGetBool(result)) + PG_RETURN_BOOL(true); + + frmg = inclusion_get_procinfo(bdesc, attno, RTAdjacentStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_DATUM(result); + + case RTLessStrategyNumber: + case RTLessEqualStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverLeftStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(DatumGetBool(result)); + + case RTGreaterStrategyNumber: + case RTGreaterEqualStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTOverRightStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_BOOL(DatumGetBool(result)); + + case RTContainsNotEqualStrategyNumber: + frmg = inclusion_get_procinfo(bdesc, attno, RTContainsNotEqualStrategyNumber); + result = FunctionCall2Coll(frmg, colloid, column->bv_values[0], query); + PG_RETURN_DATUM(result); + + default: + /* Shouldn't happen on a proper opclass. */ + elog(ERROR, "invalid strategy number %d", key->sk_strategy); + PG_RETURN_BOOL(false); /* keep compiler quiet */ + } +} + +/* + * BRIN inclusion union function + * + * Given two BrinValues, update the first of them as a union of the summary + * values contained in both. The second one is untouched. + */ +Datum +brin_inclusion_union(PG_FUNCTION_ARGS) +{ + BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0); + BrinValues *col_a = (BrinValues *) PG_GETARG_POINTER(1); + BrinValues *col_b = (BrinValues *) PG_GETARG_POINTER(2); + Oid colloid = PG_GET_COLLATION(); + AttrNumber attno; + Form_pg_attribute attr; + FmgrInfo *frmg; + Datum result; + + Assert(col_a->bv_attno == col_b->bv_attno); + + /* Adjust "hasnulls". */ + if (!col_a->bv_hasnulls && col_b->bv_hasnulls) + col_a->bv_hasnulls = true; + + /* If there are no values in B, there's nothing left to do. */ + if (col_b->bv_allnulls) + PG_RETURN_VOID(); + + attno = col_a->bv_attno; + attr = bdesc->bd_tupdesc->attrs[attno - 1]; + + /* + * Adjust "allnulls". If B has values but A doesn't, just copy the values + * from B into A, and we're done. (We cannot run the operators in this + * case, because values in A might contain garbage.) + */ + if (col_a->bv_allnulls) + { + col_a->bv_allnulls = false; + col_a->bv_values[0] = datumCopy(col_b->bv_values[0], + attr->attbyval, attr->attlen); + + PG_RETURN_VOID(); + } + + frmg = inclusion_get_procinfo(bdesc, attno, INCLUSION_UNION_NUM); + result = FunctionCall2Coll(frmg, colloid, col_a->bv_values[0], + col_b->bv_values[0]); + + if (!attr->attbyval) + pfree(DatumGetPointer(col_a->bv_values[0])); + + col_a->bv_values[0] = result; + + PG_RETURN_VOID(); +} + +/* + * Procedure for the given strategy number + * + * Returns the procedure corresponding to the given strategy number. + */ +static FmgrInfo * +inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno, uint16 num) +{ + RangeOpaque *opaque; + + opaque = (RangeOpaque *) bdesc->bd_info[attno - 1]->oi_opaque; + + /* + * We cache these in the opaque struct, to avoid repetitive syscache + * lookups. + */ + if (!opaque->inited[num]) + { + fmgr_info_copy(&opaque->operators[num], + index_getprocinfo(bdesc->bd_index, attno, + INCLUSION_MIN_PROCNUM + num), + bdesc->bd_context); + opaque->inited[num] = true; + } + + return &opaque->operators[num]; +} diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c index 009f199..eee8ead 100644 --- a/src/backend/access/brin/brin_minmax.c +++ b/src/backend/access/brin/brin_minmax.c @@ -265,21 +265,21 @@ brin_minmax_union(PG_FUNCTION_ARGS) /* Adjust "hasnulls" */ if (col_b->bv_hasnulls && !col_a->bv_hasnulls) col_a->bv_hasnulls = true; /* * Adjust "allnulls". If B has values but A doesn't, just copy the values * from B into A, and we're done. (We cannot run the operators in this * case, because values in A might contain garbage.) */ - if (!col_b->bv_allnulls && col_a->bv_allnulls) + if (col_a->bv_allnulls) { col_a->bv_allnulls = false; col_a->bv_values[0] = datumCopy(col_b->bv_values[0], attr->attbyval, attr->attlen); col_a->bv_values[1] = datumCopy(col_b->bv_values[1], attr->attbyval, attr->attlen); PG_RETURN_VOID(); } /* Adjust minimum, if B's min is less than A's min */ diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index 54391fd..1aee46d 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -903,20 +903,42 @@ box_intersect(PG_FUNCTION_ARGS) result = (BOX *) palloc(sizeof(BOX)); result->high.x = Min(box1->high.x, box2->high.x); result->low.x = Max(box1->low.x, box2->low.x); result->high.y = Min(box1->high.y, box2->high.y); result->low.y = Max(box1->low.y, box2->low.y); PG_RETURN_BOX_P(result); } +/* + * boxes_bound_box - + * returns the smallest bounding box that + * includes both of the given boxes. + */ +Datum +boxes_bound_box(PG_FUNCTION_ARGS) +{ + BOX *box1 = PG_GETARG_BOX_P(0), + *box2 = PG_GETARG_BOX_P(1), + *container; + + container = (BOX *) palloc(sizeof(BOX)); + + container->high.x = Max(box1->high.x, box2->high.x); + container->low.x = Min(box1->low.x, box2->low.x); + container->high.y = Max(box1->high.y, box2->high.y); + container->low.y = Min(box1->low.y, box2->low.y); + + PG_RETURN_BOX_P(container); +} + /* box_diagonal - * returns a line segment which happens to be the * positive-slope diagonal of "box". */ Datum box_diagonal(PG_FUNCTION_ARGS) { BOX *box = PG_GETARG_BOX_P(0); LSEG *result = (LSEG *) palloc(sizeof(LSEG)); diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index 3a705da..1213759 100644 --- a/src/backend/utils/adt/network.c +++ b/src/backend/utils/adt/network.c @@ -582,20 +582,50 @@ network_overlap(PG_FUNCTION_ARGS) if (ip_family(a1) == ip_family(a2)) { PG_RETURN_BOOL(bitncmp(ip_addr(a1), ip_addr(a2), Min(ip_bits(a1), ip_bits(a2))) == 0); } PG_RETURN_BOOL(false); } +Datum +network_overleft(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_PP(0); + inet *a2 = PG_GETARG_INET_PP(1); + + if (ip_family(a1) == ip_family(a2)) + { + PG_RETURN_BOOL(bitncmp(ip_addr(a1), ip_addr(a2), + Min(ip_bits(a1), ip_bits(a2))) <= 0); + } + + PG_RETURN_BOOL(false); +} + +Datum +network_overright(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_PP(0); + inet *a2 = PG_GETARG_INET_PP(1); + + if (ip_family(a1) == ip_family(a2)) + { + PG_RETURN_BOOL(bitncmp(ip_addr(a1), ip_addr(a2), + Min(ip_bits(a1), ip_bits(a2))) >= 0); + } + + PG_RETURN_BOOL(false); +} + /* * Extract data from a network datatype. */ Datum network_host(PG_FUNCTION_ARGS) { inet *ip = PG_GETARG_INET_PP(0); char *ptr; char tmp[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; @@ -881,20 +911,57 @@ network_hostmask(PG_FUNCTION_ARGS) } ip_family(dst) = ip_family(ip); ip_bits(dst) = ip_maxbits(ip); SET_INET_VARSIZE(dst); PG_RETURN_INET_P(dst); } /* + * Returns the network which contain both of the inputs. Note that return + * value isn't trimmed. It wouldn't be nice to display it directly. Use + * inet_to_cidr() to get the network address. + */ +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 inet values of different sizes"))); + + 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); + + /* 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 * involving network types. */ double convert_network_to_scalar(Datum value, Oid typid) { switch (typid) { case INETOID: diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c index c1c3091..f96ddab 100644 --- a/src/backend/utils/adt/rangetypes.c +++ b/src/backend/utils/adt/rangetypes.c @@ -1000,67 +1000,88 @@ range_minus(PG_FUNCTION_ARGS) upper2.inclusive = !upper2.inclusive; upper2.lower = true; /* it will become the lower bound */ PG_RETURN_RANGE(make_range(typcache, &upper2, &upper1, false)); } elog(ERROR, "unexpected case in range_minus"); PG_RETURN_NULL(); } /* set union */ -Datum -range_union(PG_FUNCTION_ARGS) +static RangeType * +range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, + bool strict) { - RangeType *r1 = PG_GETARG_RANGE(0); - RangeType *r2 = PG_GETARG_RANGE(1); - TypeCacheEntry *typcache; RangeBound lower1, lower2; RangeBound upper1, upper2; bool empty1, empty2; RangeBound *result_lower; RangeBound *result_upper; /* Different types should be prevented by ANYRANGE matching rules */ if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2)) elog(ERROR, "range types do not match"); - typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); - range_deserialize(typcache, r1, &lower1, &upper1, &empty1); range_deserialize(typcache, r2, &lower2, &upper2, &empty2); /* if either is empty, the other is the correct answer */ if (empty1) - PG_RETURN_RANGE(r2); + return r2; if (empty2) - PG_RETURN_RANGE(r1); + return r1; - if (!DatumGetBool(range_overlaps(fcinfo)) && - !DatumGetBool(range_adjacent(fcinfo))) + if (strict && + !DatumGetBool(range_overlaps_internal(typcache, r1, r2)) && + !DatumGetBool(range_adjacent_internal(typcache, r1, r2))) ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("result of range union would not be contiguous"))); if (range_cmp_bounds(typcache, &lower1, &lower2) < 0) result_lower = &lower1; else result_lower = &lower2; if (range_cmp_bounds(typcache, &upper1, &upper2) > 0) result_upper = &upper1; else result_upper = &upper2; - PG_RETURN_RANGE(make_range(typcache, result_lower, result_upper, false)); + return make_range(typcache, result_lower, result_upper, false); +} + +Datum +range_union(PG_FUNCTION_ARGS) +{ + RangeType *r1 = PG_GETARG_RANGE(0); + RangeType *r2 = PG_GETARG_RANGE(1); + TypeCacheEntry *typcache; + + typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); + + PG_RETURN_RANGE(range_union_internal(typcache, r1, r2, true)); +} + +Datum +range_merge(PG_FUNCTION_ARGS) +{ + RangeType *r1 = PG_GETARG_RANGE(0); + RangeType *r2 = PG_GETARG_RANGE(1); + TypeCacheEntry *typcache; + + typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); + + PG_RETURN_RANGE(range_union_internal(typcache, r1, r2, false)); } /* set intersection */ Datum range_intersect(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); TypeCacheEntry *typcache; RangeBound lower1, diff --git a/src/include/access/brin_internal.h b/src/include/access/brin_internal.h index c95978a..0645d1a 100644 --- a/src/include/access/brin_internal.h +++ b/src/include/access/brin_internal.h @@ -64,31 +64,38 @@ typedef struct BrinDesc /* * Globally-known function support numbers for BRIN indexes. Individual * opclasses define their own function support numbers, which must not collide * with the definitions here. */ #define BRIN_PROCNUM_OPCINFO 1 #define BRIN_PROCNUM_ADDVALUE 2 #define BRIN_PROCNUM_CONSISTENT 3 #define BRIN_PROCNUM_UNION 4 /* procedure numbers up to 10 are reserved for BRIN future expansion */ +#define BRIN_RESERVED_PROCNUM 10 #undef BRIN_DEBUG #ifdef BRIN_DEBUG #define BRIN_elog(args) elog args #else #define BRIN_elog(args) ((void) 0) #endif /* brin.c */ extern BrinDesc *brin_build_desc(Relation rel); extern void brin_free_desc(BrinDesc *bdesc); extern Datum brin_summarize_new_values(PG_FUNCTION_ARGS); /* brin_minmax.c */ extern Datum brin_minmax_opcinfo(PG_FUNCTION_ARGS); extern Datum brin_minmax_add_value(PG_FUNCTION_ARGS); extern Datum brin_minmax_consistent(PG_FUNCTION_ARGS); extern Datum brin_minmax_union(PG_FUNCTION_ARGS); +/* brin_inclusion.c */ +extern Datum brin_inclusion_opcinfo(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_add_value(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_consistent(PG_FUNCTION_ARGS); +extern Datum brin_inclusion_union(PG_FUNCTION_ARGS); + #endif /* BRIN_INTERNAL_H */ diff --git a/src/include/access/gist.h b/src/include/access/gist.h index 39394df..8b7d5b3 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.h @@ -29,40 +29,20 @@ #define GIST_UNION_PROC 2 #define GIST_COMPRESS_PROC 3 #define GIST_DECOMPRESS_PROC 4 #define GIST_PENALTY_PROC 5 #define GIST_PICKSPLIT_PROC 6 #define GIST_EQUAL_PROC 7 #define GIST_DISTANCE_PROC 8 #define GISTNProcs 8 /* - * strategy numbers for GiST opclasses that want to implement the old - * RTREE behavior. - */ -#define RTLeftStrategyNumber 1 -#define RTOverLeftStrategyNumber 2 -#define RTOverlapStrategyNumber 3 -#define RTOverRightStrategyNumber 4 -#define RTRightStrategyNumber 5 -#define RTSameStrategyNumber 6 -#define RTContainsStrategyNumber 7 /* for @> */ -#define RTContainedByStrategyNumber 8 /* for <@ */ -#define RTOverBelowStrategyNumber 9 -#define RTBelowStrategyNumber 10 -#define RTAboveStrategyNumber 11 -#define RTOverAboveStrategyNumber 12 -#define RTOldContainsStrategyNumber 13 /* for old spelling of @> */ -#define RTOldContainedByStrategyNumber 14 /* for old spelling of <@ */ -#define RTKNNSearchStrategyNumber 15 - -/* * Page opaque data in a GiST index page. */ #define F_LEAF (1 << 0) /* leaf page */ #define F_DELETED (1 << 1) /* the page has been deleted */ #define F_TUPLES_DELETED (1 << 2) /* some tuples on the page are dead */ #define F_FOLLOW_RIGHT (1 << 3) /* page to the right has no downlink */ typedef XLogRecPtr GistNSN; /* diff --git a/src/include/access/skey.h b/src/include/access/skey.h index bb96808..63b8d29 100644 --- a/src/include/access/skey.h +++ b/src/include/access/skey.h @@ -34,20 +34,54 @@ typedef uint16 StrategyNumber; #define BTLessStrategyNumber 1 #define BTLessEqualStrategyNumber 2 #define BTEqualStrategyNumber 3 #define BTGreaterEqualStrategyNumber 4 #define BTGreaterStrategyNumber 5 #define BTMaxStrategyNumber 5 /* + * Strategy numbers for opclasses that want to implement the old RTREE behavior. + * Operator strategy numbers used in the GiST, SP-GiST, GIN, BRIN opclasses. + * New numbers are chosen to match up operator names with existing usages. + */ +#define RTLeftStrategyNumber 1 /* for << */ +#define RTOverLeftStrategyNumber 2 /* for &< */ +#define RTOverlapStrategyNumber 3 /* for && */ +#define RTOverRightStrategyNumber 4 /* for &> */ +#define RTRightStrategyNumber 5 /* for >> */ +#define RTSameStrategyNumber 6 /* for ~= */ +#define RTContainsStrategyNumber 7 /* for @> */ +#define RTContainedByStrategyNumber 8 /* for <@ */ +#define RTOverBelowStrategyNumber 9 /* for &<| */ +#define RTBelowStrategyNumber 10 /* for <<| */ +#define RTAboveStrategyNumber 11 /* for |>> */ +#define RTOverAboveStrategyNumber 12 /* for |&> */ +#define RTOldContainsStrategyNumber 13 /* for old spellings of @> */ +#define RTOldContainedByStrategyNumber 14 /* for old spellings of <@ */ +#define RTKNNSearchStrategyNumber 15 +#define RTContainsElemStrategyNumber 16 /* for range types @> elem */ +#define RTAdjacentStrategyNumber 17 /* for -|- */ +#define RTEqualStrategyNumber 18 /* for = */ +#define RTNotEqualStrategyNumber 19 /* for != */ +#define RTLessStrategyNumber 20 /* for < */ +#define RTLessEqualStrategyNumber 21 /* for <= */ +#define RTGreaterStrategyNumber 22 /* for > */ +#define RTGreaterEqualStrategyNumber 23 /* for >= */ +#define RTContainsNotEqualStrategyNumber 24 /* for inet >> */ +#define RTContainedByNotEqualStrategyNumber 26 /* for inet << */ + +#define RTMaxStrategyNumber 26 + + +/* * A ScanKey represents the application of a comparison operator between * a table or index column and a constant. When it's part of an array of * ScanKeys, the comparison conditions are implicitly ANDed. The index * column is the left argument of the operator, if it's a binary operator. * (The data structure can support unary indexable operators too; in that * case sk_argument would go unused. This is not currently implemented.) * * For an index scan, sk_strategy and sk_subtype must be set correctly for * the operator. When using a ScanKey in a heap scan, these fields are not * used and may be set to InvalidStrategy/InvalidOid. diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h index 67b57cd..eb88201 100644 --- a/src/include/catalog/pg_am.h +++ b/src/include/catalog/pg_am.h @@ -125,14 +125,14 @@ DESCR("hash index access method"); #define HASH_AM_OID 405 DATA(insert OID = 783 ( gist 0 8 f t f f t t f t t t f 0 gistinsert gistbeginscan gistgettuple gistgetbitmap gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbuildempty gistbulkdelete gistvacuumcleanup - gistcostestimate gistoptions )); DESCR("GiST index access method"); #define GIST_AM_OID 783 DATA(insert OID = 2742 ( gin 0 6 f f f f t t f f t f f 0 gininsert ginbeginscan - gingetbitmap ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbuildempty ginbulkdelete ginvacuumcleanup - gincostestimate ginoptions )); DESCR("GIN index access method"); #define GIN_AM_OID 2742 DATA(insert OID = 4000 ( spgist 0 5 f f f f f t f t f f f 0 spginsert spgbeginscan spggettuple spggetbitmap spgrescan spgendscan spgmarkpos spgrestrpos spgbuild spgbuildempty spgbulkdelete spgvacuumcleanup spgcanreturn spgcostestimate spgoptions )); DESCR("SP-GiST index access method"); #define SPGIST_AM_OID 4000 -DATA(insert OID = 3580 ( brin 5 14 f f f f t t f t t f f 0 brininsert brinbeginscan - bringetbitmap brinrescan brinendscan brinmarkpos brinrestrpos brinbuild brinbuildempty brinbulkdelete brinvacuumcleanup - brincostestimate brinoptions )); +DATA(insert OID = 3580 ( brin 0 37 f f f f t t f t t f f 0 brininsert brinbeginscan - bringetbitmap brinrescan brinendscan brinmarkpos brinrestrpos brinbuild brinbuildempty brinbulkdelete brinvacuumcleanup - brincostestimate brinoptions )); #define BRIN_AM_OID 3580 #endif /* PG_AM_H */ diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index 7165f54..9468328 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -968,20 +968,31 @@ DATA(insert ( 4074 829 829 1 s 1222 3580 0 )); DATA(insert ( 4074 829 829 2 s 1223 3580 0 )); DATA(insert ( 4074 829 829 3 s 1220 3580 0 )); DATA(insert ( 4074 829 829 4 s 1225 3580 0 )); DATA(insert ( 4074 829 829 5 s 1224 3580 0 )); /* minmax inet */ DATA(insert ( 4075 869 869 1 s 1203 3580 0 )); DATA(insert ( 4075 869 869 2 s 1204 3580 0 )); DATA(insert ( 4075 869 869 3 s 1201 3580 0 )); DATA(insert ( 4075 869 869 4 s 1206 3580 0 )); DATA(insert ( 4075 869 869 5 s 1205 3580 0 )); +/* inclusion inet */ +DATA(insert ( 4060 869 869 3 s 3552 3580 0 )); +DATA(insert ( 4060 869 869 7 s 934 3580 0 )); +DATA(insert ( 4060 869 869 8 s 932 3580 0 )); +DATA(insert ( 4060 869 869 18 s 1201 3580 0 )); +DATA(insert ( 4060 869 869 20 s 1203 3580 0 )); +DATA(insert ( 4060 869 869 21 s 1204 3580 0 )); +DATA(insert ( 4060 869 869 22 s 1205 3580 0 )); +DATA(insert ( 4060 869 869 23 s 1206 3580 0 )); +DATA(insert ( 4060 869 869 24 s 933 3580 0 )); +DATA(insert ( 4060 869 869 26 s 931 3580 0 )); /* minmax character */ DATA(insert ( 4076 1042 1042 1 s 1058 3580 0 )); DATA(insert ( 4076 1042 1042 2 s 1059 3580 0 )); DATA(insert ( 4076 1042 1042 3 s 1054 3580 0 )); DATA(insert ( 4076 1042 1042 4 s 1061 3580 0 )); DATA(insert ( 4076 1042 1042 5 s 1060 3580 0 )); /* minmax time without time zone */ DATA(insert ( 4077 1083 1083 1 s 1110 3580 0 )); DATA(insert ( 4077 1083 1083 2 s 1111 3580 0 )); DATA(insert ( 4077 1083 1083 3 s 1108 3580 0 )); @@ -1063,18 +1074,48 @@ DATA(insert ( 4055 1700 1700 1 s 1754 3580 0 )); DATA(insert ( 4055 1700 1700 2 s 1755 3580 0 )); DATA(insert ( 4055 1700 1700 3 s 1752 3580 0 )); DATA(insert ( 4055 1700 1700 4 s 1757 3580 0 )); DATA(insert ( 4055 1700 1700 5 s 1756 3580 0 )); /* minmax uuid */ DATA(insert ( 4081 2950 2950 1 s 2974 3580 0 )); DATA(insert ( 4081 2950 2950 2 s 2976 3580 0 )); DATA(insert ( 4081 2950 2950 3 s 2972 3580 0 )); DATA(insert ( 4081 2950 2950 4 s 2977 3580 0 )); DATA(insert ( 4081 2950 2950 5 s 2975 3580 0 )); +/* inclusion range types */ +DATA(insert ( 4063 3831 3831 1 s 3893 3580 0 )); +DATA(insert ( 4063 3831 3831 2 s 3895 3580 0 )); +DATA(insert ( 4063 3831 3831 3 s 3888 3580 0 )); +DATA(insert ( 4063 3831 3831 4 s 3896 3580 0 )); +DATA(insert ( 4063 3831 3831 5 s 3894 3580 0 )); +DATA(insert ( 4063 3831 3831 7 s 3890 3580 0 )); +DATA(insert ( 4063 3831 3831 8 s 3892 3580 0 )); +DATA(insert ( 4063 3831 2283 16 s 3889 3580 0 )); +DATA(insert ( 4063 3831 3831 17 s 3897 3580 0 )); +DATA(insert ( 4063 3831 3831 18 s 3882 3580 0 )); +DATA(insert ( 4063 3831 3831 20 s 3884 3580 0 )); +DATA(insert ( 4063 3831 3831 21 s 3885 3580 0 )); +DATA(insert ( 4063 3831 3831 22 s 3887 3580 0 )); +DATA(insert ( 4063 3831 3831 23 s 3886 3580 0 )); /* minmax pg_lsn */ DATA(insert ( 4082 3220 3220 1 s 3224 3580 0 )); DATA(insert ( 4082 3220 3220 2 s 3226 3580 0 )); DATA(insert ( 4082 3220 3220 3 s 3222 3580 0 )); DATA(insert ( 4082 3220 3220 4 s 3227 3580 0 )); DATA(insert ( 4082 3220 3220 5 s 3225 3580 0 )); +/* inclusion box */ +DATA(insert ( 4066 603 603 1 s 493 3580 0 )); +DATA(insert ( 4066 603 603 2 s 494 3580 0 )); +DATA(insert ( 4066 603 603 3 s 500 3580 0 )); +DATA(insert ( 4066 603 603 4 s 495 3580 0 )); +DATA(insert ( 4066 603 603 5 s 496 3580 0 )); +DATA(insert ( 4066 603 603 6 s 499 3580 0 )); +DATA(insert ( 4066 603 603 7 s 498 3580 0 )); +DATA(insert ( 4066 603 603 8 s 497 3580 0 )); +DATA(insert ( 4066 603 603 9 s 2571 3580 0 )); +DATA(insert ( 4066 603 603 10 s 2570 3580 0 )); +DATA(insert ( 4066 603 603 11 s 2573 3580 0 )); +DATA(insert ( 4066 603 603 12 s 2572 3580 0 )); +DATA(insert ( 4066 603 603 13 s 2863 3580 0 )); +DATA(insert ( 4066 603 603 14 s 2862 3580 0 )); #endif /* PG_AMOP_H */ diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index 309aee6..c3c441f 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -629,20 +629,31 @@ DATA(insert ( 4074 829 829 13 834 )); DATA(insert ( 4074 829 829 14 833 )); /* minmax inet */ DATA(insert ( 4075 869 869 1 3383 )); DATA(insert ( 4075 869 869 2 3384 )); DATA(insert ( 4075 869 869 3 3385 )); DATA(insert ( 4075 869 869 4 3386 )); DATA(insert ( 4075 869 869 11 921 )); DATA(insert ( 4075 869 869 12 922 )); DATA(insert ( 4075 869 869 13 924 )); DATA(insert ( 4075 869 869 14 923 )); +/* inclusion inet */ +DATA(insert ( 4060 869 869 1 3387 )); +DATA(insert ( 4060 869 869 2 3388 )); +DATA(insert ( 4060 869 869 3 3389 )); +DATA(insert ( 4060 869 869 4 3390 )); +DATA(insert ( 4060 869 869 11 4061 )); +DATA(insert ( 4060 869 869 13 3573 )); +DATA(insert ( 4060 869 869 14 3551 )); +DATA(insert ( 4060 869 869 15 3574 )); +DATA(insert ( 4060 869 869 18 930)); +DATA(insert ( 4060 869 869 35 929 )); /* minmax character */ DATA(insert ( 4076 1042 1042 1 3383 )); DATA(insert ( 4076 1042 1042 2 3384 )); DATA(insert ( 4076 1042 1042 3 3385 )); DATA(insert ( 4076 1042 1042 4 3386 )); DATA(insert ( 4076 1042 1042 11 1049 )); DATA(insert ( 4076 1042 1042 12 1050 )); DATA(insert ( 4076 1042 1042 13 1052 )); DATA(insert ( 4076 1042 1042 14 1051 )); /* minmax time without time zone */ @@ -777,21 +788,51 @@ DATA(insert ( 4055 1700 1700 13 1721 )); DATA(insert ( 4055 1700 1700 14 1720 )); /* minmax uuid */ DATA(insert ( 4081 2950 2950 1 3383 )); DATA(insert ( 4081 2950 2950 2 3384 )); DATA(insert ( 4081 2950 2950 3 3385 )); DATA(insert ( 4081 2950 2950 4 3386 )); DATA(insert ( 4081 2950 2950 11 2954 )); DATA(insert ( 4081 2950 2950 12 2955 )); DATA(insert ( 4081 2950 2950 13 2957 )); DATA(insert ( 4081 2950 2950 14 2958 )); +/* inclusion range types */ +DATA(insert ( 4063 3831 3831 1 3387 )); +DATA(insert ( 4063 3831 3831 2 3388 )); +DATA(insert ( 4063 3831 3831 3 3389 )); +DATA(insert ( 4063 3831 3831 4 3390 )); +DATA(insert ( 4063 3831 3831 11 4057 )); +DATA(insert ( 4063 3831 3831 12 3863 )); +DATA(insert ( 4063 3831 3831 13 3865 )); +DATA(insert ( 4063 3831 3831 14 3857 )); +DATA(insert ( 4063 3831 3831 15 3866 )); +DATA(insert ( 4063 3831 3831 16 3864 )); +DATA(insert ( 4063 3831 3831 18 3859 )); +DATA(insert ( 4063 3831 3831 27 3858 )); +DATA(insert ( 4063 3831 3831 28 3862 )); /* minmax pg_lsn */ DATA(insert ( 4082 3220 3220 1 3383 )); DATA(insert ( 4082 3220 3220 2 3384 )); DATA(insert ( 4082 3220 3220 3 3385 )); DATA(insert ( 4082 3220 3220 4 3386 )); DATA(insert ( 4082 3220 3220 11 3231 )); DATA(insert ( 4082 3220 3220 12 3232 )); DATA(insert ( 4082 3220 3220 13 3234 )); DATA(insert ( 4082 3220 3220 14 3235 )); +/* inclusion box */ +DATA(insert ( 4066 603 603 1 3387 )); +DATA(insert ( 4066 603 603 2 3388 )); +DATA(insert ( 4066 603 603 3 3389 )); +DATA(insert ( 4066 603 603 4 3390 )); +DATA(insert ( 4066 603 603 11 4067 )); +DATA(insert ( 4066 603 603 12 188 )); +DATA(insert ( 4066 603 603 13 189 )); +DATA(insert ( 4066 603 603 14 125 )); +DATA(insert ( 4066 603 603 15 190 )); +DATA(insert ( 4066 603 603 16 191 )); +DATA(insert ( 4066 603 603 18 187 )); +DATA(insert ( 4066 603 603 20 2563 )); +DATA(insert ( 4066 603 603 21 2562 )); +DATA(insert ( 4066 603 603 22 2565 )); +DATA(insert ( 4066 603 603 23 2564 )); #endif /* PG_AMPROC_H */ diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index 1032d39..3d8e903 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -245,27 +245,30 @@ DATA(insert ( 3580 int8_minmax_ops PGNSP PGUID 4054 20 t 0 )); DATA(insert ( 3580 int2_minmax_ops PGNSP PGUID 4054 21 t 0 )); DATA(insert ( 3580 int4_minmax_ops PGNSP PGUID 4054 23 t 0 )); DATA(insert ( 3580 text_minmax_ops PGNSP PGUID 4056 25 t 0 )); DATA(insert ( 3580 oid_minmax_ops PGNSP PGUID 4068 26 t 0 )); DATA(insert ( 3580 tid_minmax_ops PGNSP PGUID 4069 27 t 0 )); DATA(insert ( 3580 float4_minmax_ops PGNSP PGUID 4070 700 t 0 )); DATA(insert ( 3580 float8_minmax_ops PGNSP PGUID 4070 701 t 0 )); DATA(insert ( 3580 abstime_minmax_ops PGNSP PGUID 4072 702 t 0 )); DATA(insert ( 3580 reltime_minmax_ops PGNSP PGUID 4073 703 t 0 )); DATA(insert ( 3580 macaddr_minmax_ops PGNSP PGUID 4074 829 t 0 )); -DATA(insert ( 3580 inet_minmax_ops PGNSP PGUID 4075 869 t 0 )); +DATA(insert ( 3580 inet_minmax_ops PGNSP PGUID 4075 869 f 0 )); +DATA(insert ( 3580 inet_inclusion_ops PGNSP PGUID 4060 869 t 0 )); DATA(insert ( 3580 bpchar_minmax_ops PGNSP PGUID 4076 1042 t 0 )); DATA(insert ( 3580 time_minmax_ops PGNSP PGUID 4077 1083 t 0 )); DATA(insert ( 3580 date_minmax_ops PGNSP PGUID 4059 1082 t 0 )); DATA(insert ( 3580 timestamp_minmax_ops PGNSP PGUID 4059 1114 t 0 )); DATA(insert ( 3580 timestamptz_minmax_ops PGNSP PGUID 4059 1184 t 0 )); DATA(insert ( 3580 interval_minmax_ops PGNSP PGUID 4078 1186 t 0 )); DATA(insert ( 3580 timetz_minmax_ops PGNSP PGUID 4058 1266 t 0 )); DATA(insert ( 3580 bit_minmax_ops PGNSP PGUID 4079 1560 t 0 )); DATA(insert ( 3580 varbit_minmax_ops PGNSP PGUID 4080 1562 t 0 )); DATA(insert ( 3580 numeric_minmax_ops PGNSP PGUID 4055 1700 t 0 )); /* no brin opclass for record, anyarray */ DATA(insert ( 3580 uuid_minmax_ops PGNSP PGUID 4081 2950 t 0 )); +DATA(insert ( 3580 range_inclusion_ops PGNSP PGUID 4063 3831 t 0 )); DATA(insert ( 3580 pg_lsn_minmax_ops PGNSP PGUID 4082 3220 t 0 )); -/* no brin opclass for enum, tsvector, tsquery, jsonb, range */ +DATA(insert ( 3580 box_inclusion_ops PGNSP PGUID 4066 603 t 0 )); +/* no brin opclass for enum, tsvector, tsquery, jsonb */ #endif /* PG_OPCLASS_H */ diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index f19a690..3567849 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -165,19 +165,22 @@ DATA(insert OID = 4059 ( 3580 datetime_minmax_ops PGNSP PGUID )); DATA(insert OID = 4062 ( 3580 char_minmax_ops PGNSP PGUID )); DATA(insert OID = 4064 ( 3580 bytea_minmax_ops PGNSP PGUID )); DATA(insert OID = 4065 ( 3580 name_minmax_ops PGNSP PGUID )); DATA(insert OID = 4068 ( 3580 oid_minmax_ops PGNSP PGUID )); DATA(insert OID = 4069 ( 3580 tid_minmax_ops PGNSP PGUID )); DATA(insert OID = 4070 ( 3580 float_minmax_ops PGNSP PGUID )); DATA(insert OID = 4072 ( 3580 abstime_minmax_ops PGNSP PGUID )); DATA(insert OID = 4073 ( 3580 reltime_minmax_ops PGNSP PGUID )); DATA(insert OID = 4074 ( 3580 macaddr_minmax_ops PGNSP PGUID )); DATA(insert OID = 4075 ( 3580 network_minmax_ops PGNSP PGUID )); +DATA(insert OID = 4060 ( 3580 network_inclusion_ops PGNSP PGUID )); DATA(insert OID = 4076 ( 3580 bpchar_minmax_ops PGNSP PGUID )); DATA(insert OID = 4077 ( 3580 time_minmax_ops PGNSP PGUID )); DATA(insert OID = 4078 ( 3580 interval_minmax_ops PGNSP PGUID )); DATA(insert OID = 4079 ( 3580 bit_minmax_ops PGNSP PGUID )); DATA(insert OID = 4080 ( 3580 varbit_minmax_ops PGNSP PGUID )); DATA(insert OID = 4081 ( 3580 uuid_minmax_ops PGNSP PGUID )); +DATA(insert OID = 4063 ( 3580 range_inclusion_ops PGNSP PGUID )); DATA(insert OID = 4082 ( 3580 pg_lsn_minmax_ops PGNSP PGUID )); +DATA(insert OID = 4066 ( 3580 box_inclusion_ops PGNSP PGUID )); #endif /* PG_OPFAMILY_H */ diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index e5912ea..613ff11 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -1122,20 +1122,22 @@ DATA(insert OID = 973 ( path_inter PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 DATA(insert OID = 975 ( area PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "603" _null_ _null_ _null_ _null_ box_area _null_ _null_ _null_ )); DESCR("box area"); DATA(insert OID = 976 ( width PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "603" _null_ _null_ _null_ _null_ box_width _null_ _null_ _null_ )); DESCR("box width"); DATA(insert OID = 977 ( height PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "603" _null_ _null_ _null_ _null_ box_height _null_ _null_ _null_ )); DESCR("box height"); DATA(insert OID = 978 ( box_distance PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 701 "603 603" _null_ _null_ _null_ _null_ box_distance _null_ _null_ _null_ )); DATA(insert OID = 979 ( area PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "602" _null_ _null_ _null_ _null_ path_area _null_ _null_ _null_ )); DESCR("area of a closed path"); DATA(insert OID = 980 ( box_intersect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 603 "603 603" _null_ _null_ _null_ _null_ box_intersect _null_ _null_ _null_ )); +DATA(insert OID = 4067 ( boxes_bound_box PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 603 "603 603" _null_ _null_ _null_ _null_ boxes_bound_box _null_ _null_ _null_ )); +DESCR("bounding box of two boxes"); DATA(insert OID = 981 ( diagonal PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 601 "603" _null_ _null_ _null_ _null_ box_diagonal _null_ _null_ _null_ )); DESCR("box diagonal"); DATA(insert OID = 982 ( path_n_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "602 602" _null_ _null_ _null_ _null_ path_n_lt _null_ _null_ _null_ )); DATA(insert OID = 983 ( path_n_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "602 602" _null_ _null_ _null_ _null_ path_n_gt _null_ _null_ _null_ )); DATA(insert OID = 984 ( path_n_eq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "602 602" _null_ _null_ _null_ _null_ path_n_eq _null_ _null_ _null_ )); DATA(insert OID = 985 ( path_n_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "602 602" _null_ _null_ _null_ _null_ path_n_le _null_ _null_ _null_ )); DATA(insert OID = 986 ( path_n_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "602 602" _null_ _null_ _null_ _null_ path_n_ge _null_ _null_ _null_ )); DATA(insert OID = 987 ( path_length PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 701 "602" _null_ _null_ _null_ _null_ path_length _null_ _null_ _null_ )); DATA(insert OID = 988 ( point_ne PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "600 600" _null_ _null_ _null_ _null_ point_ne _null_ _null_ _null_ )); DATA(insert OID = 989 ( point_vert PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "600 600" _null_ _null_ _null_ _null_ point_vert _null_ _null_ _null_ )); @@ -2165,20 +2167,24 @@ DATA(insert OID = 3562 ( network_larger PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 DESCR("larger of two"); DATA(insert OID = 3563 ( network_smaller PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_ network_smaller _null_ _null_ _null_ )); DESCR("smaller of two"); DATA(insert OID = 926 ( network_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "869 869" _null_ _null_ _null_ _null_ network_cmp _null_ _null_ _null_ )); DESCR("less-equal-greater"); DATA(insert OID = 927 ( network_sub PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_sub _null_ _null_ _null_ )); DATA(insert OID = 928 ( network_subeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_subeq _null_ _null_ _null_ )); DATA(insert OID = 929 ( network_sup PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_sup _null_ _null_ _null_ )); DATA(insert OID = 930 ( network_supeq PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_supeq _null_ _null_ _null_ )); DATA(insert OID = 3551 ( network_overlap PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_overlap _null_ _null_ _null_ )); +DATA(insert OID = 3573 ( network_overleft PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_overleft _null_ _null_ _null_ )); +DESCR("implementation of &< operator"); +DATA(insert OID = 3574 ( network_overright PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "869 869" _null_ _null_ _null_ _null_ network_overright _null_ _null_ _null_ )); +DESCR("implementation of &> operator"); /* inet/cidr functions */ DATA(insert OID = 598 ( abbrev PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "869" _null_ _null_ _null_ _null_ inet_abbrev _null_ _null_ _null_ )); DESCR("abbreviated display of inet value"); DATA(insert OID = 599 ( abbrev PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "650" _null_ _null_ _null_ _null_ cidr_abbrev _null_ _null_ _null_ )); DESCR("abbreviated display of cidr value"); DATA(insert OID = 605 ( set_masklen PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 23" _null_ _null_ _null_ _null_ inet_set_masklen _null_ _null_ _null_ )); DESCR("change netmask of inet"); DATA(insert OID = 635 ( set_masklen PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 650 "650 23" _null_ _null_ _null_ _null_ cidr_set_masklen _null_ _null_ _null_ )); DESCR("change netmask of cidr"); @@ -2210,20 +2216,22 @@ DESCR("inet address of the server"); DATA(insert OID = 2199 ( inet_server_port PGNSP PGUID 12 1 0 0 0 f f f f f f s 0 0 23 "" _null_ _null_ _null_ _null_ inet_server_port _null_ _null_ _null_ )); DESCR("server's port number for this connection"); DATA(insert OID = 2627 ( inetnot PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 869 "869" _null_ _null_ _null_ _null_ inetnot _null_ _null_ _null_ )); DATA(insert OID = 2628 ( inetand PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_ inetand _null_ _null_ _null_ )); DATA(insert OID = 2629 ( inetor PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_ inetor _null_ _null_ _null_ )); DATA(insert OID = 2630 ( inetpl PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 20" _null_ _null_ _null_ _null_ inetpl _null_ _null_ _null_ )); DATA(insert OID = 2631 ( int8pl_inet PGNSP PGUID 14 1 0 0 0 f f f f t f i 2 0 869 "20 869" _null_ _null_ _null_ _null_ "select $2 + $1" _null_ _null_ _null_ )); DATA(insert OID = 2632 ( inetmi_int8 PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 20" _null_ _null_ _null_ _null_ inetmi_int8 _null_ _null_ _null_ )); DATA(insert OID = 2633 ( inetmi PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 20 "869 869" _null_ _null_ _null_ _null_ inetmi _null_ _null_ _null_ )); +DATA(insert OID = 4061 ( inet_merge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 869 "869 869" _null_ _null_ _null_ _null_ inet_merge _null_ _null_ _null_ )); +DESCR("union of two networks"); /* GiST support for inet and cidr */ DATA(insert OID = 3553 ( inet_gist_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 5 0 16 "2281 869 23 26 2281" _null_ _null_ _null_ _null_ inet_gist_consistent _null_ _null_ _null_ )); DESCR("GiST support"); DATA(insert OID = 3554 ( inet_gist_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 2281 "2281 2281" _null_ _null_ _null_ _null_ inet_gist_union _null_ _null_ _null_ )); DESCR("GiST support"); DATA(insert OID = 3555 ( inet_gist_compress PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ inet_gist_compress _null_ _null_ _null_ )); DESCR("GiST support"); DATA(insert OID = 3556 ( inet_gist_decompress PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ inet_gist_decompress _null_ _null_ _null_ )); DESCR("GiST support"); @@ -4126,20 +4134,30 @@ DATA(insert OID = 2749 ( arraycontained PGNSP PGUID 12 1 0 0 0 f f f f t f i /* BRIN minmax */ DATA(insert OID = 3383 ( brin_minmax_opcinfo PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ brin_minmax_opcinfo _null_ _null_ _null_ )); DESCR("BRIN minmax support"); DATA(insert OID = 3384 ( brin_minmax_add_value PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 16 "2281 2281 2281 2281" _null_ _null_ _null_ _null_ brin_minmax_add_value _null_ _null_ _null_ )); DESCR("BRIN minmax support"); DATA(insert OID = 3385 ( brin_minmax_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ brin_minmax_consistent _null_ _null_ _null_ )); DESCR("BRIN minmax support"); DATA(insert OID = 3386 ( brin_minmax_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ brin_minmax_union _null_ _null_ _null_ )); DESCR("BRIN minmax support"); +/* BRIN inclusion */ +DATA(insert OID = 3387 ( brin_inclusion_opcinfo PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2281 "2281" _null_ _null_ _null_ _null_ brin_inclusion_opcinfo _null_ _null_ _null_ )); +DESCR("BRIN inclusion support"); +DATA(insert OID = 3388 ( brin_inclusion_add_value PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 16 "2281 2281 2281 2281" _null_ _null_ _null_ _null_ brin_inclusion_add_value _null_ _null_ _null_ )); +DESCR("BRIN inclusion support"); +DATA(insert OID = 3389 ( brin_inclusion_consistent PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ brin_inclusion_consistent _null_ _null_ _null_ )); +DESCR("BRIN inclusion support"); +DATA(insert OID = 3390 ( brin_inclusion_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 3 0 16 "2281 2281 2281" _null_ _null_ _null_ _null_ brin_inclusion_union _null_ _null_ _null_ )); +DESCR("BRIN inclusion support"); + /* userlock replacements */ DATA(insert OID = 2880 ( pg_advisory_lock PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ pg_advisory_lock_int8 _null_ _null_ _null_ )); DESCR("obtain exclusive advisory lock"); DATA(insert OID = 3089 ( pg_advisory_xact_lock PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ pg_advisory_xact_lock_int8 _null_ _null_ _null_ )); DESCR("obtain exclusive advisory lock"); DATA(insert OID = 2881 ( pg_advisory_lock_shared PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ pg_advisory_lock_shared_int8 _null_ _null_ _null_ )); DESCR("obtain shared advisory lock"); DATA(insert OID = 3090 ( pg_advisory_xact_lock_shared PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 2278 "20" _null_ _null_ _null_ _null_ pg_advisory_xact_lock_shared_int8 _null_ _null_ _null_ )); DESCR("obtain shared advisory lock"); DATA(insert OID = 2882 ( pg_try_advisory_lock PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 16 "20" _null_ _null_ _null_ _null_ pg_try_advisory_lock_int8 _null_ _null_ _null_ )); @@ -4884,20 +4902,22 @@ DESCR("implementation of -|- operator"); DATA(insert OID = 3863 ( range_before PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_before _null_ _null_ _null_ )); DESCR("implementation of << operator"); DATA(insert OID = 3864 ( range_after PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_after _null_ _null_ _null_ )); DESCR("implementation of >> operator"); DATA(insert OID = 3865 ( range_overleft PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_overleft _null_ _null_ _null_ )); DESCR("implementation of &< operator"); DATA(insert OID = 3866 ( range_overright PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_overright _null_ _null_ _null_ )); DESCR("implementation of &> operator"); DATA(insert OID = 3867 ( range_union PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3831 "3831 3831" _null_ _null_ _null_ _null_ range_union _null_ _null_ _null_ )); DESCR("implementation of + operator"); +DATA(insert OID = 4057 ( range_merge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3831 "3831 3831" _null_ _null_ _null_ _null_ range_merge _null_ _null_ _null_ )); +DESCR("merge two ranges"); DATA(insert OID = 3868 ( range_intersect PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3831 "3831 3831" _null_ _null_ _null_ _null_ range_intersect _null_ _null_ _null_ )); DESCR("implementation of * operator"); DATA(insert OID = 3869 ( range_minus PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 3831 "3831 3831" _null_ _null_ _null_ _null_ range_minus _null_ _null_ _null_ )); DESCR("implementation of - operator"); DATA(insert OID = 3870 ( range_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 23 "3831 3831" _null_ _null_ _null_ _null_ range_cmp _null_ _null_ _null_ )); DESCR("less-equal-greater"); DATA(insert OID = 3871 ( range_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_lt _null_ _null_ _null_ )); DATA(insert OID = 3872 ( range_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_le _null_ _null_ _null_ )); DATA(insert OID = 3873 ( range_ge PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_ge _null_ _null_ _null_ )); DATA(insert OID = 3874 ( range_gt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "3831 3831" _null_ _null_ _null_ _null_ range_gt _null_ _null_ _null_ )); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 2da3002..0c71af0 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -904,20 +904,22 @@ extern Datum network_ge(PG_FUNCTION_ARGS); extern Datum network_gt(PG_FUNCTION_ARGS); extern Datum network_ne(PG_FUNCTION_ARGS); extern Datum network_smaller(PG_FUNCTION_ARGS); extern Datum network_larger(PG_FUNCTION_ARGS); extern Datum hashinet(PG_FUNCTION_ARGS); extern Datum network_sub(PG_FUNCTION_ARGS); extern Datum network_subeq(PG_FUNCTION_ARGS); extern Datum network_sup(PG_FUNCTION_ARGS); extern Datum network_supeq(PG_FUNCTION_ARGS); extern Datum network_overlap(PG_FUNCTION_ARGS); +extern Datum network_overleft(PG_FUNCTION_ARGS); +extern Datum network_overright(PG_FUNCTION_ARGS); extern Datum network_network(PG_FUNCTION_ARGS); extern Datum network_netmask(PG_FUNCTION_ARGS); extern Datum network_hostmask(PG_FUNCTION_ARGS); extern Datum network_masklen(PG_FUNCTION_ARGS); extern Datum network_family(PG_FUNCTION_ARGS); extern Datum network_broadcast(PG_FUNCTION_ARGS); extern Datum network_host(PG_FUNCTION_ARGS); extern Datum network_show(PG_FUNCTION_ARGS); extern Datum inet_abbrev(PG_FUNCTION_ARGS); extern Datum cidr_abbrev(PG_FUNCTION_ARGS); @@ -931,20 +933,21 @@ extern Datum inet_client_addr(PG_FUNCTION_ARGS); extern Datum inet_client_port(PG_FUNCTION_ARGS); extern Datum inet_server_addr(PG_FUNCTION_ARGS); extern Datum inet_server_port(PG_FUNCTION_ARGS); extern Datum inetnot(PG_FUNCTION_ARGS); extern Datum inetand(PG_FUNCTION_ARGS); extern Datum inetor(PG_FUNCTION_ARGS); extern Datum inetpl(PG_FUNCTION_ARGS); extern Datum inetmi_int8(PG_FUNCTION_ARGS); extern Datum inetmi(PG_FUNCTION_ARGS); extern void clean_ipv6_addr(int addr_family, char *addr); +extern Datum inet_merge(PG_FUNCTION_ARGS); /* mac.c */ extern Datum macaddr_in(PG_FUNCTION_ARGS); extern Datum macaddr_out(PG_FUNCTION_ARGS); extern Datum macaddr_recv(PG_FUNCTION_ARGS); extern Datum macaddr_send(PG_FUNCTION_ARGS); extern Datum macaddr_cmp(PG_FUNCTION_ARGS); extern Datum macaddr_lt(PG_FUNCTION_ARGS); extern Datum macaddr_le(PG_FUNCTION_ARGS); extern Datum macaddr_eq(PG_FUNCTION_ARGS); diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h index 60b5d01..fe828d1 100644 --- a/src/include/utils/geo_decls.h +++ b/src/include/utils/geo_decls.h @@ -291,20 +291,21 @@ extern Datum box_lt(PG_FUNCTION_ARGS); extern Datum box_gt(PG_FUNCTION_ARGS); extern Datum box_eq(PG_FUNCTION_ARGS); extern Datum box_le(PG_FUNCTION_ARGS); extern Datum box_ge(PG_FUNCTION_ARGS); extern Datum box_area(PG_FUNCTION_ARGS); extern Datum box_width(PG_FUNCTION_ARGS); extern Datum box_height(PG_FUNCTION_ARGS); extern Datum box_distance(PG_FUNCTION_ARGS); extern Datum box_center(PG_FUNCTION_ARGS); extern Datum box_intersect(PG_FUNCTION_ARGS); +extern Datum boxes_bound_box(PG_FUNCTION_ARGS); extern Datum box_diagonal(PG_FUNCTION_ARGS); extern Datum points_box(PG_FUNCTION_ARGS); extern Datum box_add(PG_FUNCTION_ARGS); extern Datum box_sub(PG_FUNCTION_ARGS); extern Datum box_mul(PG_FUNCTION_ARGS); extern Datum box_div(PG_FUNCTION_ARGS); /* public path routines */ extern Datum path_area(PG_FUNCTION_ARGS); extern Datum path_in(PG_FUNCTION_ARGS); diff --git a/src/include/utils/rangetypes.h b/src/include/utils/rangetypes.h index b1d17b9..16dfd0a 100644 --- a/src/include/utils/rangetypes.h +++ b/src/include/utils/rangetypes.h @@ -203,15 +203,16 @@ extern int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2); extern bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound bound1, RangeBound bound2); extern RangeType *make_empty_range(TypeCacheEntry *typcache); /* GiST support (in rangetypes_gist.c) */ extern Datum range_gist_consistent(PG_FUNCTION_ARGS); extern Datum range_gist_compress(PG_FUNCTION_ARGS); extern Datum range_gist_decompress(PG_FUNCTION_ARGS); extern Datum range_gist_union(PG_FUNCTION_ARGS); +extern Datum range_merge(PG_FUNCTION_ARGS); extern Datum range_gist_penalty(PG_FUNCTION_ARGS); extern Datum range_gist_picksplit(PG_FUNCTION_ARGS); extern Datum range_gist_same(PG_FUNCTION_ARGS); #endif /* RANGETYPES_H */ diff --git a/src/test/regress/expected/brin.out b/src/test/regress/expected/brin.out index 61a544e..619731a 100644 --- a/src/test/regress/expected/brin.out +++ b/src/test/regress/expected/brin.out @@ -15,21 +15,23 @@ CREATE TABLE brintest (byteacol bytea, datecol date, timecol time without time zone, timestampcol timestamp without time zone, timestamptzcol timestamp with time zone, intervalcol interval, timetzcol time with time zone, bitcol bit(10), varbitcol bit varying(16), numericcol numeric, uuidcol uuid, - lsncol pg_lsn + int4rangecol int4range, + lsncol pg_lsn, + boxcol box ) WITH (fillfactor=10); INSERT INTO brintest SELECT repeat(stringu1, 42)::bytea, substr(stringu1, 1, 1)::"char", stringu1::name, 142857 * tenthous, thousand, twothousand, repeat(stringu1, 42), unique1::oid, format('(%s,%s)', tenthous, twenty)::tid, @@ -41,21 +43,23 @@ INSERT INTO brintest SELECT date '1995-08-15' + tenthous, time '01:20:30' + thousand * interval '18.5 second', timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', justify_days(justify_hours(tenthous * interval '12 minutes')), timetz '01:30:20' + hundred * interval '15 seconds', thousand::bit(10), tenthous::bit(16)::varbit, tenthous::numeric(36,30) * fivethous * even / (hundred + 1), format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, - format('%s/%s%s', odd, even, tenthous)::pg_lsn + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) FROM tenk1 LIMIT 5; -- throw in some NULL-only tuples too INSERT INTO brintest SELECT NULL FROM tenk1 LIMIT 25; CREATE INDEX brinidx ON brintest USING brin ( byteacol, charcol, namecol, int8col, int2col, int4col, @@ -70,50 +74,55 @@ CREATE INDEX brinidx ON brintest USING brin ( datecol, timecol, timestampcol, timestamptzcol, intervalcol, timetzcol, bitcol, varbitcol, numericcol, uuidcol, - lsncol + int4rangecol, + lsncol, + boxcol ) with (pages_per_range = 1); BEGIN; CREATE TABLE brinopers (colname name, op text[], value text[], check (cardinality(op) = cardinality(value))); INSERT INTO brinopers VALUES ('byteacol', '{>, >=, =, <=, <}', '{ZZAAAA, ZZAAAA, AAAAAA, AAAAAA, AAAAAA}'); INSERT INTO brinopers VALUES ('charcol', '{>, >=, =, <=, <}', '{Z, Z, A, A, A}'); INSERT INTO brinopers VALUES ('namecol', '{>, >=, =, <=, <}', '{ZZAAAA, ZZAAAA, AAAAAA, AAAAAA, AAAAAA}'); INSERT INTO brinopers VALUES ('int8col', '{>, >=, =, <=, <}', '{1428427143, 1428427143, 0, 0, 0}'); INSERT INTO brinopers VALUES ('int2col', '{>, >=, =, <=, <}', '{999, 999, 0, 0, 0}'); INSERT INTO brinopers VALUES ('int4col', '{>, >=, =, <=, <}', '{1999, 1999, 0, 0, 0}'); INSERT INTO brinopers VALUES ('textcol', '{>, >=, =, <=, <}', '{ZZAAAA, ZZAAAA, AAAAA, AAAAA, AAAAA}'); INSERT INTO brinopers VALUES ('oidcol', '{>, >=, =, <=, <}', '{9999, 9999, 0, 0, 0}'); INSERT INTO brinopers VALUES ('tidcol', '{>, >=, =, <=, <}', '{"(9999,19)", "(9999,19)", "(0,0)", "(0,0)", "(0,0)"}'); INSERT INTO brinopers VALUES ('float4col', '{>, >=, =, <=, <}', '{1, 1, 0.0103093, 0.0103093, 0.0103093}'); INSERT INTO brinopers VALUES ('float8col', '{>, >=, =, <=, <}', '{1.98, 1.98, 0, 0, 0}'); -INSERT INTO brinopers VALUES ('inetcol', '{>, >=, =, <=, <}', '{10.2.42.19, 10.2.42.19, 10.2.3.4, 10.2.3.4, 10.2.3.4}'); +INSERT INTO brinopers VALUES ('inetcol', '{&&, >>=, <<=, =, <, <=, >, >=, >>, <<}', '{10.2.42.19/8, 10.2.42.19/16, 10.2.3.4/24, 10.2.3.4, 10.2.3.4, 10.2.3.4, 10.2.3.4, 10.2.3.4, 10.2.3.4/29, 10.2.3.4/17}'); INSERT INTO brinopers VALUES ('bpcharcol', '{>, >=, =, <=, <}', '{Z, Z, A, A, A}'); INSERT INTO brinopers VALUES ('datecol', '{>, >=, =, <=, <}', '{2022-12-30, 2022-12-30, 1995-08-15, 1995-08-15, 1995-08-15}'); INSERT INTO brinopers VALUES ('timecol', '{>, >=, =, <=, <}', '{06:28:31.5, 06:28:31.5, 01:20:30, 01:20:30, 01:20:30}'); INSERT INTO brinopers VALUES ('timestampcol', '{>, >=, =, <=, <}', '{1984-01-20 22:42:21, 1984-01-20 22:42:21, 1942-07-23 03:05:09, 1942-07-23 03:05:09, 1942-07-23 03:05:09}'); INSERT INTO brinopers VALUES ('timestamptzcol', '{>, >=, =, <=, <}', '{1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03, 1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04}'); INSERT INTO brinopers VALUES ('intervalcol', '{>, >=, =, <=, <}', '{2 mons 23 days 07:48:00, 2 mons 23 days 07:48:00, 00:00:00, 00:00:00, 00:00:00}'); INSERT INTO brinopers VALUES ('timetzcol', '{>, >=, =, <=, <}', '{01:55:05-03, 01:55:05-03, 01:30:20-03, 01:30:20-03, 01:30:20-03}'); INSERT INTO brinopers VALUES ('numericcol', '{>, >=, =, <=, <}', '{99470151.9, 99470151.9, 0.00, 0.01, 0.01}'); INSERT INTO brinopers VALUES ('macaddrcol', '{>, >=, =, <=, <}', '{ff:fe:00:00:00:00, ff:fe:00:00:00:00, 00:00:01:00:00:00, 00:00:01:00:00:00, 00:00:01:00:00:00}'); INSERT INTO brinopers VALUES ('bitcol', '{>, >=, =, <=, <}', '{1111111000, 1111111000, 0000000010, 0000000010, 0000000010}'); INSERT INTO brinopers VALUES ('varbitcol', '{>, >=, =, <=, <}', '{1111111111111000, 1111111111111000, 0000000000000100, 0000000000000100, 0000000000000100}'); INSERT INTO brinopers VALUES ('uuidcol', '{>, >=, =, <=, <}', '{99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998, 00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040005}'); +INSERT INTO brinopers VALUES ('int4rangecol', '{<<, &<, &&, &>, >>, @>, <@, =, <, <=, >, >=}', '{"[3,4)","[36,44)","(,2]","[3,4)","[36,44)","(,2]","[3,4)","[36,44)","[36,44)","(3,4)","[36,44)","[536,)"}'); +INSERT INTO brinopers VALUES ('int4rangecol', '{@>}', '{3}'); INSERT INTO brinopers VALUES ('lsncol', '{>, >=, =, <=, <, IS, IS NOT}', '{198/1999799, 198/1999799, 30/312815, 0/1200, 0/1200, NULL, NULL}'); +INSERT INTO brinopers VALUES ('boxcol', '{<<, &<, &&, &>, >>, <<|, &<|, |&>, |>>, @>, <@, ~=}', '{"((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))"}'); COMMIT; DO $x$ DECLARE r record; tabname text; tabname_ss text; count int; query text; plan text; BEGIN @@ -163,20 +172,22 @@ INSERT INTO brintest SELECT date '1995-08-15' + tenthous, time '01:20:30' + thousand * interval '18.5 second', timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', justify_days(justify_hours(tenthous * interval '12 minutes')), timetz '01:30:20' + hundred * interval '15 seconds', thousand::bit(10), tenthous::bit(16)::varbit, tenthous::numeric(36,30) * fivethous * even / (hundred + 1), format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, - format('%s/%s%s', odd, even, tenthous)::pg_lsn + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) FROM tenk1 LIMIT 5 OFFSET 5; SELECT brin_summarize_new_values('brinidx'::regclass); brin_summarize_new_values --------------------------- 5 (1 row) UPDATE brintest SET int8col = int8col * int4col; UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL; diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 9870bfa..63c557e 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -1652,24 +1652,49 @@ ORDER BY 1, 2, 3; 2742 | 1 | @@ 2742 | 2 | @> 2742 | 2 | @@@ 2742 | 3 | <@ 2742 | 4 | = 2742 | 7 | @> 2742 | 9 | ? 2742 | 10 | ?| 2742 | 11 | ?& 3580 | 1 | < + 3580 | 1 | << + 3580 | 2 | &< 3580 | 2 | <= + 3580 | 3 | && 3580 | 3 | = + 3580 | 4 | &> 3580 | 4 | >= 3580 | 5 | > + 3580 | 5 | >> + 3580 | 6 | ~= + 3580 | 7 | >>= + 3580 | 7 | @> + 3580 | 8 | <<= + 3580 | 8 | <@ + 3580 | 9 | &<| + 3580 | 10 | <<| + 3580 | 11 | |>> + 3580 | 12 | |&> + 3580 | 13 | ~ + 3580 | 14 | @ + 3580 | 16 | @> + 3580 | 17 | -|- + 3580 | 18 | = + 3580 | 20 | < + 3580 | 21 | <= + 3580 | 22 | > + 3580 | 23 | >= + 3580 | 24 | >> + 3580 | 26 | << 4000 | 1 | << 4000 | 1 | ~<~ 4000 | 2 | &< 4000 | 2 | ~<=~ 4000 | 3 | && 4000 | 3 | = 4000 | 4 | &> 4000 | 4 | ~>=~ 4000 | 5 | >> 4000 | 5 | ~>~ @@ -1678,21 +1703,21 @@ ORDER BY 1, 2, 3; 4000 | 7 | @> 4000 | 8 | <@ 4000 | 10 | <^ 4000 | 11 | < 4000 | 11 | >^ 4000 | 12 | <= 4000 | 14 | >= 4000 | 15 | > 4000 | 16 | @> 4000 | 18 | = -(85 rows) +(110 rows) -- Check that all opclass search operators have selectivity estimators. -- This is not absolutely required, but it seems a reasonable thing -- to insist on for all standard datatypes. SELECT p1.amopfamily, p1.amopopr, p2.oid, p2.oprname FROM pg_amop AS p1, pg_operator AS p2 WHERE p1.amopopr = p2.oid AND p1.amoppurpose = 's' AND (p2.oprrest = 0 OR p2.oprjoin = 0); amopfamily | amopopr | oid | oprname ------------+---------+-----+--------- diff --git a/src/test/regress/sql/brin.sql b/src/test/regress/sql/brin.sql index b1d2c5c..0ee93a0 100644 --- a/src/test/regress/sql/brin.sql +++ b/src/test/regress/sql/brin.sql @@ -15,21 +15,23 @@ CREATE TABLE brintest (byteacol bytea, datecol date, timecol time without time zone, timestampcol timestamp without time zone, timestamptzcol timestamp with time zone, intervalcol interval, timetzcol time with time zone, bitcol bit(10), varbitcol bit varying(16), numericcol numeric, uuidcol uuid, - lsncol pg_lsn + int4rangecol int4range, + lsncol pg_lsn, + boxcol box ) WITH (fillfactor=10); INSERT INTO brintest SELECT repeat(stringu1, 42)::bytea, substr(stringu1, 1, 1)::"char", stringu1::name, 142857 * tenthous, thousand, twothousand, repeat(stringu1, 42), unique1::oid, @@ -42,21 +44,23 @@ INSERT INTO brintest SELECT date '1995-08-15' + tenthous, time '01:20:30' + thousand * interval '18.5 second', timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', justify_days(justify_hours(tenthous * interval '12 minutes')), timetz '01:30:20' + hundred * interval '15 seconds', thousand::bit(10), tenthous::bit(16)::varbit, tenthous::numeric(36,30) * fivethous * even / (hundred + 1), format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, - format('%s/%s%s', odd, even, tenthous)::pg_lsn + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) FROM tenk1 LIMIT 5; -- throw in some NULL-only tuples too INSERT INTO brintest SELECT NULL FROM tenk1 LIMIT 25; CREATE INDEX brinidx ON brintest USING brin ( byteacol, charcol, namecol, int8col, @@ -73,52 +77,57 @@ CREATE INDEX brinidx ON brintest USING brin ( datecol, timecol, timestampcol, timestamptzcol, intervalcol, timetzcol, bitcol, varbitcol, numericcol, uuidcol, - lsncol + int4rangecol, + lsncol, + boxcol ) with (pages_per_range = 1); BEGIN; CREATE TABLE brinopers (colname name, op text[], value text[], check (cardinality(op) = cardinality(value))); INSERT INTO brinopers VALUES ('byteacol', '{>, >=, =, <=, <}', '{ZZAAAA, ZZAAAA, AAAAAA, AAAAAA, AAAAAA}'); INSERT INTO brinopers VALUES ('charcol', '{>, >=, =, <=, <}', '{Z, Z, A, A, A}'); INSERT INTO brinopers VALUES ('namecol', '{>, >=, =, <=, <}', '{ZZAAAA, ZZAAAA, AAAAAA, AAAAAA, AAAAAA}'); INSERT INTO brinopers VALUES ('int8col', '{>, >=, =, <=, <}', '{1428427143, 1428427143, 0, 0, 0}'); INSERT INTO brinopers VALUES ('int2col', '{>, >=, =, <=, <}', '{999, 999, 0, 0, 0}'); INSERT INTO brinopers VALUES ('int4col', '{>, >=, =, <=, <}', '{1999, 1999, 0, 0, 0}'); INSERT INTO brinopers VALUES ('textcol', '{>, >=, =, <=, <}', '{ZZAAAA, ZZAAAA, AAAAA, AAAAA, AAAAA}'); INSERT INTO brinopers VALUES ('oidcol', '{>, >=, =, <=, <}', '{9999, 9999, 0, 0, 0}'); INSERT INTO brinopers VALUES ('tidcol', '{>, >=, =, <=, <}', '{"(9999,19)", "(9999,19)", "(0,0)", "(0,0)", "(0,0)"}'); INSERT INTO brinopers VALUES ('float4col', '{>, >=, =, <=, <}', '{1, 1, 0.0103093, 0.0103093, 0.0103093}'); INSERT INTO brinopers VALUES ('float8col', '{>, >=, =, <=, <}', '{1.98, 1.98, 0, 0, 0}'); -INSERT INTO brinopers VALUES ('inetcol', '{>, >=, =, <=, <}', '{10.2.42.19, 10.2.42.19, 10.2.3.4, 10.2.3.4, 10.2.3.4}'); +INSERT INTO brinopers VALUES ('inetcol', '{&&, >>=, <<=, =, <, <=, >, >=, >>, <<}', '{10.2.42.19/8, 10.2.42.19/16, 10.2.3.4/24, 10.2.3.4, 10.2.3.4, 10.2.3.4, 10.2.3.4, 10.2.3.4, 10.2.3.4/29, 10.2.3.4/17}'); INSERT INTO brinopers VALUES ('bpcharcol', '{>, >=, =, <=, <}', '{Z, Z, A, A, A}'); INSERT INTO brinopers VALUES ('datecol', '{>, >=, =, <=, <}', '{2022-12-30, 2022-12-30, 1995-08-15, 1995-08-15, 1995-08-15}'); INSERT INTO brinopers VALUES ('timecol', '{>, >=, =, <=, <}', '{06:28:31.5, 06:28:31.5, 01:20:30, 01:20:30, 01:20:30}'); INSERT INTO brinopers VALUES ('timestampcol', '{>, >=, =, <=, <}', '{1984-01-20 22:42:21, 1984-01-20 22:42:21, 1942-07-23 03:05:09, 1942-07-23 03:05:09, 1942-07-23 03:05:09}'); INSERT INTO brinopers VALUES ('timestamptzcol', '{>, >=, =, <=, <}', '{1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03, 1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04}'); INSERT INTO brinopers VALUES ('intervalcol', '{>, >=, =, <=, <}', '{2 mons 23 days 07:48:00, 2 mons 23 days 07:48:00, 00:00:00, 00:00:00, 00:00:00}'); INSERT INTO brinopers VALUES ('timetzcol', '{>, >=, =, <=, <}', '{01:55:05-03, 01:55:05-03, 01:30:20-03, 01:30:20-03, 01:30:20-03}'); INSERT INTO brinopers VALUES ('numericcol', '{>, >=, =, <=, <}', '{99470151.9, 99470151.9, 0.00, 0.01, 0.01}'); INSERT INTO brinopers VALUES ('macaddrcol', '{>, >=, =, <=, <}', '{ff:fe:00:00:00:00, ff:fe:00:00:00:00, 00:00:01:00:00:00, 00:00:01:00:00:00, 00:00:01:00:00:00}'); INSERT INTO brinopers VALUES ('bitcol', '{>, >=, =, <=, <}', '{1111111000, 1111111000, 0000000010, 0000000010, 0000000010}'); INSERT INTO brinopers VALUES ('varbitcol', '{>, >=, =, <=, <}', '{1111111111111000, 1111111111111000, 0000000000000100, 0000000000000100, 0000000000000100}'); INSERT INTO brinopers VALUES ('uuidcol', '{>, >=, =, <=, <}', '{99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998, 00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040005}'); +INSERT INTO brinopers VALUES ('int4rangecol', '{<<, &<, &&, &>, >>, @>, <@, =, <, <=, >, >=}', '{"[3,4)","[36,44)","(,2]","[3,4)","[36,44)","(,2]","[3,4)","[36,44)","[36,44)","(3,4)","[36,44)","[536,)"}'); +INSERT INTO brinopers VALUES ('int4rangecol', '{@>}', '{3}'); INSERT INTO brinopers VALUES ('lsncol', '{>, >=, =, <=, <, IS, IS NOT}', '{198/1999799, 198/1999799, 30/312815, 0/1200, 0/1200, NULL, NULL}'); +INSERT INTO brinopers VALUES ('boxcol', '{<<, &<, &&, &>, >>, <<|, &<|, |&>, |>>, @>, <@, ~=}', '{"((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))","((1,2),(3,4))"}'); COMMIT; DO $x$ DECLARE r record; tabname text; tabname_ss text; count int; query text; plan text; @@ -170,17 +179,19 @@ INSERT INTO brintest SELECT date '1995-08-15' + tenthous, time '01:20:30' + thousand * interval '18.5 second', timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours', timestamptz '1972-10-10 03:00' + thousand * interval '1 hour', justify_days(justify_hours(tenthous * interval '12 minutes')), timetz '01:30:20' + hundred * interval '15 seconds', thousand::bit(10), tenthous::bit(16)::varbit, tenthous::numeric(36,30) * fivethous * even / (hundred + 1), format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid, - format('%s/%s%s', odd, even, tenthous)::pg_lsn + int4range(thousand, twothousand), + format('%s/%s%s', odd, even, tenthous)::pg_lsn, + box(point(odd, even), point(thousand, twothousand)) FROM tenk1 LIMIT 5 OFFSET 5; SELECT brin_summarize_new_values('brinidx'::regclass); UPDATE brintest SET int8col = int8col * int4col; UPDATE brintest SET textcol = '' WHERE textcol IS NOT NULL;