PostgreSQL Source Code  git master
multirangetypes.c File Reference
#include "postgres.h"
#include "access/tupmacs.h"
#include "common/hashfn.h"
#include "funcapi.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/rangetypes.h"
#include "utils/multirangetypes.h"
#include "utils/array.h"
#include "utils/memutils.h"
Include dependency graph for multirangetypes.c:

Go to the source code of this file.

Data Structures

struct  MultirangeIOData
 

Macros

#define MultirangeGetItemsPtr(mr)
 
#define MultirangeGetFlagsPtr(mr)
 
#define MultirangeGetBoundariesPtr(mr, align)
 
#define MULTIRANGE_ITEM_OFF_BIT   0x80000000
 
#define MULTIRANGE_ITEM_GET_OFFLEN(item)   ((item) & 0x7FFFFFFF)
 
#define MULTIRANGE_ITEM_HAS_OFF(item)   ((item) & MULTIRANGE_ITEM_OFF_BIT)
 
#define MULTIRANGE_ITEM_OFFSET_STRIDE   4
 

Typedefs

typedef struct MultirangeIOData MultirangeIOData
 
typedef int(* multirange_bsearch_comparison) (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
 

Enumerations

enum  MultirangeParseState {
  MULTIRANGE_BEFORE_RANGE, MULTIRANGE_IN_RANGE, MULTIRANGE_IN_RANGE_ESCAPED, MULTIRANGE_IN_RANGE_QUOTED,
  MULTIRANGE_IN_RANGE_QUOTED_ESCAPED, MULTIRANGE_AFTER_RANGE, MULTIRANGE_FINISHED
}
 

Functions

static MultirangeIODataget_multirange_io_data (FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func)
 
static int32 multirange_canonicalize (TypeCacheEntry *rangetyp, int32 input_range_count, RangeType **ranges)
 
Datum multirange_in (PG_FUNCTION_ARGS)
 
Datum multirange_out (PG_FUNCTION_ARGS)
 
Datum multirange_recv (PG_FUNCTION_ARGS)
 
Datum multirange_send (PG_FUNCTION_ARGS)
 
TypeCacheEntrymultirange_get_typcache (FunctionCallInfo fcinfo, Oid mltrngtypid)
 
static Size multirange_size_estimate (TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
 
static void write_multirange_data (MultirangeType *multirange, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
 
MultirangeTypemake_multirange (Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
 
static uint32 multirange_get_bounds_offset (const MultirangeType *multirange, int32 i)
 
RangeTypemultirange_get_range (TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
 
void multirange_get_bounds (TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
 
RangeTypemultirange_get_union_range (TypeCacheEntry *rangetyp, const MultirangeType *mr)
 
void multirange_deserialize (TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
 
MultirangeTypemake_empty_multirange (Oid mltrngtypoid, TypeCacheEntry *rangetyp)
 
static bool range_bounds_overlaps (TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
 
static bool range_bounds_contains (TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
 
static bool multirange_bsearch_match (TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
 
Datum multirange_constructor2 (PG_FUNCTION_ARGS)
 
Datum multirange_constructor1 (PG_FUNCTION_ARGS)
 
Datum multirange_constructor0 (PG_FUNCTION_ARGS)
 
Datum multirange_union (PG_FUNCTION_ARGS)
 
Datum multirange_minus (PG_FUNCTION_ARGS)
 
MultirangeTypemultirange_minus_internal (Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
 
Datum multirange_intersect (PG_FUNCTION_ARGS)
 
MultirangeTypemultirange_intersect_internal (Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
 
Datum range_agg_transfn (PG_FUNCTION_ARGS)
 
Datum range_agg_finalfn (PG_FUNCTION_ARGS)
 
Datum multirange_intersect_agg_transfn (PG_FUNCTION_ARGS)
 
Datum multirange_lower (PG_FUNCTION_ARGS)
 
Datum multirange_upper (PG_FUNCTION_ARGS)
 
Datum multirange_empty (PG_FUNCTION_ARGS)
 
Datum multirange_lower_inc (PG_FUNCTION_ARGS)
 
Datum multirange_upper_inc (PG_FUNCTION_ARGS)
 
Datum multirange_lower_inf (PG_FUNCTION_ARGS)
 
Datum multirange_upper_inf (PG_FUNCTION_ARGS)
 
Datum multirange_contains_elem (PG_FUNCTION_ARGS)
 
Datum elem_contained_by_multirange (PG_FUNCTION_ARGS)
 
static int multirange_elem_bsearch_comparison (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
 
bool multirange_contains_elem_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr, Datum val)
 
Datum multirange_contains_range (PG_FUNCTION_ARGS)
 
Datum range_contains_multirange (PG_FUNCTION_ARGS)
 
Datum range_contained_by_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_contained_by_range (PG_FUNCTION_ARGS)
 
static int multirange_range_contains_bsearch_comparison (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
 
bool multirange_contains_range_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr, const RangeType *r)
 
bool range_contains_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool multirange_eq_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
Datum multirange_eq (PG_FUNCTION_ARGS)
 
bool multirange_ne_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
Datum multirange_ne (PG_FUNCTION_ARGS)
 
Datum range_overlaps_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_overlaps_range (PG_FUNCTION_ARGS)
 
Datum multirange_overlaps_multirange (PG_FUNCTION_ARGS)
 
static int multirange_range_overlaps_bsearch_comparison (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
 
bool range_overlaps_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool multirange_overlaps_multirange_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
bool range_overleft_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
Datum range_overleft_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_overleft_range (PG_FUNCTION_ARGS)
 
Datum multirange_overleft_multirange (PG_FUNCTION_ARGS)
 
bool range_overright_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
Datum range_overright_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_overright_range (PG_FUNCTION_ARGS)
 
Datum multirange_overright_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_contains_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_contained_by_multirange (PG_FUNCTION_ARGS)
 
bool multirange_contains_multirange_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
Datum range_before_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_before_range (PG_FUNCTION_ARGS)
 
Datum multirange_before_multirange (PG_FUNCTION_ARGS)
 
Datum range_after_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_after_range (PG_FUNCTION_ARGS)
 
Datum multirange_after_multirange (PG_FUNCTION_ARGS)
 
bool range_before_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool multirange_before_multirange_internal (TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
 
bool range_after_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
bool range_adjacent_multirange_internal (TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
 
Datum range_adjacent_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_adjacent_range (PG_FUNCTION_ARGS)
 
Datum multirange_adjacent_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_cmp (PG_FUNCTION_ARGS)
 
Datum multirange_lt (PG_FUNCTION_ARGS)
 
Datum multirange_le (PG_FUNCTION_ARGS)
 
Datum multirange_ge (PG_FUNCTION_ARGS)
 
Datum multirange_gt (PG_FUNCTION_ARGS)
 
Datum range_merge_from_multirange (PG_FUNCTION_ARGS)
 
Datum multirange_unnest (PG_FUNCTION_ARGS)
 
Datum hash_multirange (PG_FUNCTION_ARGS)
 
Datum hash_multirange_extended (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ MULTIRANGE_ITEM_GET_OFFLEN

#define MULTIRANGE_ITEM_GET_OFFLEN (   item)    ((item) & 0x7FFFFFFF)

Definition at line 81 of file multirangetypes.c.

Referenced by multirange_get_bounds_offset().

◆ MULTIRANGE_ITEM_HAS_OFF

#define MULTIRANGE_ITEM_HAS_OFF (   item)    ((item) & MULTIRANGE_ITEM_OFF_BIT)

Definition at line 82 of file multirangetypes.c.

Referenced by multirange_get_bounds_offset().

◆ MULTIRANGE_ITEM_OFF_BIT

#define MULTIRANGE_ITEM_OFF_BIT   0x80000000

Definition at line 80 of file multirangetypes.c.

Referenced by write_multirange_data().

◆ MULTIRANGE_ITEM_OFFSET_STRIDE

#define MULTIRANGE_ITEM_OFFSET_STRIDE   4

Definition at line 83 of file multirangetypes.c.

Referenced by write_multirange_data().

◆ MultirangeGetBoundariesPtr

#define MultirangeGetBoundariesPtr (   mr,
  align 
)
Value:
((Pointer) (mr) + \
att_align_nominal(sizeof(MultirangeType) + \
((mr)->rangeCount - 1) * sizeof(uint32) + \
(mr)->rangeCount * sizeof(uint8), (align)))
unsigned char uint8
Definition: c.h:439
char * Pointer
Definition: c.h:418
unsigned int uint32
Definition: c.h:441

Definition at line 75 of file multirangetypes.c.

Referenced by multirange_get_bounds(), multirange_get_range(), and write_multirange_data().

◆ MultirangeGetFlagsPtr

#define MultirangeGetFlagsPtr (   mr)
Value:
((uint8 *) ((Pointer) (mr) + \
sizeof(MultirangeType) + ((mr)->rangeCount - 1) * sizeof(uint32)))
unsigned char uint8
Definition: c.h:439
char * Pointer
Definition: c.h:418
unsigned int uint32
Definition: c.h:441

Definition at line 73 of file multirangetypes.c.

Referenced by hash_multirange(), hash_multirange_extended(), multirange_get_bounds(), multirange_get_range(), and write_multirange_data().

◆ MultirangeGetItemsPtr

#define MultirangeGetItemsPtr (   mr)
Value:
((uint32 *) ((Pointer) (mr) + \
sizeof(MultirangeType)))
char * Pointer
Definition: c.h:418
unsigned int uint32
Definition: c.h:441

Definition at line 71 of file multirangetypes.c.

Referenced by multirange_get_bounds_offset(), and write_multirange_data().

Typedef Documentation

◆ multirange_bsearch_comparison

typedef int(* multirange_bsearch_comparison) (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)

Definition at line 85 of file multirangetypes.c.

◆ MultirangeIOData

Enumeration Type Documentation

◆ MultirangeParseState

Enumerator
MULTIRANGE_BEFORE_RANGE 
MULTIRANGE_IN_RANGE 
MULTIRANGE_IN_RANGE_ESCAPED 
MULTIRANGE_IN_RANGE_QUOTED 
MULTIRANGE_IN_RANGE_QUOTED_ESCAPED 
MULTIRANGE_AFTER_RANGE 
MULTIRANGE_FINISHED 

Definition at line 56 of file multirangetypes.c.

Function Documentation

◆ elem_contained_by_multirange()

Datum elem_contained_by_multirange ( PG_FUNCTION_ARGS  )

Definition at line 1593 of file multirangetypes.c.

References multirange_contains_elem_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_DATUM, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and val.

1594 {
1595  Datum val = PG_GETARG_DATUM(0);
1597  TypeCacheEntry *typcache;
1598 
1599  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1600 
1602 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
bool multirange_contains_elem_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, Datum val)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
long val
Definition: informix.c:664

◆ get_multirange_io_data()

static MultirangeIOData * get_multirange_io_data ( FunctionCallInfo  fcinfo,
Oid  mltrngtypid,
IOFuncSelector  func 
)
static

Definition at line 410 of file multirangetypes.c.

References elog, ereport, errcode(), errmsg(), ERROR, FunctionCallInfoBaseData::flinfo, fmgr_info_cxt(), FmgrInfo::fn_extra, FmgrInfo::fn_mcxt, format_type_be(), get_type_io_data(), IOFunc_receive, lookup_type_cache(), MemoryContextAlloc(), OidIsValid, TypeCacheEntry::rngtype, typalign, MultirangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_MULTIRANGE_INFO, MultirangeIOData::typioparam, and MultirangeIOData::typioproc.

Referenced by multirange_in(), multirange_out(), multirange_recv(), and multirange_send().

411 {
412  MultirangeIOData *cache = (MultirangeIOData *) fcinfo->flinfo->fn_extra;
413 
414  if (cache == NULL || cache->typcache->type_id != mltrngtypid)
415  {
416  Oid typiofunc;
417  int16 typlen;
418  bool typbyval;
419  char typalign;
420  char typdelim;
421 
422  cache = (MultirangeIOData *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
423  sizeof(MultirangeIOData));
425  if (cache->typcache->rngtype == NULL)
426  elog(ERROR, "type %u is not a multirange type", mltrngtypid);
427 
428  /* get_type_io_data does more than we need, but is convenient */
430  func,
431  &typlen,
432  &typbyval,
433  &typalign,
434  &typdelim,
435  &cache->typioparam,
436  &typiofunc);
437 
438  if (!OidIsValid(typiofunc))
439  {
440  /* this could only happen for receive or send */
441  if (func == IOFunc_receive)
442  ereport(ERROR,
443  (errcode(ERRCODE_UNDEFINED_FUNCTION),
444  errmsg("no binary input function available for type %s",
445  format_type_be(cache->typcache->rngtype->type_id))));
446  else
447  ereport(ERROR,
448  (errcode(ERRCODE_UNDEFINED_FUNCTION),
449  errmsg("no binary output function available for type %s",
450  format_type_be(cache->typcache->rngtype->type_id))));
451  }
452  fmgr_info_cxt(typiofunc, &cache->typioproc,
453  fcinfo->flinfo->fn_mcxt);
454 
455  fcinfo->flinfo->fn_extra = (void *) cache;
456  }
457 
458  return cache;
459 }
signed short int16
Definition: c.h:428
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define TYPECACHE_MULTIRANGE_INFO
Definition: typcache.h:152
int errcode(int sqlerrcode)
Definition: elog.c:698
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:710
char typalign
Definition: pg_type.h:176
#define ERROR
Definition: elog.h:46
TypeCacheEntry * typcache
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
#define ereport(elevel,...)
Definition: elog.h:157
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
void * fn_extra
Definition: fmgr.h:64
int errmsg(const char *fmt,...)
Definition: elog.c:909
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
#define elog(elevel,...)
Definition: elog.h:232
void get_type_io_data(Oid typid, IOFuncSelector which_func, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *func)
Definition: lsyscache.c:2272

◆ hash_multirange()

Datum hash_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2721 of file multirangetypes.c.

References DatumGetUInt32, ereport, errcode(), errmsg(), ERROR, FmgrInfo::fn_oid, format_type_be(), FunctionCall1Coll(), TypeCacheEntry::hash_proc_finfo, hash_uint32(), i, lookup_type_cache(), lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeGetFlagsPtr, MultirangeTypeGetOid, OidIsValid, PG_FREE_IF_COPY, PG_GETARG_MULTIRANGE_P, PG_RETURN_UINT32, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, MultirangeType::rangeCount, TypeCacheEntry::rng_collation, TypeCacheEntry::rngelemtype, TypeCacheEntry::rngtype, MultirangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_HASH_PROC_FINFO, upper(), and RangeBound::val.

2722 {
2724  uint32 result = 1;
2725  TypeCacheEntry *typcache,
2726  *scache;
2727  int32 range_count,
2728  i;
2729 
2730  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2731  scache = typcache->rngtype->rngelemtype;
2732  if (!OidIsValid(scache->hash_proc_finfo.fn_oid))
2733  {
2734  scache = lookup_type_cache(scache->type_id,
2736  if (!OidIsValid(scache->hash_proc_finfo.fn_oid))
2737  ereport(ERROR,
2738  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2739  errmsg("could not identify a hash function for type %s",
2740  format_type_be(scache->type_id))));
2741  }
2742 
2743  range_count = mr->rangeCount;
2744  for (i = 0; i < range_count; i++)
2745  {
2746  RangeBound lower,
2747  upper;
2748  uint8 flags = MultirangeGetFlagsPtr(mr)[i];
2749  uint32 lower_hash;
2750  uint32 upper_hash;
2751  uint32 range_hash;
2752 
2753  multirange_get_bounds(typcache->rngtype, mr, i, &lower, &upper);
2754 
2755  if (RANGE_HAS_LBOUND(flags))
2756  lower_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo,
2757  typcache->rngtype->rng_collation,
2758  lower.val));
2759  else
2760  lower_hash = 0;
2761 
2762  if (RANGE_HAS_UBOUND(flags))
2763  upper_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo,
2764  typcache->rngtype->rng_collation,
2765  upper.val));
2766  else
2767  upper_hash = 0;
2768 
2769  /* Merge hashes of flags and bounds */
2770  range_hash = hash_uint32((uint32) flags);
2771  range_hash ^= lower_hash;
2772  range_hash = (range_hash << 1) | (range_hash >> 31);
2773  range_hash ^= upper_hash;
2774 
2775  /*
2776  * Use the same approach as hash_array to combine the individual
2777  * elements' hash values:
2778  */
2779  result = (result << 5) - result + range_hash;
2780  }
2781 
2782  PG_FREE_IF_COPY(mr, 0);
2783 
2784  PG_RETURN_UINT32(result);
2785 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
#define DatumGetUInt32(X)
Definition: postgres.h:530
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define TYPECACHE_HASH_PROC_FINFO
Definition: typcache.h:143
unsigned char uint8
Definition: c.h:439
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
#define OidIsValid(objectId)
Definition: c.h:710
#define PG_RETURN_UINT32(x)
Definition: fmgr.h:355
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
unsigned int uint32
Definition: c.h:441
FmgrInfo hash_proc_finfo
Definition: typcache.h:77
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1128
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:157
#define MultirangeGetFlagsPtr(mr)
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
Oid rng_collation
Definition: typcache.h:99
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define MultirangeTypeGetOid(mr)

◆ hash_multirange_extended()

Datum hash_multirange_extended ( PG_FUNCTION_ARGS  )

Definition at line 2792 of file multirangetypes.c.

References DatumGetInt64, DatumGetUInt64, ereport, errcode(), errmsg(), ERROR, FmgrInfo::fn_oid, format_type_be(), FunctionCall2Coll(), TypeCacheEntry::hash_extended_proc_finfo, hash_uint32_extended(), i, lookup_type_cache(), lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeGetFlagsPtr, MultirangeTypeGetOid, OidIsValid, PG_FREE_IF_COPY, PG_GETARG_DATUM, PG_GETARG_MULTIRANGE_P, PG_RETURN_UINT64, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, MultirangeType::rangeCount, TypeCacheEntry::rng_collation, TypeCacheEntry::rngelemtype, TypeCacheEntry::rngtype, ROTATE_HIGH_AND_LOW_32BITS, MultirangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_HASH_EXTENDED_PROC_FINFO, upper(), and RangeBound::val.

2793 {
2795  Datum seed = PG_GETARG_DATUM(1);
2796  uint64 result = 1;
2797  TypeCacheEntry *typcache,
2798  *scache;
2799  int32 range_count,
2800  i;
2801 
2802  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2803  scache = typcache->rngtype->rngelemtype;
2805  {
2806  scache = lookup_type_cache(scache->type_id,
2809  ereport(ERROR,
2810  (errcode(ERRCODE_UNDEFINED_FUNCTION),
2811  errmsg("could not identify a hash function for type %s",
2812  format_type_be(scache->type_id))));
2813  }
2814 
2815  range_count = mr->rangeCount;
2816  for (i = 0; i < range_count; i++)
2817  {
2818  RangeBound lower,
2819  upper;
2820  uint8 flags = MultirangeGetFlagsPtr(mr)[i];
2821  uint64 lower_hash;
2822  uint64 upper_hash;
2823  uint64 range_hash;
2824 
2825  multirange_get_bounds(typcache->rngtype, mr, i, &lower, &upper);
2826 
2827  if (RANGE_HAS_LBOUND(flags))
2829  typcache->rngtype->rng_collation,
2830  lower.val,
2831  seed));
2832  else
2833  lower_hash = 0;
2834 
2835  if (RANGE_HAS_UBOUND(flags))
2837  typcache->rngtype->rng_collation,
2838  upper.val,
2839  seed));
2840  else
2841  upper_hash = 0;
2842 
2843  /* Merge hashes of flags and bounds */
2844  range_hash = DatumGetUInt64(hash_uint32_extended((uint32) flags,
2845  DatumGetInt64(seed)));
2846  range_hash ^= lower_hash;
2847  range_hash = ROTATE_HIGH_AND_LOW_32BITS(range_hash);
2848  range_hash ^= upper_hash;
2849 
2850  /*
2851  * Use the same approach as hash_array to combine the individual
2852  * elements' hash values:
2853  */
2854  result = (result << 5) - result + range_hash;
2855  }
2856 
2857  PG_FREE_IF_COPY(mr, 0);
2858 
2859  PG_RETURN_UINT64(result);
2860 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define PG_GETARG_MULTIRANGE_P(n)
#define TYPECACHE_HASH_EXTENDED_PROC_FINFO
Definition: typcache.h:151
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
unsigned char uint8
Definition: c.h:439
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1148
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:369
#define OidIsValid(objectId)
Definition: c.h:710
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
#define DatumGetInt64(X)
Definition: postgres.h:651
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
unsigned int uint32
Definition: c.h:441
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
FmgrInfo hash_extended_proc_finfo
Definition: typcache.h:78
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Definition: hashfn.h:18
uintptr_t Datum
Definition: postgres.h:411
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:157
#define DatumGetUInt64(X)
Definition: postgres.h:678
#define MultirangeGetFlagsPtr(mr)
Oid rng_collation
Definition: typcache.h:99
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
int errmsg(const char *fmt,...)
Definition: elog.c:909
int i
#define MultirangeTypeGetOid(mr)
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfn.h:49

◆ make_empty_multirange()

MultirangeType* make_empty_multirange ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp 
)

Definition at line 839 of file multirangetypes.c.

References make_multirange().

Referenced by multirange_intersect().

840 {
841  return make_multirange(mltrngtypoid, rangetyp, 0, NULL);
842 }
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)

◆ make_multirange()

MultirangeType* make_multirange ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp,
int32  range_count,
RangeType **  ranges 
)

Definition at line 640 of file multirangetypes.c.

References multirange_canonicalize(), multirange_size_estimate(), MultirangeType::multirangetypid, palloc0(), MultirangeType::rangeCount, SET_VARSIZE, and write_multirange_data().

Referenced by make_empty_multirange(), multirange_constructor0(), multirange_constructor1(), multirange_constructor2(), multirange_in(), multirange_intersect_internal(), multirange_minus_internal(), multirange_recv(), multirange_union(), multirangesel(), and range_agg_finalfn().

642 {
643  MultirangeType *multirange;
644  Size size;
645 
646  /* Sort and merge input ranges. */
647  range_count = multirange_canonicalize(rangetyp, range_count, ranges);
648 
649  /* Note: zero-fill is required here, just as in heap tuples */
650  size = multirange_size_estimate(rangetyp, range_count, ranges);
651  multirange = palloc0(size);
652  SET_VARSIZE(multirange, size);
653 
654  /* Now fill in the datum */
655  multirange->multirangetypid = mltrngtypoid;
656  multirange->rangeCount = range_count;
657 
658  write_multirange_data(multirange, rangetyp, range_count, ranges);
659 
660  return multirange;
661 }
static void write_multirange_data(MultirangeType *multirange, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
static Size multirange_size_estimate(TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
static int32 multirange_canonicalize(TypeCacheEntry *rangetyp, int32 input_range_count, RangeType **ranges)
void * palloc0(Size size)
Definition: mcxt.c:1093
size_t Size
Definition: c.h:540
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ multirange_adjacent_multirange()

Datum multirange_adjacent_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2469 of file multirangetypes.c.

References bounds_adjacent(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, MultirangeType::rangeCount, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2470 {
2473  TypeCacheEntry *typcache;
2474  int32 range_count1;
2475  int32 range_count2;
2476  RangeBound lower1,
2477  upper1,
2478  lower2,
2479  upper2;
2480 
2481  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
2482  return false;
2483 
2484  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2485 
2486  range_count1 = mr1->rangeCount;
2487  range_count2 = mr2->rangeCount;
2488  multirange_get_bounds(typcache->rngtype, mr1, range_count1 - 1,
2489  &lower1, &upper1);
2490  multirange_get_bounds(typcache->rngtype, mr2, 0,
2491  &lower2, &upper2);
2492  if (bounds_adjacent(typcache->rngtype, upper1, lower2))
2493  PG_RETURN_BOOL(true);
2494 
2495  if (range_count1 > 1)
2496  multirange_get_bounds(typcache->rngtype, mr1, 0,
2497  &lower1, &upper1);
2498  if (range_count2 > 1)
2499  multirange_get_bounds(typcache->rngtype, mr2, range_count2 - 1,
2500  &lower2, &upper2);
2501  if (bounds_adjacent(typcache->rngtype, upper2, lower1))
2502  PG_RETURN_BOOL(true);
2503  PG_RETURN_BOOL(false);
2504 }
#define PG_GETARG_MULTIRANGE_P(n)
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition: rangetypes.c:739
signed int int32
Definition: c.h:429
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_adjacent_range()

Datum multirange_adjacent_range ( PG_FUNCTION_ARGS  )

Definition at line 2454 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_adjacent_multirange_internal(), RangeIsEmpty, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2455 {
2457  RangeType *r = PG_GETARG_RANGE_P(1);
2458  TypeCacheEntry *typcache;
2459 
2460  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2461  return false;
2462 
2463  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2464 
2466 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
#define MultirangeTypeGetOid(mr)

◆ multirange_after_multirange()

Datum multirange_after_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2324 of file multirangetypes.c.

References multirange_before_multirange_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2325 {
2328  TypeCacheEntry *typcache;
2329 
2330  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2331 
2333 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool multirange_before_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)

◆ multirange_after_range()

Datum multirange_after_range ( PG_FUNCTION_ARGS  )

Definition at line 2312 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_before_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2313 {
2315  RangeType *r = PG_GETARG_RANGE_P(1);
2316  TypeCacheEntry *typcache;
2317 
2318  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2319 
2321 }
#define PG_GETARG_MULTIRANGE_P(n)
bool range_before_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_before_multirange()

Datum multirange_before_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2287 of file multirangetypes.c.

References multirange_before_multirange_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2288 {
2291  TypeCacheEntry *typcache;
2292 
2293  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2294 
2296 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool multirange_before_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)

◆ multirange_before_multirange_internal()

bool multirange_before_multirange_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)

Definition at line 2359 of file multirangetypes.c.

References multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_after_multirange(), and multirange_before_multirange().

2362 {
2363  RangeBound lower1,
2364  upper1,
2365  lower2,
2366  upper2;
2367 
2368  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
2369  return false;
2370 
2371  multirange_get_bounds(rangetyp, mr1, mr1->rangeCount - 1,
2372  &lower1, &upper1);
2373  multirange_get_bounds(rangetyp, mr2, 0,
2374  &lower2, &upper2);
2375 
2376  return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2377 }
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define MultirangeIsEmpty(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_before_range()

Datum multirange_before_range ( PG_FUNCTION_ARGS  )

Definition at line 2275 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_after_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2276 {
2278  RangeType *r = PG_GETARG_RANGE_P(1);
2279  TypeCacheEntry *typcache;
2280 
2281  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2282 
2284 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool range_after_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)

◆ multirange_bsearch_match()

static bool multirange_bsearch_match ( TypeCacheEntry typcache,
const MultirangeType mr,
void *  key,
multirange_bsearch_comparison  cmp_func 
)
static

Definition at line 889 of file multirangetypes.c.

References idx(), sort-test::key, lower(), multirange_get_bounds(), MultirangeType::rangeCount, MultirangeIOData::typcache, and upper().

Referenced by multirange_contains_elem_internal(), multirange_contains_range_internal(), and range_overlaps_multirange_internal().

891 {
892  uint32 l,
893  u,
894  idx;
895  int comparison;
896  bool match = false;
897 
898  l = 0;
899  u = mr->rangeCount;
900  while (l < u)
901  {
903  upper;
904 
905  idx = (l + u) / 2;
906  multirange_get_bounds(typcache, mr, idx, &lower, &upper);
907  comparison = (*cmp_func) (typcache, &lower, &upper, key, &match);
908 
909  if (comparison < 0)
910  u = idx;
911  else if (comparison > 0)
912  l = idx + 1;
913  else
914  return match;
915  }
916 
917  return false;
918 }
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:259
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
unsigned int uint32
Definition: c.h:441
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)

◆ multirange_canonicalize()

static int32 multirange_canonicalize ( TypeCacheEntry rangetyp,
int32  input_range_count,
RangeType **  ranges 
)
static

Definition at line 471 of file multirangetypes.c.

References i, qsort_arg(), range_adjacent_internal(), range_before_internal(), range_compare(), range_union_internal(), and RangeIsEmpty.

Referenced by make_multirange().

473 {
474  RangeType *lastRange = NULL;
475  RangeType *currentRange;
476  int32 i;
477  int32 output_range_count = 0;
478 
479  /* Sort the ranges so we can find the ones that overlap/meet. */
480  qsort_arg(ranges, input_range_count, sizeof(RangeType *), range_compare,
481  rangetyp);
482 
483  /* Now merge where possible: */
484  for (i = 0; i < input_range_count; i++)
485  {
486  currentRange = ranges[i];
487  if (RangeIsEmpty(currentRange))
488  continue;
489 
490  if (lastRange == NULL)
491  {
492  ranges[output_range_count++] = lastRange = currentRange;
493  continue;
494  }
495 
496  /*
497  * range_adjacent_internal gives true if *either* A meets B or B meets
498  * A, which is not quite want we want, but we rely on the sorting
499  * above to rule out B meets A ever happening.
500  */
501  if (range_adjacent_internal(rangetyp, lastRange, currentRange))
502  {
503  /* The two ranges touch (without overlap), so merge them: */
504  ranges[output_range_count - 1] = lastRange =
505  range_union_internal(rangetyp, lastRange, currentRange, false);
506  }
507  else if (range_before_internal(rangetyp, lastRange, currentRange))
508  {
509  /* There's a gap, so make a new entry: */
510  lastRange = ranges[output_range_count] = currentRange;
511  output_range_count++;
512  }
513  else
514  {
515  /* They must overlap, so merge them: */
516  ranges[output_range_count - 1] = lastRange =
517  range_union_internal(rangetyp, lastRange, currentRange, true);
518  }
519  }
520 
521  return output_range_count;
522 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
signed int int32
Definition: c.h:429
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
Definition: rangetypes.c:1034
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:646
int i
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:780
int range_compare(const void *key1, const void *key2, void *arg)
Definition: rangetypes.c:2037

◆ multirange_cmp()

Datum multirange_cmp ( PG_FUNCTION_ARGS  )

Definition at line 2510 of file multirangetypes.c.

References cmp(), elog, ERROR, i, Max, multirange_get_bounds(), multirange_get_typcache(), MultirangeTypeGetOid, PG_FREE_IF_COPY, PG_GETARG_MULTIRANGE_P, PG_RETURN_INT32, range_cmp_bounds(), MultirangeType::rangeCount, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

Referenced by multirange_ge(), multirange_gt(), multirange_le(), and multirange_lt().

2511 {
2514  int32 range_count_1;
2515  int32 range_count_2;
2516  int32 range_count_max;
2517  int32 i;
2518  TypeCacheEntry *typcache;
2519  int cmp = 0; /* If both are empty we'll use this. */
2520 
2521  /* Different types should be prevented by ANYMULTIRANGE matching rules */
2522  if (MultirangeTypeGetOid(mr1) != MultirangeTypeGetOid(mr2))
2523  elog(ERROR, "multirange types do not match");
2524 
2525  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2526 
2527  range_count_1 = mr1->rangeCount;
2528  range_count_2 = mr2->rangeCount;
2529 
2530  /* Loop over source data */
2531  range_count_max = Max(range_count_1, range_count_2);
2532  for (i = 0; i < range_count_max; i++)
2533  {
2534  RangeBound lower1,
2535  upper1,
2536  lower2,
2537  upper2;
2538 
2539  /*
2540  * If one multirange is shorter, it's as if it had empty ranges at the
2541  * end to extend its length. An empty range compares earlier than any
2542  * other range, so the shorter multirange comes before the longer.
2543  * This is the same behavior as in other types, e.g. in strings 'aaa'
2544  * < 'aaaaaa'.
2545  */
2546  if (i >= range_count_1)
2547  {
2548  cmp = -1;
2549  break;
2550  }
2551  if (i >= range_count_2)
2552  {
2553  cmp = 1;
2554  break;
2555  }
2556 
2557  multirange_get_bounds(typcache->rngtype, mr1, i, &lower1, &upper1);
2558  multirange_get_bounds(typcache->rngtype, mr2, i, &lower2, &upper2);
2559 
2560  cmp = range_cmp_bounds(typcache->rngtype, &lower1, &lower2);
2561  if (cmp == 0)
2562  cmp = range_cmp_bounds(typcache->rngtype, &upper1, &upper2);
2563  if (cmp != 0)
2564  break;
2565  }
2566 
2567  PG_FREE_IF_COPY(mr1, 0);
2568  PG_FREE_IF_COPY(mr2, 1);
2569 
2570  PG_RETURN_INT32(cmp);
2571 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Max(x, y)
Definition: c.h:980
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define elog(elevel,...)
Definition: elog.h:232
int i
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ multirange_constructor0()

Datum multirange_constructor0 ( PG_FUNCTION_ARGS  )

Definition at line 1050 of file multirangetypes.c.

References elog, ERROR, get_fn_expr_rettype(), make_multirange(), multirange_get_typcache(), PG_NARGS, PG_RETURN_MULTIRANGE_P, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1051 {
1052  Oid mltrngtypid;
1053  TypeCacheEntry *typcache;
1054  TypeCacheEntry *rangetyp;
1055 
1056  /* This should always be called without arguments */
1057  if (PG_NARGS() != 0)
1058  elog(ERROR,
1059  "niladic multirange constructor must not receive arguments");
1060 
1061  mltrngtypid = get_fn_expr_rettype(fcinfo->flinfo);
1062  typcache = multirange_get_typcache(fcinfo, mltrngtypid);
1063  rangetyp = typcache->rngtype;
1064 
1065  PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 0, NULL));
1066 }
#define PG_RETURN_MULTIRANGE_P(x)
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:46
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1778
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define PG_NARGS()
Definition: fmgr.h:203
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define elog(elevel,...)
Definition: elog.h:232

◆ multirange_constructor1()

Datum multirange_constructor1 ( PG_FUNCTION_ARGS  )

Definition at line 1014 of file multirangetypes.c.

References elog, ERROR, get_fn_expr_rettype(), make_multirange(), multirange_get_typcache(), PG_ARGISNULL, PG_GETARG_RANGE_P, PG_RETURN_MULTIRANGE_P, range(), RangeTypeGetOid, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and TypeCacheEntry::type_id.

1015 {
1016  Oid mltrngtypid = get_fn_expr_rettype(fcinfo->flinfo);
1017  Oid rngtypid;
1018  TypeCacheEntry *typcache;
1019  TypeCacheEntry *rangetyp;
1020  RangeType *range;
1021 
1022  typcache = multirange_get_typcache(fcinfo, mltrngtypid);
1023  rangetyp = typcache->rngtype;
1024 
1025  /*
1026  * This check should be guaranteed by our signature, but let's do it just
1027  * in case.
1028  */
1029 
1030  if (PG_ARGISNULL(0))
1031  elog(ERROR,
1032  "multirange values cannot contain null members");
1033 
1034  range = PG_GETARG_RANGE_P(0);
1035 
1036  /* Make sure the range type matches. */
1037  rngtypid = RangeTypeGetOid(range);
1038  if (rngtypid != rangetyp->type_id)
1039  elog(ERROR, "type %u does not match constructor type", rngtypid);
1040 
1041  PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 1, &range));
1042 }
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_MULTIRANGE_P(x)
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:46
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1778
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define elog(elevel,...)
Definition: elog.h:232

◆ multirange_constructor2()

Datum multirange_constructor2 ( PG_FUNCTION_ARGS  )

Definition at line 932 of file multirangetypes.c.

References ARR_ELEMTYPE, ARR_NDIM, DatumGetRangeTypeP, deconstruct_array(), elog, ereport, errcode(), errmsg(), ERROR, get_fn_expr_rettype(), i, make_multirange(), multirange_get_typcache(), palloc0(), PG_ARGISNULL, PG_GETARG_ARRAYTYPE_P, PG_NARGS, PG_RETURN_MULTIRANGE_P, TypeCacheEntry::rngtype, TypeCacheEntry::typalign, TypeCacheEntry::typbyval, MultirangeIOData::typcache, TypeCacheEntry::type_id, and TypeCacheEntry::typlen.

933 {
934  Oid mltrngtypid = get_fn_expr_rettype(fcinfo->flinfo);
935  Oid rngtypid;
936  TypeCacheEntry *typcache;
937  TypeCacheEntry *rangetyp;
938  ArrayType *rangeArray;
939  int range_count;
940  Datum *elements;
941  bool *nulls;
942  RangeType **ranges;
943  int dims;
944  int i;
945 
946  typcache = multirange_get_typcache(fcinfo, mltrngtypid);
947  rangetyp = typcache->rngtype;
948 
949  /*
950  * A no-arg invocation should call multirange_constructor0 instead, but
951  * returning an empty range is what that does.
952  */
953 
954  if (PG_NARGS() == 0)
955  PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, 0, NULL));
956 
957  /*
958  * This check should be guaranteed by our signature, but let's do it just
959  * in case.
960  */
961 
962  if (PG_ARGISNULL(0))
963  elog(ERROR,
964  "multirange values cannot contain null members");
965 
966  rangeArray = PG_GETARG_ARRAYTYPE_P(0);
967 
968  dims = ARR_NDIM(rangeArray);
969  if (dims > 1)
970  ereport(ERROR,
971  (errcode(ERRCODE_CARDINALITY_VIOLATION),
972  errmsg("multiranges cannot be constructed from multidimensional arrays")));
973 
974  rngtypid = ARR_ELEMTYPE(rangeArray);
975  if (rngtypid != rangetyp->type_id)
976  elog(ERROR, "type %u does not match constructor type", rngtypid);
977 
978  /*
979  * Be careful: we can still be called with zero ranges, like this:
980  * `int4multirange(variadic '{}'::int4range[])
981  */
982  if (dims == 0)
983  {
984  range_count = 0;
985  ranges = NULL;
986  }
987  else
988  {
989  deconstruct_array(rangeArray, rngtypid, rangetyp->typlen, rangetyp->typbyval,
990  rangetyp->typalign, &elements, &nulls, &range_count);
991 
992  ranges = palloc0(range_count * sizeof(RangeType *));
993  for (i = 0; i < range_count; i++)
994  {
995  if (nulls[i])
996  ereport(ERROR,
997  (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
998  errmsg("multirange values cannot contain null members")));
999 
1000  /* make_multirange will do its own copy */
1001  ranges[i] = DatumGetRangeTypeP(elements[i]);
1002  }
1003  }
1004 
1005  PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypid, rangetyp, range_count, ranges));
1006 }
#define PG_RETURN_MULTIRANGE_P(x)
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
int16 typlen
Definition: typcache.h:39
bool typbyval
Definition: typcache.h:40
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:256
#define ERROR
Definition: elog.h:46
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void * palloc0(Size size)
Definition: mcxt.c:1093
uintptr_t Datum
Definition: postgres.h:411
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1778
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:73
#define PG_NARGS()
Definition: fmgr.h:203
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define ARR_NDIM(a)
Definition: array.h:283
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
Definition: arrayfuncs.c:3491
char typalign
Definition: typcache.h:41
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int i
#define ARR_ELEMTYPE(a)
Definition: array.h:285

◆ multirange_contained_by_multirange()

Datum multirange_contained_by_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2186 of file multirangetypes.c.

References multirange_contains_multirange_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2187 {
2190  TypeCacheEntry *typcache;
2191 
2192  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2193 
2195 }
#define PG_GETARG_MULTIRANGE_P(n)
bool multirange_contains_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_contained_by_range()

Datum multirange_contained_by_range ( PG_FUNCTION_ARGS  )

Definition at line 1693 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contains_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1694 {
1696  RangeType *r = PG_GETARG_RANGE_P(1);
1697  TypeCacheEntry *typcache;
1698 
1699  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1700 
1702 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
bool range_contains_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_contains_elem()

Datum multirange_contains_elem ( PG_FUNCTION_ARGS  )

Definition at line 1580 of file multirangetypes.c.

References multirange_contains_elem_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_DATUM, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and val.

1581 {
1583  Datum val = PG_GETARG_DATUM(1);
1584  TypeCacheEntry *typcache;
1585 
1586  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1587 
1589 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
bool multirange_contains_elem_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, Datum val)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
long val
Definition: informix.c:664

◆ multirange_contains_elem_internal()

bool multirange_contains_elem_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr,
Datum  val 
)

Definition at line 1642 of file multirangetypes.c.

References multirange_bsearch_match(), multirange_elem_bsearch_comparison(), and MultirangeIsEmpty.

Referenced by elem_contained_by_multirange(), and multirange_contains_elem().

1644 {
1645  if (MultirangeIsEmpty(mr))
1646  return false;
1647 
1648  return multirange_bsearch_match(rangetyp, mr, &val,
1650 }
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
#define MultirangeIsEmpty(mr)
static int multirange_elem_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
long val
Definition: informix.c:664

◆ multirange_contains_multirange()

Datum multirange_contains_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2173 of file multirangetypes.c.

References multirange_contains_multirange_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2174 {
2177  TypeCacheEntry *typcache;
2178 
2179  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2180 
2182 }
#define PG_GETARG_MULTIRANGE_P(n)
bool multirange_contains_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_contains_multirange_internal()

bool multirange_contains_multirange_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)

Definition at line 2201 of file multirangetypes.c.

References multirange_get_bounds(), range_bounds_contains(), range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_contained_by_multirange(), and multirange_contains_multirange().

2204 {
2205  int32 range_count1 = mr1->rangeCount;
2206  int32 range_count2 = mr2->rangeCount;
2207  int i1,
2208  i2;
2209  RangeBound lower1,
2210  upper1,
2211  lower2,
2212  upper2;
2213 
2214  /*
2215  * We follow the same logic for empties as ranges: - an empty multirange
2216  * contains an empty range/multirange. - an empty multirange can't contain
2217  * any other range/multirange. - an empty multirange is contained by any
2218  * other range/multirange.
2219  */
2220 
2221  if (range_count2 == 0)
2222  return true;
2223  if (range_count1 == 0)
2224  return false;
2225 
2226  /*
2227  * Every range in mr2 must be contained by some range in mr1. To avoid
2228  * O(n^2) we walk through both ranges in tandem.
2229  */
2230  i1 = 0;
2231  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
2232  for (i2 = 0; i2 < range_count2; i2++)
2233  {
2234  multirange_get_bounds(rangetyp, mr2, i2, &lower2, &upper2);
2235 
2236  /* Discard r1s while r1 << r2 */
2237  while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0)
2238  {
2239  if (++i1 >= range_count1)
2240  return false;
2241  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
2242  }
2243 
2244  /*
2245  * If r1 @> r2, go to the next r2, otherwise return false (since every
2246  * r1[n] and r1[n+1] must have a gap). Note this will give weird
2247  * answers if you don't canonicalize, e.g. with a custom
2248  * int2multirange {[1,1], [2,2]} there is a "gap". But that is
2249  * consistent with other range operators, e.g. '[1,1]'::int2range -|-
2250  * '[2,2]'::int2range is false.
2251  */
2252  if (!range_bounds_contains(rangetyp, &lower1, &upper1,
2253  &lower2, &upper2))
2254  return false;
2255  }
2256 
2257  /* All ranges in mr2 are satisfied */
2258  return true;
2259 }
signed int int32
Definition: c.h:429
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_contains_range()

Datum multirange_contains_range ( PG_FUNCTION_ARGS  )

Definition at line 1656 of file multirangetypes.c.

References multirange_contains_range_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1657 {
1659  RangeType *r = PG_GETARG_RANGE_P(1);
1660  TypeCacheEntry *typcache;
1661 
1662  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1663 
1665 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool multirange_contains_range_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, const RangeType *r)
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_contains_range_internal()

bool multirange_contains_range_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr,
const RangeType r 
)

Definition at line 1736 of file multirangetypes.c.

References Assert, multirange_bsearch_match(), multirange_range_contains_bsearch_comparison(), MultirangeIsEmpty, range_deserialize(), and RangeIsEmpty.

Referenced by multirange_contains_range(), range_contained_by_multirange(), and range_gist_consistent_leaf_multirange().

1739 {
1740  RangeBound bounds[2];
1741  bool empty;
1742 
1743  /*
1744  * Every multirange contains an infinite number of empty ranges, even an
1745  * empty one.
1746  */
1747  if (RangeIsEmpty(r))
1748  return true;
1749 
1750  if (MultirangeIsEmpty(mr))
1751  return false;
1752 
1753  range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1754  Assert(!empty);
1755 
1756  return multirange_bsearch_match(rangetyp, mr, bounds,
1758 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
static int multirange_range_contains_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)

◆ multirange_deserialize()

void multirange_deserialize ( TypeCacheEntry rangetyp,
const MultirangeType multirange,
int32 range_count,
RangeType ***  ranges 
)

Definition at line 817 of file multirangetypes.c.

References i, multirange_get_range(), palloc(), and MultirangeType::rangeCount.

Referenced by multirange_intersect(), multirange_intersect_agg_transfn(), multirange_minus(), multirange_out(), multirange_send(), and multirange_union().

820 {
821  *range_count = multirange->rangeCount;
822 
823  /* Convert each ShortRangeType into a RangeType */
824  if (*range_count > 0)
825  {
826  int i;
827 
828  *ranges = palloc(*range_count * sizeof(RangeType *));
829  for (i = 0; i < *range_count; i++)
830  (*ranges)[i] = multirange_get_range(rangetyp, multirange, i);
831  }
832  else
833  {
834  *ranges = NULL;
835  }
836 }
RangeType * multirange_get_range(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
void * palloc(Size size)
Definition: mcxt.c:1062
int i

◆ multirange_elem_bsearch_comparison()

static int multirange_elem_bsearch_comparison ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
void *  key,
bool match 
)
static

Definition at line 1609 of file multirangetypes.c.

References cmp(), DatumGetInt32, FunctionCall2Coll(), RangeBound::inclusive, RangeBound::infinite, TypeCacheEntry::rng_cmp_proc_finfo, TypeCacheEntry::rng_collation, RangeBound::val, and val.

Referenced by multirange_contains_elem_internal().

1612 {
1613  Datum val = *((Datum *) key);
1614  int cmp;
1615 
1616  if (!lower->infinite)
1617  {
1619  typcache->rng_collation,
1620  lower->val, val));
1621  if (cmp > 0 || (cmp == 0 && !lower->inclusive))
1622  return -1;
1623  }
1624 
1625  if (!upper->infinite)
1626  {
1628  typcache->rng_collation,
1629  upper->val, val));
1630  if (cmp < 0 || (cmp == 0 && !upper->inclusive))
1631  return 1;
1632  }
1633 
1634  *match = true;
1635  return 0;
1636 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:100
#define DatumGetInt32(X)
Definition: postgres.h:516
Datum val
Definition: rangetypes.h:64
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1148
bool inclusive
Definition: rangetypes.h:66
uintptr_t Datum
Definition: postgres.h:411
bool infinite
Definition: rangetypes.h:65
Oid rng_collation
Definition: typcache.h:99
long val
Definition: informix.c:664
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ multirange_empty()

