70 #define MultirangeGetItemsPtr(mr) ((uint32 *) ((Pointer) (mr) + \ 71 sizeof(MultirangeType))) 72 #define MultirangeGetFlagsPtr(mr) ((uint8 *) ((Pointer) (mr) + \ 73 sizeof(MultirangeType) + ((mr)->rangeCount - 1) * sizeof(uint32))) 74 #define MultirangeGetBoundariesPtr(mr, align) ((Pointer) (mr) + \ 75 att_align_nominal(sizeof(MultirangeType) + \ 76 ((mr)->rangeCount - 1) * sizeof(uint32) + \ 77 (mr)->rangeCount * sizeof(uint8), (align))) 79 #define MULTIRANGE_ITEM_OFF_BIT 0x80000000 80 #define MULTIRANGE_ITEM_GET_OFFLEN(item) ((item) & 0x7FFFFFFF) 81 #define MULTIRANGE_ITEM_HAS_OFF(item) ((item) & MULTIRANGE_ITEM_OFF_BIT) 82 #define MULTIRANGE_ITEM_OFFSET_STRIDE 4 94 int32 input_range_count,
122 int32 ranges_seen = 0;
123 int32 range_count = 0;
124 int32 range_capacity = 8;
130 const char *ptr = input_str;
131 const char *range_str_begin = NULL;
139 while (*ptr !=
'\0' && isspace((
unsigned char) *ptr))
146 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
147 errmsg(
"malformed multirange literal: \"%s\"",
159 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
160 errmsg(
"malformed multirange literal: \"%s\"",
165 if (isspace((
unsigned char) ch))
171 if (ch ==
'[' || ch ==
'(')
173 range_str_begin = ptr;
176 else if (ch ==
'}' && ranges_seen == 0)
188 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
189 errmsg(
"malformed multirange literal: \"%s\"",
194 if (ch ==
']' || ch ==
')')
196 range_str_len = ptr - range_str_begin + 1;
197 range_str =
pnstrdup(range_str_begin, range_str_len);
198 if (range_capacity == range_count)
210 ranges[range_count++] =
range;
234 if (*(ptr + 1) ==
'"')
256 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
257 errmsg(
"malformed multirange literal: \"%s\"",
259 errdetail(
"Expected comma or end of multirange.")));
269 elog(
ERROR,
"unknown parse state: %d", parse_state);
274 while (*ptr !=
'\0' && isspace((
unsigned char) *ptr))
279 (
errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
280 errmsg(
"malformed multirange literal: \"%s\"",
282 errdetail(
"Junk after right bracket.")));
308 for (i = 0; i < range_count; i++)
344 for (
int i = 0;
i < range_count;
i++)
362 range_count, ranges);
384 for (
int i = 0;
i < range_count;
i++)
422 elog(
ERROR,
"type %u is not a multirange type", mltrngtypid);
439 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
440 errmsg(
"no binary input function available for type %s",
444 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
445 errmsg(
"no binary output function available for type %s",
473 int32 output_range_count = 0;
480 for (i = 0; i < input_range_count; i++)
482 currentRange = ranges[
i];
486 if (lastRange == NULL)
488 ranges[output_range_count++] = lastRange = currentRange;
500 ranges[output_range_count - 1] = lastRange =
506 lastRange = ranges[output_range_count] = currentRange;
507 output_range_count++;
512 ranges[output_range_count - 1] = lastRange =
517 return output_range_count;
542 if (typcache == NULL ||
543 typcache->
type_id != mltrngtypid)
547 elog(
ERROR,
"type %u is not a multirange type", mltrngtypid);
570 Max(range_count - 1, 0) *
sizeof(
uint32) +
571 range_count *
sizeof(
uint8), elemalign);
574 for (i = 0; i < range_count; i++)
577 sizeof(
char), elemalign);
600 for (i = 0; i < range_count; i++)
611 items[i - 1] = ptr - begin;
613 items[i - 1] -= prev_offset;
616 prev_offset = ptr - begin;
620 memcpy(ptr, (
Pointer) (ranges[i] + 1), len);
697 Assert(i < multirange->rangeCount);
719 memcpy(range + 1, begin, ptr - begin);
720 *((
uint8 *) (range + 1) + (ptr - begin)) = flags;
744 Assert(i < multirange->rangeCount);
757 lbound =
fetch_att(ptr, typbyval, typlen);
767 ubound =
fetch_att(ptr, typbyval, typlen);
782 upper->
lower =
false;
802 return make_range(rangetyp, &lower, &upper,
false);
820 if (*range_count > 0)
825 for (i = 0; i < *range_count; i++)
907 else if (comparison > 0)
960 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
961 errmsg(
"multirange values cannot contain NULL members")));
968 (
errcode(ERRCODE_CARDINALITY_VIOLATION),
969 errmsg(
"multiranges cannot be constructed from multi-dimensional arrays")));
972 if (rngtypid != rangetyp->
type_id)
974 (
errcode(ERRCODE_DATATYPE_MISMATCH),
975 errmsg(
"type %u does not match constructor type", rngtypid)));
989 rangetyp->
typalign, &elements, &nulls, &range_count);
992 for (i = 0; i < range_count; i++)
996 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
997 errmsg(
"multirange values cannot contain NULL members")));
1031 (
errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
1032 errmsg(
"multirange values cannot contain NULL members")));
1038 if (rngtypid != rangetyp->
type_id)
1040 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1041 errmsg(
"type %u does not match constructor type", rngtypid)));
1061 "niladic multirange constructor must not receive arguments");
1097 range_count3 = range_count1 + range_count2;
1099 memcpy(ranges3, ranges1, range_count1 *
sizeof(
RangeType *));
1100 memcpy(ranges3 + range_count1, ranges2, range_count2 *
sizeof(
RangeType *));
1102 range_count3, ranges3));
1162 for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1169 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1181 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1200 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1217 ranges3[range_count3++] = r1;
1220 return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3);
1266 if (range_count1 == 0 || range_count2 == 0)
1290 for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1297 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1309 r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1325 return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3);
1342 elog(
ERROR,
"range_agg_transfn called in non-aggregate context");
1347 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1348 errmsg(
"range_agg must be called with a range")));
1377 elog(
ERROR,
"range_agg_finalfn called in non-aggregate context");
1385 range_count = state->
nelems;
1386 if (range_count == 0)
1393 for (i = 0; i < range_count; i++)
1413 elog(
ERROR,
"multirange_intersect_agg_transfn called in non-aggregate context");
1418 (
errcode(ERRCODE_DATATYPE_MISMATCH),
1419 errmsg(
"range_intersect_agg must be called with a multirange")));
1613 void *
key,
bool *match)
1623 if (cmp > 0 || (cmp == 0 && !lower->
inclusive))
1632 if (cmp < 0 || (cmp == 0 && !upper->
inclusive))
1713 void *
key,
bool *match)
1805 int32 range_count_1;
1806 int32 range_count_2;
1815 elog(
ERROR,
"multirange types do not match");
1820 if (range_count_1 != range_count_2)
1823 for (i = 0; i < range_count_1; i++)
1915 void *
key,
bool *match)
1984 for (i1 = 0, i2 = 0; i2 < range_count2; i2++)
1991 if (++i1 >= range_count1)
2223 if (range_count2 == 0)
2225 if (range_count1 == 0)
2234 for (i2 = 0; i2 < range_count2; i2++)
2241 if (++i1 >= range_count1)
2432 if (range_count > 1)
2497 if (range_count1 > 1)
2500 if (range_count2 > 1)
2516 int32 range_count_1;
2517 int32 range_count_2;
2518 int32 range_count_max;
2525 elog(
ERROR,
"multirange types do not match");
2533 range_count_max =
Max(range_count_1, range_count_2);
2534 for (i = 0; i < range_count_max; i++)
2548 if (i >= range_count_1)
2553 if (i >= range_count_2)
2637 &firstLower, &firstUpper);
2639 &lastLower, &lastUpper);
2668 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
2669 errmsg(
"could not identify a hash function for type %s",
2674 for (i = 0; i < range_count; i++)
2701 range_hash ^= lower_hash;
2702 range_hash = (range_hash << 1) | (range_hash >> 31);
2703 range_hash ^= upper_hash;
2709 result = (result << 5) - result + range_hash;
2740 (
errcode(ERRCODE_UNDEFINED_FUNCTION),
2741 errmsg(
"could not identify a hash function for type %s",
2746 for (i = 0; i < range_count; i++)
2776 range_hash ^= lower_hash;
2778 range_hash ^= upper_hash;
2784 result = (result << 5) - result + range_hash;
Datum multirange_overright_multirange(PG_FUNCTION_ARGS)
#define RANGE_HAS_UBOUND(flags)
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
#define PG_RETURN_POINTER(x)
#define DatumGetUInt32(X)
static void write_multirange_data(MultirangeType *multirange, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
int(* multirange_bsearch_comparison)(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
#define PG_GETARG_INT32(n)
Datum multirange_lower_inf(PG_FUNCTION_ARGS)
FmgrInfo rng_cmp_proc_finfo
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Datum multirange_contains_range(PG_FUNCTION_ARGS)
Datum multirange_lt(PG_FUNCTION_ARGS)
#define RANGE_HAS_LBOUND(flags)
#define MULTIRANGE_ITEM_GET_OFFLEN(item)
Datum multirange_send(PG_FUNCTION_ARGS)
char * pnstrdup(const char *in, Size len)
RangeType * range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Datum range_agg_finalfn(PG_FUNCTION_ARGS)
Datum multirange_upper_inc(PG_FUNCTION_ARGS)
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
#define RANGE_EMPTY_LITERAL
#define att_align_nominal(cur_offset, attalign)
#define PG_GETARG_MULTIRANGE_P(n)
#define TYPECACHE_HASH_EXTENDED_PROC_FINFO
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
#define RangeTypeGetOid(r)
Datum multirange_le(PG_FUNCTION_ARGS)
Datum multirange_in(PG_FUNCTION_ARGS)
Datum lower(PG_FUNCTION_ARGS)
Datum multirange_after_multirange(PG_FUNCTION_ARGS)
#define TYPECACHE_MULTIRANGE_INFO
#define PG_RETURN_MULTIRANGE_P(x)
#define PointerGetDatum(X)
#define PG_GETARG_DATUM(n)
Datum multirange_cmp(PG_FUNCTION_ARGS)
bool multirange_contains_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
StringInfo makeStringInfo(void)
StringInfoData * StringInfo
Datum range_merge_from_multirange(PG_FUNCTION_ARGS)
#define TYPECACHE_HASH_PROC_FINFO
Datum multirange_recv(PG_FUNCTION_ARGS)
#define MULTIRANGE_ITEM_OFFSET_STRIDE
#define PG_RETURN_INT32(x)
int errcode(int sqlerrcode)
bool type_is_range(Oid typid)
Datum idx(PG_FUNCTION_ARGS)
#define PG_GETARG_POINTER(n)
Datum range_overright_multirange(PG_FUNCTION_ARGS)
RangeType * multirange_get_union_range(TypeCacheEntry *rangetyp, const MultirangeType *mr)
RangeType * make_empty_range(TypeCacheEntry *typcache)
static Size multirange_size_estimate(TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
#define PG_RETURN_BYTEA_P(x)
Datum upper(PG_FUNCTION_ARGS)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Datum multirange_contained_by_range(PG_FUNCTION_ARGS)
#define PG_RETURN_UINT64(x)
#define OidIsValid(objectId)
Datum multirange_upper(PG_FUNCTION_ARGS)
Datum multirange_contained_by_multirange(PG_FUNCTION_ARGS)
#define RangeTypePGetDatum(X)
Datum range_before_multirange(PG_FUNCTION_ARGS)
Datum multirange_gt(PG_FUNCTION_ARGS)
#define PG_RETURN_UINT32(x)
struct MultirangeIOData MultirangeIOData
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Datum multirange_contains_multirange(PG_FUNCTION_ARGS)
Datum multirange_upper_inf(PG_FUNCTION_ARGS)
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
#define PG_GETARG_ARRAYTYPE_P(n)
static MultirangeIOData * get_multirange_io_data(FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func)
void pfree(void *pointer)
Datum range_overlaps_multirange(PG_FUNCTION_ARGS)
Datum multirange_overright_range(PG_FUNCTION_ARGS)
static bool range_bounds_overlaps(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
bool range_overleft_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
#define MultirangeGetItemsPtr(mr)
bool range_overright_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
Datum multirange_overlaps_multirange(PG_FUNCTION_ARGS)
Datum range_adjacent_multirange(PG_FUNCTION_ARGS)
Datum range_contains_multirange(PG_FUNCTION_ARGS)
Datum multirange_intersect(PG_FUNCTION_ARGS)
static int multirange_range_contains_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
bool range_before_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
void appendStringInfoString(StringInfo str, const char *s)
Datum multirange_overlaps_range(PG_FUNCTION_ARGS)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
Datum multirange_lower(PG_FUNCTION_ARGS)
TypeCacheEntry * typcache
Datum multirange_after_range(PG_FUNCTION_ARGS)
int errdetail(const char *fmt,...)
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
bool range_contains_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
bool multirange_ne_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
void resetStringInfo(StringInfo str)
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
static int32 multirange_canonicalize(TypeCacheEntry *rangetyp, int32 input_range_count, RangeType **ranges)
#define MULTIRANGE_ITEM_HAS_OFF(item)
MultirangeType * multirange_minus_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
#define MultirangeGetBoundariesPtr(mr, align)
#define att_addlength_pointer(cur_offset, attlen, attptr)
Datum hash_multirange_extended(PG_FUNCTION_ARGS)
Datum range_contained_by_multirange(PG_FUNCTION_ARGS)
#define PG_RETURN_RANGE_P(x)
struct TypeCacheEntry * rngelemtype
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
Datum multirange_minus(PG_FUNCTION_ARGS)
Datum multirange_ge(PG_FUNCTION_ARGS)
FmgrInfo hash_extended_proc_finfo
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Datum multirange_constructor0(PG_FUNCTION_ARGS)
void * palloc0(Size size)
bool multirange_contains_elem_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, Datum val)
Datum range_agg_transfn(PG_FUNCTION_ARGS)
MultirangeType * make_empty_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp)
#define PG_RETURN_BOOL(x)
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
#define PG_RETURN_DATUM(x)
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
Datum multirange_union(PG_FUNCTION_ARGS)
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
static uint32 multirange_get_bounds_offset(const MultirangeType *multirange, int32 i)
Datum range_after_multirange(PG_FUNCTION_ARGS)
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
RangeType * multirange_get_range(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
Datum multirange_contains_elem(PG_FUNCTION_ARGS)
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
#define ereport(elevel,...)
#define DatumGetUInt64(X)
Datum multirange_ne(PG_FUNCTION_ARGS)
#define MultirangeGetFlagsPtr(mr)
bool multirange_contains_range_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, const RangeType *r)
#define Assert(condition)
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Datum range_overleft_multirange(PG_FUNCTION_ARGS)
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
static Datum hash_uint32(uint32 k)
bool multirange_eq_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
#define PG_RETURN_CSTRING(x)
MultirangeType * multirange_intersect_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
Datum multirange_adjacent_multirange(PG_FUNCTION_ARGS)
Datum multirange_constructor2(PG_FUNCTION_ARGS)
Datum multirange_lower_inc(PG_FUNCTION_ARGS)
bool type_is_multirange(Oid typid)
#define PG_GETARG_RANGE_P(n)
#define DatumGetRangeTypeP(X)
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
#define PG_FREE_IF_COPY(ptr, n)
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
void * repalloc(void *pointer, Size size)
bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
Datum multirange_eq(PG_FUNCTION_ARGS)
static StringInfoData tmpbuf
Datum multirange_overleft_range(PG_FUNCTION_ARGS)
Datum multirange_overleft_multirange(PG_FUNCTION_ARGS)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
static int multirange_elem_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
static int multirange_range_overlaps_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
int errmsg(const char *fmt,...)
#define fetch_att(T, attbyval, attlen)
void * MemoryContextAlloc(MemoryContext context, Size size)
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
#define PG_GETARG_CSTRING(n)
#define MultirangeTypeGetOid(mr)
Datum multirange_empty(PG_FUNCTION_ARGS)
#define MULTIRANGE_ITEM_OFF_BIT
bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
Datum multirange_intersect_agg_transfn(PG_FUNCTION_ARGS)
Datum multirange_out(PG_FUNCTION_ARGS)
#define SET_VARSIZE(PTR, len)
bool multirange_overlaps_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
Datum multirange_adjacent_range(PG_FUNCTION_ARGS)
Datum multirange_constructor1(PG_FUNCTION_ARGS)
bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
bool multirange_before_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
int range_compare(const void *key1, const void *key2, void *arg)
static Datum hash_uint32_extended(uint32 k, uint64 seed)
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Datum multirange_before_range(PG_FUNCTION_ARGS)
bool range_after_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Datum multirange_before_multirange(PG_FUNCTION_ARGS)
Datum hash_multirange(PG_FUNCTION_ARGS)
static int cmp(const chr *x, const chr *y, size_t len)
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
Datum elem_contained_by_multirange(PG_FUNCTION_ARGS)