Datum multirange_empty ( PG_FUNCTION_ARGS  )

Definition at line 1491 of file multirangetypes.c.

References MultirangeIsEmpty, PG_GETARG_MULTIRANGE_P, and PG_RETURN_BOOL.

1492 {
1494 
1496 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define MultirangeIsEmpty(mr)

◆ multirange_eq()

Datum multirange_eq ( PG_FUNCTION_ARGS  )

Definition at line 1836 of file multirangetypes.c.

References multirange_eq_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1837 {
1840  TypeCacheEntry *typcache;
1841 
1842  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
1843 
1844  PG_RETURN_BOOL(multirange_eq_internal(typcache->rngtype, mr1, mr2));
1845 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool multirange_eq_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_eq_internal()

bool multirange_eq_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)

Definition at line 1799 of file multirangetypes.c.

References elog, ERROR, i, multirange_get_bounds(), MultirangeTypeGetOid, range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_eq(), and multirange_ne_internal().

1802 {
1803  int32 range_count_1;
1804  int32 range_count_2;
1805  int32 i;
1806  RangeBound lower1,
1807  upper1,
1808  lower2,
1809  upper2;
1810 
1811  /* Different types should be prevented by ANYMULTIRANGE matching rules */
1812  if (MultirangeTypeGetOid(mr1) != MultirangeTypeGetOid(mr2))
1813  elog(ERROR, "multirange types do not match");
1814 
1815  range_count_1 = mr1->rangeCount;
1816  range_count_2 = mr2->rangeCount;
1817 
1818  if (range_count_1 != range_count_2)
1819  return false;
1820 
1821  for (i = 0; i < range_count_1; i++)
1822  {
1823  multirange_get_bounds(rangetyp, mr1, i, &lower1, &upper1);
1824  multirange_get_bounds(rangetyp, mr2, i, &lower2, &upper2);
1825 
1826  if (range_cmp_bounds(rangetyp, &lower1, &lower2) != 0 ||
1827  range_cmp_bounds(rangetyp, &upper1, &upper2) != 0)
1828  return false;
1829  }
1830 
1831  return true;
1832 }
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define elog(elevel,...)
Definition: elog.h:232
int i
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_ge()

Datum multirange_ge ( PG_FUNCTION_ARGS  )

Definition at line 2591 of file multirangetypes.c.

References cmp(), multirange_cmp(), and PG_RETURN_BOOL.

2592 {
2593  int cmp = multirange_cmp(fcinfo);
2594 
2595  PG_RETURN_BOOL(cmp >= 0);
2596 }
Datum multirange_cmp(PG_FUNCTION_ARGS)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ multirange_get_bounds()

void multirange_get_bounds ( TypeCacheEntry rangetyp,
const MultirangeType multirange,
uint32  i,
RangeBound lower,
RangeBound upper 
)

Definition at line 735 of file multirangetypes.c.

References Assert, att_addlength_pointer, att_align_pointer, fetch_att, i, RangeBound::inclusive, RangeBound::infinite, RangeBound::lower, multirange_get_bounds_offset(), MultirangeGetBoundariesPtr, MultirangeGetFlagsPtr, RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, TypeCacheEntry::rngelemtype, TypeCacheEntry::typalign, typalign, TypeCacheEntry::typbyval, TypeCacheEntry::typlen, and RangeBound::val.

Referenced by calc_hist_selectivity(), compute_range_stats(), hash_multirange(), hash_multirange_extended(), multirange_adjacent_multirange(), multirange_before_multirange_internal(), multirange_bsearch_match(), multirange_cmp(), multirange_contains_multirange_internal(), multirange_eq_internal(), multirange_get_union_range(), multirange_lower(), multirange_lower_inc(), multirange_lower_inf(), multirange_overlaps_multirange_internal(), multirange_overleft_multirange(), multirange_overleft_range(), multirange_overright_multirange(), multirange_overright_range(), multirange_union_range_equal(), multirange_upper(), multirange_upper_inc(), multirange_upper_inf(), range_adjacent_multirange_internal(), range_after_multirange_internal(), range_before_multirange_internal(), range_contains_multirange_internal(), range_merge_from_multirange(), range_overleft_multirange_internal(), and range_overright_multirange_internal().

738 {
739  uint32 offset;
740  uint8 flags;
741  Pointer ptr;
742  int16 typlen = rangetyp->rngelemtype->typlen;
743  char typalign = rangetyp->rngelemtype->typalign;
744  bool typbyval = rangetyp->rngelemtype->typbyval;
745  Datum lbound;
746  Datum ubound;
747 
748  Assert(i < multirange->rangeCount);
749 
750  offset = multirange_get_bounds_offset(multirange, i);
751  flags = MultirangeGetFlagsPtr(multirange)[i];
752  ptr = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
753 
754  /* multirange can't contain empty ranges */
755  Assert((flags & RANGE_EMPTY) == 0);
756 
757  /* fetch lower bound, if any */
758  if (RANGE_HAS_LBOUND(flags))
759  {
760  /* att_align_pointer cannot be necessary here */
761  lbound = fetch_att(ptr, typbyval, typlen);
762  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
763  }
764  else
765  lbound = (Datum) 0;
766 
767  /* fetch upper bound, if any */
768  if (RANGE_HAS_UBOUND(flags))
769  {
770  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
771  ubound = fetch_att(ptr, typbyval, typlen);
772  /* no need for att_addlength_pointer */
773  }
774  else
775  ubound = (Datum) 0;
776 
777  /* emit results */
778  lower->val = lbound;
779  lower->infinite = (flags & RANGE_LB_INF) != 0;
780  lower->inclusive = (flags & RANGE_LB_INC) != 0;
781  lower->lower = true;
782 
783  upper->val = ubound;
784  upper->infinite = (flags & RANGE_UB_INF) != 0;
785  upper->inclusive = (flags & RANGE_UB_INC) != 0;
786  upper->lower = false;
787 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
signed short int16
Definition: c.h:428
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define RANGE_EMPTY
Definition: rangetypes.h:38
unsigned char uint8
Definition: c.h:439
Datum val
Definition: rangetypes.h:64
int16 typlen
Definition: typcache.h:39
#define RANGE_LB_INF
Definition: rangetypes.h:41
bool typbyval
Definition: typcache.h:40
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
bool inclusive
Definition: rangetypes.h:66
#define RANGE_UB_INC
Definition: rangetypes.h:40
unsigned int uint32
Definition: c.h:441
#define MultirangeGetBoundariesPtr(mr, align)
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
bool lower
Definition: rangetypes.h:67
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
uintptr_t Datum
Definition: postgres.h:411
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:126
static uint32 multirange_get_bounds_offset(const MultirangeType *multirange, int32 i)
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define MultirangeGetFlagsPtr(mr)
#define Assert(condition)
Definition: c.h:804
bool infinite
Definition: rangetypes.h:65
#define RANGE_UB_INF
Definition: rangetypes.h:42
char typalign
Definition: typcache.h:41
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:75
int i

◆ multirange_get_bounds_offset()

static uint32 multirange_get_bounds_offset ( const MultirangeType multirange,
int32  i 
)
static

Definition at line 667 of file multirangetypes.c.

References MULTIRANGE_ITEM_GET_OFFLEN, MULTIRANGE_ITEM_HAS_OFF, and MultirangeGetItemsPtr.

Referenced by multirange_get_bounds(), and multirange_get_range().

668 {
669  uint32 *items = MultirangeGetItemsPtr(multirange);
670  uint32 offset = 0;
671 
672  /*
673  * Summarize lengths till we meet an offset.
674  */
675  while (i > 0)
676  {
677  offset += MULTIRANGE_ITEM_GET_OFFLEN(items[i - 1]);
678  if (MULTIRANGE_ITEM_HAS_OFF(items[i - 1]))
679  break;
680  i--;
681  }
682  return offset;
683 }
#define MULTIRANGE_ITEM_GET_OFFLEN(item)
#define MultirangeGetItemsPtr(mr)
unsigned int uint32
Definition: c.h:441
#define MULTIRANGE_ITEM_HAS_OFF(item)
int i

◆ multirange_get_range()

RangeType* multirange_get_range ( TypeCacheEntry rangetyp,
const MultirangeType multirange,
int  i 
)

Definition at line 689 of file multirangetypes.c.

References Assert, att_addlength_pointer, i, multirange_get_bounds_offset(), MultirangeGetBoundariesPtr, MultirangeGetFlagsPtr, palloc0(), range(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeType::rangetypid, TypeCacheEntry::rngelemtype, SET_VARSIZE, TypeCacheEntry::typalign, typalign, TypeCacheEntry::type_id, and TypeCacheEntry::typlen.

Referenced by multirange_deserialize(), multirange_unnest(), and range_merge_from_multirange().

691 {
692  uint32 offset;
693  uint8 flags;
694  Pointer begin,
695  ptr;
696  int16 typlen = rangetyp->rngelemtype->typlen;
697  char typalign = rangetyp->rngelemtype->typalign;
698  uint32 len;
699  RangeType *range;
700 
701  Assert(i < multirange->rangeCount);
702 
703  offset = multirange_get_bounds_offset(multirange, i);
704  flags = MultirangeGetFlagsPtr(multirange)[i];
705  ptr = begin = MultirangeGetBoundariesPtr(multirange, typalign) + offset;
706 
707  /*
708  * Calculate the size of bound values. In principle, we could get offset
709  * of the next range bound values and calculate accordingly. But range
710  * bound values are aligned, so we have to walk the values to get the
711  * exact size.
712  */
713  if (RANGE_HAS_LBOUND(flags))
714  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
715  if (RANGE_HAS_UBOUND(flags))
716  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
717  len = (ptr - begin) + sizeof(RangeType) + sizeof(uint8);
718 
719  range = palloc0(len);
720  SET_VARSIZE(range, len);
721  range->rangetypid = rangetyp->type_id;
722 
723  memcpy(range + 1, begin, ptr - begin);
724  *((uint8 *) (range + 1) + (ptr - begin)) = flags;
725 
726  return range;
727 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
signed short int16
Definition: c.h:428
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
unsigned char uint8
Definition: c.h:439
int16 typlen
Definition: typcache.h:39
Oid rangetypid
Definition: rangetypes.h:28
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
unsigned int uint32
Definition: c.h:441
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
#define MultirangeGetBoundariesPtr(mr, align)
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:176
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
void * palloc0(Size size)
Definition: mcxt.c:1093
static uint32 multirange_get_bounds_offset(const MultirangeType *multirange, int32 i)
#define MultirangeGetFlagsPtr(mr)
#define Assert(condition)
Definition: c.h:804
char typalign
Definition: typcache.h:41
int i
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342

◆ multirange_get_typcache()

TypeCacheEntry* multirange_get_typcache ( FunctionCallInfo  fcinfo,
Oid  mltrngtypid 
)

Definition at line 542 of file multirangetypes.c.

References elog, ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngtype, MultirangeIOData::typcache, TypeCacheEntry::type_id, and TYPECACHE_MULTIRANGE_INFO.

Referenced by elem_contained_by_multirange(), hash_multirange(), hash_multirange_extended(), multirange_adjacent_multirange(), multirange_adjacent_range(), multirange_after_multirange(), multirange_after_range(), multirange_before_multirange(), multirange_before_range(), multirange_cmp(), multirange_constructor0(), multirange_constructor1(), multirange_constructor2(), multirange_contained_by_multirange(), multirange_contained_by_range(), multirange_contains_elem(), multirange_contains_multirange(), multirange_contains_range(), multirange_eq(), multirange_gist_compress(), multirange_intersect(), multirange_intersect_agg_transfn(), multirange_lower(), multirange_lower_inc(), multirange_lower_inf(), multirange_minus(), multirange_ne(), multirange_overlaps_multirange(), multirange_overlaps_range(), multirange_overleft_multirange(), multirange_overleft_range(), multirange_overright_multirange(), multirange_overright_range(), multirange_typanalyze(), multirange_union(), multirange_upper(), multirange_upper_inc(), multirange_upper_inf(), multirangesel(), range_adjacent_multirange(), range_after_multirange(), range_agg_finalfn(), range_before_multirange(), range_contained_by_multirange(), range_contains_multirange(), range_merge_from_multirange(), range_overlaps_multirange(), range_overleft_multirange(), and range_overright_multirange().

543 {
544  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
545 
546  if (typcache == NULL ||
547  typcache->type_id != mltrngtypid)
548  {
549  typcache = lookup_type_cache(mltrngtypid, TYPECACHE_MULTIRANGE_INFO);
550  if (typcache->rngtype == NULL)
551  elog(ERROR, "type %u is not a multirange type", mltrngtypid);
552  fcinfo->flinfo->fn_extra = (void *) typcache;
553  }
554 
555  return typcache;
556 }
#define TYPECACHE_MULTIRANGE_INFO
Definition: typcache.h:152
#define ERROR
Definition: elog.h:46
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
void * fn_extra
Definition: fmgr.h:64
#define elog(elevel,...)
Definition: elog.h:232

◆ multirange_get_union_range()

RangeType* multirange_get_union_range ( TypeCacheEntry rangetyp,
const MultirangeType mr 
)

Definition at line 793 of file multirangetypes.c.

References lower(), make_empty_range(), make_range(), multirange_get_bounds(), MultirangeIsEmpty, MultirangeType::rangeCount, and upper().

Referenced by multirange_gist_compress().

795 {
797  upper,
798  tmp;
799 
800  if (MultirangeIsEmpty(mr))
801  return make_empty_range(rangetyp);
802 
803  multirange_get_bounds(rangetyp, mr, 0, &lower, &tmp);
804  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper);
805 
806  return make_range(rangetyp, &lower, &upper, false);
807 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define MultirangeIsEmpty(mr)

◆ multirange_gt()

Datum multirange_gt ( PG_FUNCTION_ARGS  )

Definition at line 2599 of file multirangetypes.c.

References cmp(), multirange_cmp(), and PG_RETURN_BOOL.

2600 {
2601  int cmp = multirange_cmp(fcinfo);
2602 
2603  PG_RETURN_BOOL(cmp > 0);
2604 }
Datum multirange_cmp(PG_FUNCTION_ARGS)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ multirange_in()

Datum multirange_in ( PG_FUNCTION_ARGS  )

Definition at line 117 of file multirangetypes.c.

References DatumGetRangeTypeP, elog, ereport, errcode(), errdetail(), errmsg(), ERROR, get_multirange_io_data(), InputFunctionCall(), IOFunc_input, make_multirange(), MULTIRANGE_AFTER_RANGE, MULTIRANGE_BEFORE_RANGE, MULTIRANGE_FINISHED, MULTIRANGE_IN_RANGE, MULTIRANGE_IN_RANGE_ESCAPED, MULTIRANGE_IN_RANGE_QUOTED, MULTIRANGE_IN_RANGE_QUOTED_ESCAPED, palloc(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_MULTIRANGE_P, pg_strncasecmp(), pnstrdup(), range(), RANGE_EMPTY_LITERAL, RangeIsEmpty, repalloc(), TypeCacheEntry::rngtype, MultirangeIOData::typcache, MultirangeIOData::typioparam, and MultirangeIOData::typioproc.

118 {
119  char *input_str = PG_GETARG_CSTRING(0);
120  Oid mltrngtypoid = PG_GETARG_OID(1);
121  Oid typmod = PG_GETARG_INT32(2);
122  TypeCacheEntry *rangetyp;
123  int32 ranges_seen = 0;
124  int32 range_count = 0;
125  int32 range_capacity = 8;
126  RangeType *range;
127  RangeType **ranges = palloc(range_capacity * sizeof(RangeType *));
128  MultirangeIOData *cache;
129  MultirangeType *ret;
130  MultirangeParseState parse_state;
131  const char *ptr = input_str;
132  const char *range_str_begin = NULL;
133  int32 range_str_len;
134  char *range_str;
135 
136  cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_input);
137  rangetyp = cache->typcache->rngtype;
138 
139  /* consume whitespace */
140  while (*ptr != '\0' && isspace((unsigned char) *ptr))
141  ptr++;
142 
143  if (*ptr == '{')
144  ptr++;
145  else
146  ereport(ERROR,
147  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
148  errmsg("malformed multirange literal: \"%s\"",
149  input_str),
150  errdetail("Missing left brace.")));
151 
152  /* consume ranges */
153  parse_state = MULTIRANGE_BEFORE_RANGE;
154  for (; parse_state != MULTIRANGE_FINISHED; ptr++)
155  {
156  char ch = *ptr;
157 
158  if (ch == '\0')
159  ereport(ERROR,
160  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
161  errmsg("malformed multirange literal: \"%s\"",
162  input_str),
163  errdetail("Unexpected end of input.")));
164 
165  /* skip whitespace */
166  if (isspace((unsigned char) ch))
167  continue;
168 
169  switch (parse_state)
170  {
172  if (ch == '[' || ch == '(')
173  {
174  range_str_begin = ptr;
175  parse_state = MULTIRANGE_IN_RANGE;
176  }
177  else if (ch == '}' && ranges_seen == 0)
178  parse_state = MULTIRANGE_FINISHED;
179  else if (pg_strncasecmp(ptr, RANGE_EMPTY_LITERAL,
180  strlen(RANGE_EMPTY_LITERAL)) == 0)
181  {
182  ranges_seen++;
183  /* nothing to do with an empty range */
184  ptr += strlen(RANGE_EMPTY_LITERAL) - 1;
185  parse_state = MULTIRANGE_AFTER_RANGE;
186  }
187  else
188  ereport(ERROR,
189  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
190  errmsg("malformed multirange literal: \"%s\"",
191  input_str),
192  errdetail("Expected range start.")));
193  break;
194  case MULTIRANGE_IN_RANGE:
195  if (ch == ']' || ch == ')')
196  {
197  range_str_len = ptr - range_str_begin + 1;
198  range_str = pnstrdup(range_str_begin, range_str_len);
199  if (range_capacity == range_count)
200  {
201  range_capacity *= 2;
202  ranges = (RangeType **)
203  repalloc(ranges, range_capacity * sizeof(RangeType *));
204  }
205  ranges_seen++;
207  range_str,
208  cache->typioparam,
209  typmod));
210  if (!RangeIsEmpty(range))
211  ranges[range_count++] = range;
212  parse_state = MULTIRANGE_AFTER_RANGE;
213  }
214  else
215  {
216  if (ch == '"')
217  parse_state = MULTIRANGE_IN_RANGE_QUOTED;
218  else if (ch == '\\')
219  parse_state = MULTIRANGE_IN_RANGE_ESCAPED;
220 
221  /*
222  * We will include this character into range_str once we
223  * find the end of the range value.
224  */
225  }
226  break;
228 
229  /*
230  * We will include this character into range_str once we find
231  * the end of the range value.
232  */
233  parse_state = MULTIRANGE_IN_RANGE;
234  break;
236  if (ch == '"')
237  if (*(ptr + 1) == '"')
238  {
239  /* two quote marks means an escaped quote mark */
240  ptr++;
241  }
242  else
243  parse_state = MULTIRANGE_IN_RANGE;
244  else if (ch == '\\')
246 
247  /*
248  * We will include this character into range_str once we find
249  * the end of the range value.
250  */
251  break;
253  if (ch == ',')
254  parse_state = MULTIRANGE_BEFORE_RANGE;
255  else if (ch == '}')
256  parse_state = MULTIRANGE_FINISHED;
257  else
258  ereport(ERROR,
259  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
260  errmsg("malformed multirange literal: \"%s\"",
261  input_str),
262  errdetail("Expected comma or end of multirange.")));
263  break;
265 
266  /*
267  * We will include this character into range_str once we find
268  * the end of the range value.
269  */
270  parse_state = MULTIRANGE_IN_RANGE_QUOTED;
271  break;
272  default:
273  elog(ERROR, "unknown parse state: %d", parse_state);
274  }
275  }
276 
277  /* consume whitespace */
278  while (*ptr != '\0' && isspace((unsigned char) *ptr))
279  ptr++;
280 
281  if (*ptr != '\0')
282  ereport(ERROR,
283  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
284  errmsg("malformed multirange literal: \"%s\"",
285  input_str),
286  errdetail("Junk after closing right brace.")));
287 
288  ret = make_multirange(mltrngtypoid, rangetyp, range_count, ranges);
290 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
char * pnstrdup(const char *in, Size len)
Definition: mcxt.c:1310
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.h:32
#define PG_RETURN_MULTIRANGE_P(x)
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
static MultirangeIOData * get_multirange_io_data(FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func)
#define ERROR
Definition: elog.h:46
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
TypeCacheEntry * typcache
int errdetail(const char *fmt,...)
Definition: elog.c:1042
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1529
#define ereport(elevel,...)
Definition: elog.h:157
MultirangeParseState
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:73
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1182
void * palloc(Size size)
Definition: mcxt.c:1062
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277

◆ multirange_intersect()

Datum multirange_intersect ( PG_FUNCTION_ARGS  )

Definition at line 1223 of file multirangetypes.c.

References make_empty_multirange(), multirange_deserialize(), multirange_get_typcache(), multirange_intersect_internal(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_MULTIRANGE_P, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1224 {
1227  Oid mltrngtypoid = MultirangeTypeGetOid(mr1);
1228  TypeCacheEntry *typcache;
1229  TypeCacheEntry *rangetyp;
1230  int32 range_count1;
1231  int32 range_count2;
1232  RangeType **ranges1;
1233  RangeType **ranges2;
1234 
1235  typcache = multirange_get_typcache(fcinfo, mltrngtypoid);
1236  rangetyp = typcache->rngtype;
1237 
1238  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
1239  PG_RETURN_MULTIRANGE_P(make_empty_multirange(mltrngtypoid, rangetyp));
1240 
1241  multirange_deserialize(rangetyp, mr1, &range_count1, &ranges1);
1242  multirange_deserialize(rangetyp, mr2, &range_count2, &ranges2);
1243 
1245  rangetyp,
1246  range_count1,
1247  ranges1,
1248  range_count2,
1249  ranges2));
1250 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_RETURN_MULTIRANGE_P(x)
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
MultirangeType * make_empty_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp)
MultirangeType * multirange_intersect_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_intersect_agg_transfn()

Datum multirange_intersect_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1398 of file multirangetypes.c.

References AggCheckCallContext(), elog, ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), multirange_deserialize(), multirange_get_typcache(), multirange_intersect_internal(), PG_GETARG_MULTIRANGE_P, PG_RETURN_RANGE_P, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and type_is_multirange().

1399 {
1400  MemoryContext aggContext;
1401  Oid mltrngtypoid;
1402  TypeCacheEntry *typcache;
1403  MultirangeType *result;
1404  MultirangeType *current;
1405  int32 range_count1;
1406  int32 range_count2;
1407  RangeType **ranges1;
1408  RangeType **ranges2;
1409 
1410  if (!AggCheckCallContext(fcinfo, &aggContext))
1411  elog(ERROR, "multirange_intersect_agg_transfn called in non-aggregate context");
1412 
1413  mltrngtypoid = get_fn_expr_argtype(fcinfo->flinfo, 1);
1414  if (!type_is_multirange(mltrngtypoid))
1415  ereport(ERROR,
1416  (errcode(ERRCODE_DATATYPE_MISMATCH),
1417  errmsg("range_intersect_agg must be called with a multirange")));
1418 
1419  typcache = multirange_get_typcache(fcinfo, mltrngtypoid);
1420 
1421  /* strictness ensures these are non-null */
1422  result = PG_GETARG_MULTIRANGE_P(0);
1423  current = PG_GETARG_MULTIRANGE_P(1);
1424 
1425  multirange_deserialize(typcache->rngtype, result, &range_count1, &ranges1);
1426  multirange_deserialize(typcache->rngtype, current, &range_count2, &ranges2);
1427 
1428  result = multirange_intersect_internal(mltrngtypoid,
1429  typcache->rngtype,
1430  range_count1,
1431  ranges1,
1432  range_count2,
1433  ranges2);
1434  PG_RETURN_RANGE_P(result);
1435 }
#define PG_GETARG_MULTIRANGE_P(n)
int errcode(int sqlerrcode)
Definition: elog.c:698
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define ereport(elevel,...)
Definition: elog.h:157
MultirangeType * multirange_intersect_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
bool type_is_multirange(Oid typid)
Definition: lsyscache.c:2645
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4495
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232

◆ multirange_intersect_internal()

MultirangeType* multirange_intersect_internal ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp,
int32  range_count1,
RangeType **  ranges1,
int32  range_count2,
RangeType **  ranges2 
)

Definition at line 1253 of file multirangetypes.c.

References make_multirange(), palloc0(), range_before_internal(), range_intersect_internal(), range_overlaps_internal(), and range_overleft_internal().

Referenced by multirange_intersect(), and multirange_intersect_agg_transfn().

1256 {
1257  RangeType *r1;
1258  RangeType *r2;
1259  RangeType **ranges3;
1260  int32 range_count3;
1261  int32 i1;
1262  int32 i2;
1263 
1264  if (range_count1 == 0 || range_count2 == 0)
1265  return make_multirange(mltrngtypoid, rangetyp, 0, NULL);
1266 
1267  /*-----------------------------------------------
1268  * Worst case is a stitching pattern like this:
1269  *
1270  * mr1: --- --- --- ---
1271  * mr2: --- --- ---
1272  * mr3: - - - - - -
1273  *
1274  * That seems to be range_count1 + range_count2 - 1,
1275  * but one extra won't hurt.
1276  *-----------------------------------------------
1277  */
1278  ranges3 = palloc0((range_count1 + range_count2) * sizeof(RangeType *));
1279  range_count3 = 0;
1280 
1281  /*
1282  * For each range in mr1, keep intersecting until the ranges in mr2 have
1283  * passed it. The parallel progress through mr1 and mr2 is similar to
1284  * multirange_minus_multirange_internal, but we don't have to assign back
1285  * to r1.
1286  */
1287  r2 = ranges2[0];
1288  for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1289  {
1290  r1 = ranges1[i1];
1291 
1292  /* Discard r2s while r2 << r1 */
1293  while (r2 != NULL && range_before_internal(rangetyp, r2, r1))
1294  {
1295  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1296  }
1297 
1298  while (r2 != NULL)
1299  {
1300  if (range_overlaps_internal(rangetyp, r1, r2))
1301  {
1302  /* Keep the overlapping part */
1303  ranges3[range_count3++] = range_intersect_internal(rangetyp, r1, r2);
1304 
1305  /* If we "used up" all of r2, go to the next one... */
1306  if (range_overleft_internal(rangetyp, r2, r1))
1307  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1308 
1309  /* ...otherwise go to the next r1 */
1310  else
1311  break;
1312  }
1313  else
1314  /* We're past r1, so move to the next one */
1315  break;
1316  }
1317 
1318  /* If we're out of r2s, there can be no more intersections */
1319  if (r2 == NULL)
1320  break;
1321  }
1322 
1323  return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3);
1324 }
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
signed int int32
Definition: c.h:429
void * palloc0(Size size)
Definition: mcxt.c:1093
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:869
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:1125
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:646

◆ multirange_le()

Datum multirange_le ( PG_FUNCTION_ARGS  )

Definition at line 2583 of file multirangetypes.c.

References cmp(), multirange_cmp(), and PG_RETURN_BOOL.

2584 {
2585  int cmp = multirange_cmp(fcinfo);
2586 
2587  PG_RETURN_BOOL(cmp <= 0);
2588 }
Datum multirange_cmp(PG_FUNCTION_ARGS)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ multirange_lower()

Datum multirange_lower ( PG_FUNCTION_ARGS  )

Definition at line 1442 of file multirangetypes.c.

References RangeBound::infinite, lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_DATUM, PG_RETURN_NULL, TypeCacheEntry::rngtype, MultirangeIOData::typcache, upper(), and RangeBound::val.

1443 {
1445  TypeCacheEntry *typcache;
1446  RangeBound lower;
1447  RangeBound upper;
1448 
1449  if (MultirangeIsEmpty(mr))
1450  PG_RETURN_NULL();
1451 
1452  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1453 
1454  multirange_get_bounds(typcache->rngtype, mr, 0,
1455  &lower, &upper);
1456 
1457  if (!lower.infinite)
1458  PG_RETURN_DATUM(lower.val);
1459  else
1460  PG_RETURN_NULL();
1461 }
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
bool infinite
Definition: rangetypes.h:65
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ multirange_lower_inc()

Datum multirange_lower_inc ( PG_FUNCTION_ARGS  )

Definition at line 1500 of file multirangetypes.c.

References RangeBound::inclusive, lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and upper().

1501 {
1503  TypeCacheEntry *typcache;
1504  RangeBound lower;
1505  RangeBound upper;
1506 
1507  if (MultirangeIsEmpty(mr))
1508  PG_RETURN_BOOL(false);
1509 
1510  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1511  multirange_get_bounds(typcache->rngtype, mr, 0,
1512  &lower, &upper);
1513 
1514  PG_RETURN_BOOL(lower.inclusive);
1515 }
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
bool inclusive
Definition: rangetypes.h:66
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_lower_inf()

Datum multirange_lower_inf ( PG_FUNCTION_ARGS  )

Definition at line 1538 of file multirangetypes.c.

References RangeBound::infinite, lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and upper().

1539 {
1541  TypeCacheEntry *typcache;
1542  RangeBound lower;
1543  RangeBound upper;
1544 
1545  if (MultirangeIsEmpty(mr))
1546  PG_RETURN_BOOL(false);
1547 
1548  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1549  multirange_get_bounds(typcache->rngtype, mr, 0,
1550  &lower, &upper);
1551 
1552  PG_RETURN_BOOL(lower.infinite);
1553 }
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool infinite
Definition: rangetypes.h:65
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_lt()

Datum multirange_lt ( PG_FUNCTION_ARGS  )

Definition at line 2575 of file multirangetypes.c.

References cmp(), multirange_cmp(), and PG_RETURN_BOOL.

2576 {
2577  int cmp = multirange_cmp(fcinfo);
2578 
2579  PG_RETURN_BOOL(cmp < 0);
2580 }
Datum multirange_cmp(PG_FUNCTION_ARGS)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ multirange_minus()

Datum multirange_minus ( PG_FUNCTION_ARGS  )

Definition at line 1105 of file multirangetypes.c.

References multirange_deserialize(), multirange_get_typcache(), multirange_minus_internal(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_MULTIRANGE_P, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1106 {
1109  Oid mltrngtypoid = MultirangeTypeGetOid(mr1);
1110  TypeCacheEntry *typcache;
1111  TypeCacheEntry *rangetyp;
1112  int32 range_count1;
1113  int32 range_count2;
1114  RangeType **ranges1;
1115  RangeType **ranges2;
1116 
1117  typcache = multirange_get_typcache(fcinfo, mltrngtypoid);
1118  rangetyp = typcache->rngtype;
1119 
1120  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
1122 
1123  multirange_deserialize(typcache->rngtype, mr1, &range_count1, &ranges1);
1124  multirange_deserialize(typcache->rngtype, mr2, &range_count2, &ranges2);
1125 
1127  rangetyp,
1128  range_count1,
1129  ranges1,
1130  range_count2,
1131  ranges2));
1132 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_RETURN_MULTIRANGE_P(x)
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
MultirangeType * multirange_minus_internal(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count1, RangeType **ranges1, int32 range_count2, RangeType **ranges2)
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_minus_internal()

MultirangeType* multirange_minus_internal ( Oid  mltrngtypoid,
TypeCacheEntry rangetyp,
int32  range_count1,
RangeType **  ranges1,
int32  range_count2,
RangeType **  ranges2 
)

Definition at line 1135 of file multirangetypes.c.

References make_multirange(), palloc0(), range_before_internal(), range_minus_internal(), range_overlaps_internal(), range_split_internal(), and RangeIsEmpty.

Referenced by multirange_minus().

1138 {
1139  RangeType *r1;
1140  RangeType *r2;
1141  RangeType **ranges3;
1142  int32 range_count3;
1143  int32 i1;
1144  int32 i2;
1145 
1146  /*
1147  * Worst case: every range in ranges1 makes a different cut to some range
1148  * in ranges2.
1149  */
1150  ranges3 = palloc0((range_count1 + range_count2) * sizeof(RangeType *));
1151  range_count3 = 0;
1152 
1153  /*
1154  * For each range in mr1, keep subtracting until it's gone or the ranges
1155  * in mr2 have passed it. After a subtraction we assign what's left back
1156  * to r1. The parallel progress through mr1 and mr2 is similar to
1157  * multirange_overlaps_multirange_internal.
1158  */
1159  r2 = ranges2[0];
1160  for (i1 = 0, i2 = 0; i1 < range_count1; i1++)
1161  {
1162  r1 = ranges1[i1];
1163 
1164  /* Discard r2s while r2 << r1 */
1165  while (r2 != NULL && range_before_internal(rangetyp, r2, r1))
1166  {
1167  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1168  }
1169 
1170  while (r2 != NULL)
1171  {
1172  if (range_split_internal(rangetyp, r1, r2, &ranges3[range_count3], &r1))
1173  {
1174  /*
1175  * If r2 takes a bite out of the middle of r1, we need two
1176  * outputs
1177  */
1178  range_count3++;
1179  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1180 
1181  }
1182  else if (range_overlaps_internal(rangetyp, r1, r2))
1183  {
1184  /*
1185  * If r2 overlaps r1, replace r1 with r1 - r2.
1186  */
1187  r1 = range_minus_internal(rangetyp, r1, r2);
1188 
1189  /*
1190  * If r2 goes past r1, then we need to stay with it, in case
1191  * it hits future r1s. Otherwise we need to keep r1, in case
1192  * future r2s hit it. Since we already subtracted, there's no
1193  * point in using the overright/overleft calls.
1194  */
1195  if (RangeIsEmpty(r1) || range_before_internal(rangetyp, r1, r2))
1196  break;
1197  else
1198  r2 = ++i2 >= range_count2 ? NULL : ranges2[i2];
1199 
1200  }
1201  else
1202  {
1203  /*
1204  * This and all future r2s are past r1, so keep them. Also
1205  * assign whatever is left of r1 to the result.
1206  */
1207  break;
1208  }
1209  }
1210 
1211  /*
1212  * Nothing else can remove anything from r1, so keep it. Even if r1 is
1213  * empty here, make_multirange will remove it.
1214  */
1215  ranges3[range_count3++] = r1;
1216  }
1217 
1218  return make_multirange(mltrngtypoid, rangetyp, range_count3, ranges3);
1219 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
RangeType * range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:975
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
signed int int32
Definition: c.h:429
void * palloc0(Size size)
Definition: mcxt.c:1093
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:646
bool range_split_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
Definition: rangetypes.c:1164

◆ multirange_ne()

Datum multirange_ne ( PG_FUNCTION_ARGS  )

Definition at line 1858 of file multirangetypes.c.

References multirange_get_typcache(), multirange_ne_internal(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1859 {
1862  TypeCacheEntry *typcache;
1863 
1864  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
1865 
1866  PG_RETURN_BOOL(multirange_ne_internal(typcache->rngtype, mr1, mr2));
1867 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
bool multirange_ne_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_ne_internal()

bool multirange_ne_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)

Definition at line 1849 of file multirangetypes.c.

References multirange_eq_internal().

Referenced by multirange_ne().

1852 {
1853  return (!multirange_eq_internal(rangetyp, mr1, mr2));
1854 }
bool multirange_eq_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)

◆ multirange_out()

Datum multirange_out ( PG_FUNCTION_ARGS  )

Definition at line 293 of file multirangetypes.c.

References appendStringInfoChar(), appendStringInfoString(), buf, StringInfoData::data, get_multirange_io_data(), i, initStringInfo(), IOFunc_output, multirange_deserialize(), MultirangeTypeGetOid, OutputFunctionCall(), PG_GETARG_MULTIRANGE_P, PG_RETURN_CSTRING, range(), RangeTypePGetDatum, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and MultirangeIOData::typioproc.

Referenced by anycompatiblemultirange_out(), and anymultirange_out().

294 {
295  MultirangeType *multirange = PG_GETARG_MULTIRANGE_P(0);
296  Oid mltrngtypoid = MultirangeTypeGetOid(multirange);
297  MultirangeIOData *cache;
299  RangeType *range;
300  char *rangeStr;
301  int32 range_count;
302  int32 i;
303  RangeType **ranges;
304 
305  cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_output);
306 
307  initStringInfo(&buf);
308 
309  appendStringInfoChar(&buf, '{');
310 
311  multirange_deserialize(cache->typcache->rngtype, multirange, &range_count, &ranges);
312  for (i = 0; i < range_count; i++)
313  {
314  if (i > 0)
315  appendStringInfoChar(&buf, ',');
316  range = ranges[i];
317  rangeStr = OutputFunctionCall(&cache->typioproc, RangeTypePGetDatum(range));
318  appendStringInfoString(&buf, rangeStr);
319  }
320 
321  appendStringInfoChar(&buf, '}');
322 
323  PG_RETURN_CSTRING(buf.data);
324 }
#define PG_GETARG_MULTIRANGE_P(n)
unsigned int Oid
Definition: postgres_ext.h:31
#define RangeTypePGetDatum(X)
Definition: rangetypes.h:75
signed int int32
Definition: c.h:429
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1573
static MultirangeIOData * get_multirange_io_data(FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func)
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:68
TypeCacheEntry * typcache
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
int i
#define MultirangeTypeGetOid(mr)

◆ multirange_overlaps_multirange()

Datum multirange_overlaps_multirange ( PG_FUNCTION_ARGS  )

Definition at line 1895 of file multirangetypes.c.

References multirange_get_typcache(), multirange_overlaps_multirange_internal(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1896 {
1899  TypeCacheEntry *typcache;
1900 
1901  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
1902 
1904 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool multirange_overlaps_multirange_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr1, const MultirangeType *mr2)

◆ multirange_overlaps_multirange_internal()

bool multirange_overlaps_multirange_internal ( TypeCacheEntry rangetyp,
const MultirangeType mr1,
const MultirangeType mr2 
)

Definition at line 1950 of file multirangetypes.c.

References multirange_get_bounds(), MultirangeIsEmpty, range_bounds_overlaps(), range_cmp_bounds(), and MultirangeType::rangeCount.

Referenced by multirange_overlaps_multirange().

1953 {
1954  int32 range_count1;
1955  int32 range_count2;
1956  int32 i1;
1957  int32 i2;
1958  RangeBound lower1,
1959  upper1,
1960  lower2,
1961  upper2;
1962 
1963  /*
1964  * Empties never overlap, even with empties. (This seems strange since
1965  * they *do* contain each other, but we want to follow how ranges work.)
1966  */
1967  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
1968  return false;
1969 
1970  range_count1 = mr1->rangeCount;
1971  range_count2 = mr2->rangeCount;
1972 
1973  /*
1974  * Every range in mr1 gets a chance to overlap with the ranges in mr2, but
1975  * we can use their ordering to avoid O(n^2). This is similar to
1976  * range_overlaps_multirange where r1 : r2 :: mrr : r, but there if we
1977  * don't find an overlap with r we're done, and here if we don't find an
1978  * overlap with r2 we try the next r2.
1979  */
1980  i1 = 0;
1981  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
1982  for (i1 = 0, i2 = 0; i2 < range_count2; i2++)
1983  {
1984  multirange_get_bounds(rangetyp, mr2, i2, &lower2, &upper2);
1985 
1986  /* Discard r1s while r1 << r2 */
1987  while (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0)
1988  {
1989  if (++i1 >= range_count1)
1990  return false;
1991  multirange_get_bounds(rangetyp, mr1, i1, &lower1, &upper1);
1992  }
1993 
1994  /*
1995  * If r1 && r2, we're done, otherwise we failed to find an overlap for
1996  * r2, so go to the next one.
1997  */
1998  if (range_bounds_overlaps(rangetyp, &lower1, &upper1, &lower2, &upper2))
1999  return true;
2000  }
2001 
2002  /* We looked through all of mr2 without finding an overlap */
2003  return false;
2004 }
signed int int32
Definition: c.h:429
static bool range_bounds_overlaps(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define MultirangeIsEmpty(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_overlaps_range()

Datum multirange_overlaps_range ( PG_FUNCTION_ARGS  )

Definition at line 1883 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_overlaps_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1884 {
1886  RangeType *r = PG_GETARG_RANGE_P(1);
1887  TypeCacheEntry *typcache;
1888 
1889  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1890 
1892 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)

◆ multirange_overleft_multirange()

Datum multirange_overleft_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2068 of file multirangetypes.c.

References multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, range_cmp_bounds(), MultirangeType::rangeCount, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2069 {
2072  TypeCacheEntry *typcache;
2073  RangeBound lower1,
2074  upper1,
2075  lower2,
2076  upper2;
2077 
2078  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
2079  PG_RETURN_BOOL(false);
2080 
2081  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2082 
2083  multirange_get_bounds(typcache->rngtype, mr1, mr1->rangeCount - 1,
2084  &lower1, &upper1);
2085  multirange_get_bounds(typcache->rngtype, mr2, mr2->rangeCount - 1,
2086  &lower2, &upper2);
2087 
2088  PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &upper1, &upper2) <= 0);
2089 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_overleft_range()

Datum multirange_overleft_range ( PG_FUNCTION_ARGS  )

Definition at line 2043 of file multirangetypes.c.

References Assert, multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_cmp_bounds(), range_deserialize(), MultirangeType::rangeCount, RangeIsEmpty, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2044 {
2046  RangeType *r = PG_GETARG_RANGE_P(1);
2047  TypeCacheEntry *typcache;
2048  RangeBound lower1,
2049  upper1,
2050  lower2,
2051  upper2;
2052  bool empty;
2053 
2054  if (MultirangeIsEmpty(mr) || RangeIsEmpty(r))
2055  PG_RETURN_BOOL(false);
2056 
2057  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2058 
2059  multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1,
2060  &lower1, &upper1);
2061  range_deserialize(typcache->rngtype, r, &lower2, &upper2, &empty);
2062  Assert(!empty);
2063 
2064  PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &upper1, &upper2) <= 0);
2065 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define Assert(condition)
Definition: c.h:804
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_overright_multirange()

Datum multirange_overright_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2150 of file multirangetypes.c.

References multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, range_cmp_bounds(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2151 {
2154  TypeCacheEntry *typcache;
2155  RangeBound lower1,
2156  upper1,
2157  lower2,
2158  upper2;
2159 
2160  if (MultirangeIsEmpty(mr1) || MultirangeIsEmpty(mr2))
2161  PG_RETURN_BOOL(false);
2162 
2163  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
2164 
2165  multirange_get_bounds(typcache->rngtype, mr1, 0, &lower1, &upper1);
2166  multirange_get_bounds(typcache->rngtype, mr2, 0, &lower2, &upper2);
2167 
2168  PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &lower1, &lower2) >= 0);
2169 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_overright_range()

Datum multirange_overright_range ( PG_FUNCTION_ARGS  )

Definition at line 2126 of file multirangetypes.c.

References Assert, multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_cmp_bounds(), range_deserialize(), RangeIsEmpty, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2127 {
2129  RangeType *r = PG_GETARG_RANGE_P(1);
2130  TypeCacheEntry *typcache;
2131  RangeBound lower1,
2132  upper1,
2133  lower2,
2134  upper2;
2135  bool empty;
2136 
2137  if (MultirangeIsEmpty(mr) || RangeIsEmpty(r))
2138  PG_RETURN_BOOL(false);
2139 
2140  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2141 
2142  multirange_get_bounds(typcache->rngtype, mr, 0, &lower1, &upper1);
2143  range_deserialize(typcache->rngtype, r, &lower2, &upper2, &empty);
2144  Assert(!empty);
2145 
2146  PG_RETURN_BOOL(range_cmp_bounds(typcache->rngtype, &lower1, &lower2) >= 0);
2147 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define Assert(condition)
Definition: c.h:804
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
#define MultirangeTypeGetOid(mr)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_range_contains_bsearch_comparison()

static int multirange_range_contains_bsearch_comparison ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
void *  key,
bool match 
)
static

Definition at line 1709 of file multirangetypes.c.

References range_bounds_contains(), and range_cmp_bounds().

Referenced by multirange_contains_range_internal().

1712 {
1713  RangeBound *keyLower = (RangeBound *) key;
1714  RangeBound *keyUpper = (RangeBound *) key + 1;
1715 
1716  /* Check if key range is strictly in the left or in the right */
1717  if (range_cmp_bounds(typcache, keyUpper, lower) < 0)
1718  return -1;
1719  if (range_cmp_bounds(typcache, keyLower, upper) > 0)
1720  return 1;
1721 
1722  /*
1723  * At this point we found overlapping range. But we have to check if it
1724  * really contains the key range. Anyway, we have to stop our search
1725  * here, because multirange contains only non-overlapping ranges.
1726  */
1727  *match = range_bounds_contains(typcache, lower, upper, keyLower, keyUpper);
1728 
1729  return 0;
1730 }
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_range_overlaps_bsearch_comparison()

static int multirange_range_overlaps_bsearch_comparison ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
void *  key,
bool match 
)
static

Definition at line 1911 of file multirangetypes.c.

References range_cmp_bounds().

Referenced by range_overlaps_multirange_internal().

1914 {
1915  RangeBound *keyLower = (RangeBound *) key;
1916  RangeBound *keyUpper = (RangeBound *) key + 1;
1917 
1918  if (range_cmp_bounds(typcache, keyUpper, lower) < 0)
1919  return -1;
1920  if (range_cmp_bounds(typcache, keyLower, upper) > 0)
1921  return 1;
1922 
1923  *match = true;
1924  return 0;
1925 }
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ multirange_recv()

Datum multirange_recv ( PG_FUNCTION_ARGS  )

Definition at line 331 of file multirangetypes.c.

References appendBinaryStringInfo(), buf, StringInfoData::data, DatumGetRangeTypeP, get_multirange_io_data(), i, initStringInfo(), IOFunc_receive, make_multirange(), palloc(), pfree(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_MULTIRANGE_P, pq_getmsgbytes(), pq_getmsgend(), pq_getmsgint(), ReceiveFunctionCall(), resetStringInfo(), TypeCacheEntry::rngtype, tmpbuf, MultirangeIOData::typcache, MultirangeIOData::typioparam, and MultirangeIOData::typioproc.

332 {
334  Oid mltrngtypoid = PG_GETARG_OID(1);
335  int32 typmod = PG_GETARG_INT32(2);
336  MultirangeIOData *cache;
337  uint32 range_count;
338  RangeType **ranges;
339  MultirangeType *ret;
341 
342  cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_receive);
343 
344  range_count = pq_getmsgint(buf, 4);
345  ranges = palloc(range_count * sizeof(RangeType *));
346 
347  initStringInfo(&tmpbuf);
348  for (int i = 0; i < range_count; i++)
349  {
350  uint32 range_len = pq_getmsgint(buf, 4);
351  const char *range_data = pq_getmsgbytes(buf, range_len);
352 
353  resetStringInfo(&tmpbuf);
354  appendBinaryStringInfo(&tmpbuf, range_data, range_len);
355 
357  &tmpbuf,
358  cache->typioparam,
359  typmod));
360  }
361  pfree(tmpbuf.data);
362 
363  pq_getmsgend(buf);
364 
365  ret = make_multirange(mltrngtypoid, cache->typcache->rngtype,
366  range_count, ranges);
368 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_MULTIRANGE_P(x)
StringInfoData * StringInfo
Definition: stringinfo.h:44
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
unsigned int Oid
Definition: postgres_ext.h:31
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:510
signed int int32
Definition: c.h:429
static MultirangeIOData * get_multirange_io_data(FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func)
void pfree(void *pointer)
Definition: mcxt.c:1169
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
Definition: fmgr.c:1587
static char * buf
Definition: pg_test_fsync.c:68
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
TypeCacheEntry * typcache
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
unsigned int uint32
Definition: c.h:441
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:73
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
static StringInfoData tmpbuf
Definition: walsender.c:159
void * palloc(Size size)
Definition: mcxt.c:1062
int i
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:637
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227

◆ multirange_send()

Datum multirange_send ( PG_FUNCTION_ARGS  )

Definition at line 371 of file multirangetypes.c.

References buf, get_multirange_io_data(), i, IOFunc_send, makeStringInfo(), multirange_deserialize(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BYTEA_P, PointerGetDatum, pq_begintypsend(), pq_endtypsend(), pq_sendbytes(), pq_sendint32(), range(), MultirangeType::rangeCount, RangeTypePGetDatum, TypeCacheEntry::rngtype, SendFunctionCall(), MultirangeIOData::typcache, MultirangeIOData::typioproc, VARDATA, VARHDRSZ, and VARSIZE.

372 {
373  MultirangeType *multirange = PG_GETARG_MULTIRANGE_P(0);
374  Oid mltrngtypoid = MultirangeTypeGetOid(multirange);
376  RangeType **ranges;
377  int32 range_count;
378  MultirangeIOData *cache;
379 
380  cache = get_multirange_io_data(fcinfo, mltrngtypoid, IOFunc_send);
381 
382  /* construct output */
383  pq_begintypsend(buf);
384 
385  pq_sendint32(buf, multirange->rangeCount);
386 
387  multirange_deserialize(cache->typcache->rngtype, multirange, &range_count, &ranges);
388  for (int i = 0; i < range_count; i++)
389  {
390  Datum range;
391 
392  range = RangeTypePGetDatum(ranges[i]);
393  range = PointerGetDatum(SendFunctionCall(&cache->typioproc, range));
394 
395  pq_sendint32(buf, VARSIZE(range) - VARHDRSZ);
396  pq_sendbytes(buf, VARDATA(range), VARSIZE(range) - VARHDRSZ);
397  }
398 
400 }
#define VARDATA(PTR)
Definition: postgres.h:315
#define PG_GETARG_MULTIRANGE_P(n)
#define VARSIZE(PTR)
Definition: postgres.h:316
#define PointerGetDatum(X)
Definition: postgres.h:600
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
#define VARHDRSZ
Definition: c.h:627
StringInfo makeStringInfo(void)
Definition: stringinfo.c:41
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
unsigned int Oid
Definition: postgres_ext.h:31
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
#define RangeTypePGetDatum(X)
Definition: rangetypes.h:75
signed int int32
Definition: c.h:429
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static MultirangeIOData * get_multirange_io_data(FunctionCallInfo fcinfo, Oid mltrngtypid, IOFuncSelector func)
static char * buf
Definition: pg_test_fsync.c:68
TypeCacheEntry * typcache
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1634
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
uintptr_t Datum
Definition: postgres.h:411
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125
int i
#define MultirangeTypeGetOid(mr)

◆ multirange_size_estimate()

static Size multirange_size_estimate ( TypeCacheEntry rangetyp,
int32  range_count,
RangeType **  ranges 
)
static

Definition at line 563 of file multirangetypes.c.

References att_align_nominal, i, Max, TypeCacheEntry::rngelemtype, TypeCacheEntry::typalign, and VARSIZE.

Referenced by make_multirange().

565 {
566  char elemalign = rangetyp->rngelemtype->typalign;
567  Size size;
568  int32 i;
569 
570  /*
571  * Count space for MultirangeType struct, items and flags.
572  */
573  size = att_align_nominal(sizeof(MultirangeType) +
574  Max(range_count - 1, 0) * sizeof(uint32) +
575  range_count * sizeof(uint8), elemalign);
576 
577  /* Count space for range bounds */
578  for (i = 0; i < range_count; i++)
579  size += att_align_nominal(VARSIZE(ranges[i]) -
580  sizeof(RangeType) -
581  sizeof(char), elemalign);
582 
583  return size;
584 }
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
#define VARSIZE(PTR)
Definition: postgres.h:316
unsigned char uint8
Definition: c.h:439
signed int int32
Definition: c.h:429
unsigned int uint32
Definition: c.h:441
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
#define Max(x, y)
Definition: c.h:980
size_t Size
Definition: c.h:540
char typalign
Definition: typcache.h:41
int i

◆ multirange_union()

Datum multirange_union ( PG_FUNCTION_ARGS  )

Definition at line 1073 of file multirangetypes.c.

References make_multirange(), multirange_deserialize(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, palloc0(), PG_GETARG_MULTIRANGE_P, PG_RETURN_MULTIRANGE_P, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and TypeCacheEntry::type_id.

1074 {
1077  TypeCacheEntry *typcache;
1078  int32 range_count1;
1079  int32 range_count2;
1080  int32 range_count3;
1081  RangeType **ranges1;
1082  RangeType **ranges2;
1083  RangeType **ranges3;
1084 
1085  if (MultirangeIsEmpty(mr1))
1087  if (MultirangeIsEmpty(mr2))
1089 
1090  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr1));
1091 
1092  multirange_deserialize(typcache->rngtype, mr1, &range_count1, &ranges1);
1093  multirange_deserialize(typcache->rngtype, mr2, &range_count2, &ranges2);
1094 
1095  range_count3 = range_count1 + range_count2;
1096  ranges3 = palloc0(range_count3 * sizeof(RangeType *));
1097  memcpy(ranges3, ranges1, range_count1 * sizeof(RangeType *));
1098  memcpy(ranges3 + range_count1, ranges2, range_count2 * sizeof(RangeType *));
1100  range_count3, ranges3));
1101 }
#define PG_GETARG_MULTIRANGE_P(n)
#define PG_RETURN_MULTIRANGE_P(x)
signed int int32
Definition: c.h:429
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_deserialize(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int32 *range_count, RangeType ***ranges)
void * palloc0(Size size)
Definition: mcxt.c:1093
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_unnest()

Datum multirange_unnest ( PG_FUNCTION_ARGS  )

Definition at line 2647 of file multirangetypes.c.

References lookup_type_cache(), MemoryContextSwitchTo(), FuncCallContext::multi_call_memory_ctx, multirange_get_range(), MultirangeTypeGetOid, palloc(), PG_GETARG_MULTIRANGE_P, range(), RangeTypePGetDatum, SRF_FIRSTCALL_INIT, SRF_IS_FIRSTCALL, SRF_PERCALL_SETUP, SRF_RETURN_DONE, SRF_RETURN_NEXT, MultirangeIOData::typcache, TYPECACHE_MULTIRANGE_INFO, and FuncCallContext::user_fctx.

2648 {
2649  typedef struct
2650  {
2651  MultirangeType *mr;
2652  TypeCacheEntry *typcache;
2653  int index;
2654  } multirange_unnest_fctx;
2655 
2656  FuncCallContext *funcctx;
2657  multirange_unnest_fctx *fctx;
2658  MemoryContext oldcontext;
2659 
2660  /* stuff done only on the first call of the function */
2661  if (SRF_IS_FIRSTCALL())
2662  {
2663  MultirangeType *mr;
2664 
2665  /* create a function context for cross-call persistence */
2666  funcctx = SRF_FIRSTCALL_INIT();
2667 
2668  /*
2669  * switch to memory context appropriate for multiple function calls
2670  */
2671  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
2672 
2673  /*
2674  * Get the multirange value and detoast if needed. We can't do this
2675  * earlier because if we have to detoast, we want the detoasted copy
2676  * to be in multi_call_memory_ctx, so it will go away when we're done
2677  * and not before. (If no detoast happens, we assume the originally
2678  * passed multirange will stick around till then.)
2679  */
2680  mr = PG_GETARG_MULTIRANGE_P(0);
2681 
2682  /* allocate memory for user context */
2683  fctx = (multirange_unnest_fctx *) palloc(sizeof(multirange_unnest_fctx));
2684 
2685  /* initialize state */
2686  fctx->mr = mr;
2687  fctx->index = 0;
2688  fctx->typcache = lookup_type_cache(MultirangeTypeGetOid(mr),
2690 
2691  funcctx->user_fctx = fctx;
2692  MemoryContextSwitchTo(oldcontext);
2693  }
2694 
2695  /* stuff done on every call of the function */
2696  funcctx = SRF_PERCALL_SETUP();
2697  fctx = funcctx->user_fctx;
2698 
2699  if (fctx->index < fctx->mr->rangeCount)
2700  {
2701  RangeType *range;
2702 
2703  range = multirange_get_range(fctx->typcache->rngtype,
2704  fctx->mr,
2705  fctx->index);
2706  fctx->index++;
2707 
2708  SRF_RETURN_NEXT(funcctx, RangeTypePGetDatum(range));
2709  }
2710  else
2711  {
2712  /* do when there is no more left */
2713  SRF_RETURN_DONE(funcctx);
2714  }
2715 }
#define PG_GETARG_MULTIRANGE_P(n)
#define TYPECACHE_MULTIRANGE_INFO
Definition: typcache.h:152
#define SRF_IS_FIRSTCALL()
Definition: funcapi.h:293
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define SRF_PERCALL_SETUP()
Definition: funcapi.h:297
#define RangeTypePGetDatum(X)
Definition: rangetypes.h:75
Definition: type.h:89
#define SRF_RETURN_NEXT(_funcctx, _result)
Definition: funcapi.h:299
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:339
RangeType * multirange_get_range(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
MemoryContext multi_call_memory_ctx
Definition: funcapi.h:101
void * user_fctx
Definition: funcapi.h:82
void * palloc(Size size)
Definition: mcxt.c:1062
#define MultirangeTypeGetOid(mr)
#define SRF_RETURN_DONE(_funcctx)
Definition: funcapi.h:317
#define SRF_FIRSTCALL_INIT()
Definition: funcapi.h:295

◆ multirange_upper()

Datum multirange_upper ( PG_FUNCTION_ARGS  )

Definition at line 1465 of file multirangetypes.c.

References RangeBound::infinite, lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_DATUM, PG_RETURN_NULL, MultirangeType::rangeCount, TypeCacheEntry::rngtype, MultirangeIOData::typcache, upper(), and RangeBound::val.

1466 {
1468  TypeCacheEntry *typcache;
1469  RangeBound lower;
1470  RangeBound upper;
1471 
1472  if (MultirangeIsEmpty(mr))
1473  PG_RETURN_NULL();
1474 
1475  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1476 
1477  multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1,
1478  &lower, &upper);
1479 
1480  if (!upper.infinite)
1481  PG_RETURN_DATUM(upper.val);
1482  else
1483  PG_RETURN_NULL();
1484 }
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
bool infinite
Definition: rangetypes.h:65
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ multirange_upper_inc()

Datum multirange_upper_inc ( PG_FUNCTION_ARGS  )

Definition at line 1519 of file multirangetypes.c.

References RangeBound::inclusive, lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, MultirangeType::rangeCount, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and upper().

1520 {
1522  TypeCacheEntry *typcache;
1523  RangeBound lower;
1524  RangeBound upper;
1525 
1526  if (MultirangeIsEmpty(mr))
1527  PG_RETURN_BOOL(false);
1528 
1529  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1530  multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1,
1531  &lower, &upper);
1532 
1533  PG_RETURN_BOOL(upper.inclusive);
1534 }
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
bool inclusive
Definition: rangetypes.h:66
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ multirange_upper_inf()

Datum multirange_upper_inf ( PG_FUNCTION_ARGS  )

Definition at line 1557 of file multirangetypes.c.

References RangeBound::infinite, lower(), multirange_get_bounds(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_BOOL, MultirangeType::rangeCount, TypeCacheEntry::rngtype, MultirangeIOData::typcache, and upper().

1558 {
1560  TypeCacheEntry *typcache;
1561  RangeBound lower;
1562  RangeBound upper;
1563 
1564  if (MultirangeIsEmpty(mr))
1565  PG_RETURN_BOOL(false);
1566 
1567  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1568  multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1,
1569  &lower, &upper);
1570 
1571  PG_RETURN_BOOL(upper.infinite);
1572 }
#define PG_GETARG_MULTIRANGE_P(n)
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool infinite
Definition: rangetypes.h:65
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ range_adjacent_multirange()

Datum range_adjacent_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2442 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_adjacent_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2443 {
2444  RangeType *r = PG_GETARG_RANGE_P(0);
2446  TypeCacheEntry *typcache;
2447 
2448  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2449 
2451 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
bool range_adjacent_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
#define MultirangeTypeGetOid(mr)

◆ range_adjacent_multirange_internal()

bool range_adjacent_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)

Definition at line 2406 of file multirangetypes.c.

References Assert, bounds_adjacent(), multirange_get_bounds(), MultirangeIsEmpty, range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

Referenced by multirange_adjacent_range(), range_adjacent_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

2409 {
2410  RangeBound lower1,
2411  upper1,
2412  lower2,
2413  upper2;
2414  bool empty;
2415  int32 range_count;
2416 
2417  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2418  return false;
2419 
2420  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2421  Assert(!empty);
2422 
2423  range_count = mr->rangeCount;
2424  multirange_get_bounds(rangetyp, mr, 0,
2425  &lower2, &upper2);
2426 
2427  if (bounds_adjacent(rangetyp, upper1, lower2))
2428  return true;
2429 
2430  if (range_count > 1)
2431  multirange_get_bounds(rangetyp, mr, range_count - 1,
2432  &lower2, &upper2);
2433 
2434  if (bounds_adjacent(rangetyp, upper2, lower1))
2435  return true;
2436 
2437  return false;
2438 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition: rangetypes.c:739
signed int int32
Definition: c.h:429
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)

◆ range_after_multirange()

Datum range_after_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2300 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_after_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2301 {
2302  RangeType *r = PG_GETARG_RANGE_P(0);
2304  TypeCacheEntry *typcache;
2305 
2306  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2307 
2309 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool range_after_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)

◆ range_after_multirange_internal()

bool range_after_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)

Definition at line 2381 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

Referenced by multirange_before_range(), range_after_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

2384 {
2385  RangeBound lower1,
2386  upper1,
2387  lower2,
2388  upper2;
2389  bool empty;
2390  int32 range_count;
2391 
2392  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2393  return false;
2394 
2395  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2396  Assert(!empty);
2397 
2398  range_count = mr->rangeCount;
2399  multirange_get_bounds(rangetyp, mr, range_count - 1,
2400  &lower2, &upper2);
2401 
2402  return (range_cmp_bounds(rangetyp, &lower1, &upper2) > 0);
2403 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
signed int int32
Definition: c.h:429
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_agg_finalfn()

Datum range_agg_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 1364 of file multirangetypes.c.

References AggCheckCallContext(), DatumGetRangeTypeP, ArrayBuildState::dvalues, elog, ERROR, get_fn_expr_rettype(), i, make_multirange(), multirange_get_typcache(), ArrayBuildState::nelems, palloc0(), PG_ARGISNULL, PG_GETARG_POINTER, PG_RETURN_MULTIRANGE_P, PG_RETURN_NULL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1365 {
1366  MemoryContext aggContext;
1367  Oid mltrngtypoid;
1368  TypeCacheEntry *typcache;
1370  int32 range_count;
1371  RangeType **ranges;
1372  int i;
1373 
1374  if (!AggCheckCallContext(fcinfo, &aggContext))
1375  elog(ERROR, "range_agg_finalfn called in non-aggregate context");
1376 
1377  state = PG_ARGISNULL(0) ? NULL : (ArrayBuildState *) PG_GETARG_POINTER(0);
1378  if (state == NULL)
1379  /* This shouldn't be possible, but just in case.... */
1380  PG_RETURN_NULL();
1381 
1382  /* Also return NULL if we had zero inputs, like other aggregates */
1383  range_count = state->nelems;
1384  if (range_count == 0)
1385  PG_RETURN_NULL();
1386 
1387  mltrngtypoid = get_fn_expr_rettype(fcinfo->flinfo);
1388  typcache = multirange_get_typcache(fcinfo, mltrngtypoid);
1389 
1390  ranges = palloc0(range_count * sizeof(RangeType *));
1391  for (i = 0; i < range_count; i++)
1392  ranges[i] = DatumGetRangeTypeP(state->dvalues[i]);
1393 
1394  PG_RETURN_MULTIRANGE_P(make_multirange(mltrngtypoid, typcache->rngtype, range_count, ranges));
1395 }
#define PG_RETURN_MULTIRANGE_P(x)
Datum * dvalues
Definition: array.h:183
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
unsigned int Oid
Definition: postgres_ext.h:31
signed int int32
Definition: c.h:429
#define ERROR
Definition: elog.h:46
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void * palloc0(Size size)
Definition: mcxt.c:1093
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1778
MultirangeType * make_multirange(Oid mltrngtypoid, TypeCacheEntry *rangetyp, int32 range_count, RangeType **ranges)
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
Definition: regguts.h:317
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:73
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4495
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define elog(elevel,...)
Definition: elog.h:232
int i
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ range_agg_transfn()

Datum range_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1333 of file multirangetypes.c.

References accumArrayResult(), AggCheckCallContext(), elog, ereport, errcode(), errmsg(), ERROR, get_fn_expr_argtype(), initArrayResult(), PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_POINTER, PG_RETURN_POINTER, and type_is_range().

1334 {
1335  MemoryContext aggContext;
1336  Oid rngtypoid;
1338 
1339  if (!AggCheckCallContext(fcinfo, &aggContext))
1340  elog(ERROR, "range_agg_transfn called in non-aggregate context");
1341 
1342  rngtypoid = get_fn_expr_argtype(fcinfo->flinfo, 1);
1343  if (!type_is_range(rngtypoid))
1344  ereport(ERROR,
1345  (errcode(ERRCODE_DATATYPE_MISMATCH),
1346  errmsg("range_agg must be called with a range")));
1347 
1348  if (PG_ARGISNULL(0))
1349  state = initArrayResult(rngtypoid, aggContext, false);
1350  else
1351  state = (ArrayBuildState *) PG_GETARG_POINTER(0);
1352 
1353  /* skip NULLs */
1354  if (!PG_ARGISNULL(1))
1355  accumArrayResult(state, PG_GETARG_DATUM(1), false, rngtypoid, aggContext);
1356 
1357  PG_RETURN_POINTER(state);
1358 }
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
ArrayBuildState * initArrayResult(Oid element_type, MemoryContext rcontext, bool subcontext)
Definition: arrayfuncs.c:5083
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
int errcode(int sqlerrcode)
Definition: elog.c:698
bool type_is_range(Oid typid)
Definition: lsyscache.c:2635
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:46
Oid get_fn_expr_argtype(FmgrInfo *flinfo, int argnum)
Definition: fmgr.c:1800
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
Definition: regguts.h:317
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4495
ArrayBuildState * accumArrayResult(ArrayBuildState *astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext)
Definition: arrayfuncs.c:5122
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232

◆ range_before_multirange()

Datum range_before_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2263 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_before_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2264 {
2265  RangeType *r = PG_GETARG_RANGE_P(0);
2267  TypeCacheEntry *typcache;
2268 
2269  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2270 
2272 }
#define PG_GETARG_MULTIRANGE_P(n)
bool range_before_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ range_before_multirange_internal()

bool range_before_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)

Definition at line 2337 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, range_cmp_bounds(), range_deserialize(), and RangeIsEmpty.

Referenced by multirange_after_range(), range_before_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

2340 {
2341  RangeBound lower1,
2342  upper1,
2343  lower2,
2344  upper2;
2345  bool empty;
2346 
2347  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2348  return false;
2349 
2350  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2351  Assert(!empty);
2352 
2353  multirange_get_bounds(rangetyp, mr, 0, &lower2, &upper2);
2354 
2355  return (range_cmp_bounds(rangetyp, &upper1, &lower2) < 0);
2356 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_bounds_contains()

static bool range_bounds_contains ( TypeCacheEntry typcache,
RangeBound lower1,
RangeBound upper1,
RangeBound lower2,
RangeBound upper2 
)
static

Definition at line 869 of file multirangetypes.c.

References range_cmp_bounds().

Referenced by multirange_contains_multirange_internal(), multirange_range_contains_bsearch_comparison(), and range_contains_multirange_internal().

872 {
873  if (range_cmp_bounds(typcache, lower1, lower2) <= 0 &&
874  range_cmp_bounds(typcache, upper1, upper2) >= 0)
875  return true;
876 
877  return false;
878 }
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_bounds_overlaps()

static bool range_bounds_overlaps ( TypeCacheEntry typcache,
RangeBound lower1,
RangeBound upper1,
RangeBound lower2,
RangeBound upper2 
)
static

Definition at line 849 of file multirangetypes.c.

References range_cmp_bounds().

Referenced by multirange_overlaps_multirange_internal().

852 {
853  if (range_cmp_bounds(typcache, lower1, lower2) >= 0 &&
854  range_cmp_bounds(typcache, lower1, upper2) <= 0)
855  return true;
856 
857  if (range_cmp_bounds(typcache, lower2, lower1) >= 0 &&
858  range_cmp_bounds(typcache, lower2, upper1) <= 0)
859  return true;
860 
861  return false;
862 }
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_contained_by_multirange()

Datum range_contained_by_multirange ( PG_FUNCTION_ARGS  )

Definition at line 1681 of file multirangetypes.c.

References multirange_contains_range_internal(), multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1682 {
1683  RangeType *r = PG_GETARG_RANGE_P(0);
1685  TypeCacheEntry *typcache;
1686 
1687  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1688 
1690 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool multirange_contains_range_internal(TypeCacheEntry *rangetyp, const MultirangeType *mr, const RangeType *r)
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ range_contains_multirange()

Datum range_contains_multirange ( PG_FUNCTION_ARGS  )

Definition at line 1668 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contains_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1669 {
1670  RangeType *r = PG_GETARG_RANGE_P(0);
1672  TypeCacheEntry *typcache;
1673 
1674  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1675 
1677 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
bool range_contains_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ range_contains_multirange_internal()

bool range_contains_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)

Definition at line 1764 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, range_bounds_contains(), range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

Referenced by multirange_contained_by_range(), range_contains_multirange(), range_gist_consistent_int_multirange(), and range_gist_consistent_leaf_multirange().

1767 {
1768  RangeBound lower1,
1769  upper1,
1770  lower2,
1771  upper2,
1772  tmp;
1773  bool empty;
1774 
1775  /*
1776  * Every range contains an infinite number of empty multiranges, even an
1777  * empty one.
1778  */
1779  if (MultirangeIsEmpty(mr))
1780  return true;
1781 
1782  if (RangeIsEmpty(r))
1783  return false;
1784 
1785  /* Range contains multirange iff it contains its union range. */
1786  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
1787  Assert(!empty);
1788  multirange_get_bounds(rangetyp, mr, 0, &lower2, &tmp);
1789  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1, &tmp, &upper2);
1790 
1791  return range_bounds_contains(rangetyp, &lower1, &upper1, &lower2, &upper2);
1792 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
static bool range_bounds_contains(TypeCacheEntry *typcache, RangeBound *lower1, RangeBound *upper1, RangeBound *lower2, RangeBound *upper2)

◆ range_merge_from_multirange()

Datum range_merge_from_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2610 of file multirangetypes.c.

References make_empty_range(), make_range(), multirange_get_bounds(), multirange_get_range(), multirange_get_typcache(), MultirangeIsEmpty, MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_RETURN_RANGE_P, MultirangeType::rangeCount, TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2611 {
2613  Oid mltrngtypoid = MultirangeTypeGetOid(mr);
2614  TypeCacheEntry *typcache;
2615  RangeType *result;
2616 
2617  typcache = multirange_get_typcache(fcinfo, mltrngtypoid);
2618 
2619  if (MultirangeIsEmpty(mr))
2620  {
2621  result = make_empty_range(typcache->rngtype);
2622  }
2623  else if (mr->rangeCount == 1)
2624  {
2625  result = multirange_get_range(typcache->rngtype, mr, 0);
2626  }
2627  else
2628  {
2629  RangeBound firstLower,
2630  firstUpper,
2631  lastLower,
2632  lastUpper;
2633 
2634  multirange_get_bounds(typcache->rngtype, mr, 0,
2635  &firstLower, &firstUpper);
2636  multirange_get_bounds(typcache->rngtype, mr, mr->rangeCount - 1,
2637  &lastLower, &lastUpper);
2638 
2639  result = make_range(typcache->rngtype, &firstLower, &lastUpper, false);
2640  }
2641 
2642  PG_RETURN_RANGE_P(result);
2643 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
#define PG_GETARG_MULTIRANGE_P(n)
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
unsigned int Oid
Definition: postgres_ext.h:31
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
RangeType * multirange_get_range(TypeCacheEntry *rangetyp, const MultirangeType *multirange, int i)
#define MultirangeIsEmpty(mr)
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ range_overlaps_multirange()

Datum range_overlaps_multirange ( PG_FUNCTION_ARGS  )

Definition at line 1871 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_overlaps_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

1872 {
1873  RangeType *r = PG_GETARG_RANGE_P(0);
1875  TypeCacheEntry *typcache;
1876 
1877  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
1878 
1880 }
#define PG_GETARG_MULTIRANGE_P(n)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)
bool range_overlaps_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)

◆ range_overlaps_multirange_internal()

bool range_overlaps_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)

Definition at line 1928 of file multirangetypes.c.

References Assert, multirange_bsearch_match(), multirange_range_overlaps_bsearch_comparison(), MultirangeIsEmpty, range_deserialize(), and RangeIsEmpty.

Referenced by multirange_overlaps_range(), range_gist_consistent_int_multirange(), range_gist_consistent_leaf_multirange(), and range_overlaps_multirange().

1931 {
1932  RangeBound bounds[2];
1933  bool empty;
1934 
1935  /*
1936  * Empties never overlap, even with empties. (This seems strange since
1937  * they *do* contain each other, but we want to follow how ranges work.)
1938  */
1939  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
1940  return false;
1941 
1942  range_deserialize(rangetyp, r, &bounds[0], &bounds[1], &empty);
1943  Assert(!empty);
1944 
1945  return multirange_bsearch_match(rangetyp, mr, bounds,
1947 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
static bool multirange_bsearch_match(TypeCacheEntry *typcache, const MultirangeType *mr, void *key, multirange_bsearch_comparison cmp_func)
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
static int multirange_range_overlaps_bsearch_comparison(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, void *key, bool *match)

◆ range_overleft_multirange()

Datum range_overleft_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2031 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_overleft_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2032 {
2033  RangeType *r = PG_GETARG_RANGE_P(0);
2035  TypeCacheEntry *typcache;
2036 
2037  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2038 
2040 }
#define PG_GETARG_MULTIRANGE_P(n)
bool range_overleft_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
struct TypeCacheEntry * rngtype
Definition: typcache.h:107
#define MultirangeTypeGetOid(mr)

◆ range_overleft_multirange_internal()

bool range_overleft_multirange_internal ( TypeCacheEntry rangetyp,
const RangeType r,
const MultirangeType mr 
)

Definition at line 2008 of file multirangetypes.c.

References Assert, multirange_get_bounds(), MultirangeIsEmpty, PG_RETURN_BOOL, range_cmp_bounds(), range_deserialize(), MultirangeType::rangeCount, and RangeIsEmpty.

Referenced by range_gist_consistent_int_multirange(), range_gist_consistent_leaf_multirange(), and range_overleft_multirange().

2011 {
2012  RangeBound lower1,
2013  upper1,
2014  lower2,
2015  upper2;
2016  bool empty;
2017 
2018  if (RangeIsEmpty(r) || MultirangeIsEmpty(mr))
2019  PG_RETURN_BOOL(false);
2020 
2021 
2022  range_deserialize(rangetyp, r, &lower1, &upper1, &empty);
2023  Assert(!empty);
2024  multirange_get_bounds(rangetyp, mr, mr->rangeCount - 1,
2025  &lower2, &upper2);
2026 
2027  PG_RETURN_BOOL(range_cmp_bounds(rangetyp, &upper1, &upper2) <= 0);
2028 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
void multirange_get_bounds(TypeCacheEntry *rangetyp, const MultirangeType *multirange, uint32 i, RangeBound *lower, RangeBound *upper)
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define Assert(condition)
Definition: c.h:804
#define MultirangeIsEmpty(mr)
static Ranges * range_deserialize(int maxvalues, SerializedRanges *range)
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_overright_multirange()

Datum range_overright_multirange ( PG_FUNCTION_ARGS  )

Definition at line 2114 of file multirangetypes.c.

References multirange_get_typcache(), MultirangeTypeGetOid, PG_GETARG_MULTIRANGE_P, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_overright_multirange_internal(), TypeCacheEntry::rngtype, and MultirangeIOData::typcache.

2115 {
2116  RangeType *r = PG_GETARG_RANGE_P(0);
2118  TypeCacheEntry *typcache;
2119 
2120  typcache = multirange_get_typcache(fcinfo, MultirangeTypeGetOid(mr));
2121 
2123 }
#define PG_GETARG_MULTIRANGE_P(n)
bool range_overright_multirange_internal(TypeCacheEntry *rangetyp, const RangeType *r, const MultirangeType *mr)
TypeCacheEntry * multirange_get_typcache(FunctionCallInfo fcinfo, Oid mltrngtypid)