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

Go to the source code of this file.

Data Structures

struct  RangeIOData
 

Macros

#define TYPE_IS_PACKABLE(typlen, typstorage)   ((typlen) == -1 && (typstorage) != TYPSTORAGE_PLAIN)
 

Typedefs

typedef struct RangeIOData RangeIOData
 

Functions

static RangeIODataget_range_io_data (FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
 
static char range_parse_flags (const char *flags_str)
 
static void range_parse (const char *input_str, char *flags, char **lbound_str, char **ubound_str)
 
static const char * range_parse_bound (const char *string, const char *ptr, char **bound_str, bool *infinite)
 
static char * range_deparse (char flags, const char *lbound_str, const char *ubound_str)
 
static char * range_bound_escape (const char *value)
 
static Size datum_compute_size (Size sz, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
 
static Pointer datum_write (Pointer ptr, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
 
Datum range_in (PG_FUNCTION_ARGS)
 
Datum range_out (PG_FUNCTION_ARGS)
 
Datum range_recv (PG_FUNCTION_ARGS)
 
Datum range_send (PG_FUNCTION_ARGS)
 
Datum range_constructor2 (PG_FUNCTION_ARGS)
 
Datum range_constructor3 (PG_FUNCTION_ARGS)
 
Datum range_lower (PG_FUNCTION_ARGS)
 
Datum range_upper (PG_FUNCTION_ARGS)
 
Datum range_empty (PG_FUNCTION_ARGS)
 
Datum range_lower_inc (PG_FUNCTION_ARGS)
 
Datum range_upper_inc (PG_FUNCTION_ARGS)
 
Datum range_lower_inf (PG_FUNCTION_ARGS)
 
Datum range_upper_inf (PG_FUNCTION_ARGS)
 
Datum range_contains_elem (PG_FUNCTION_ARGS)
 
Datum elem_contained_by_range (PG_FUNCTION_ARGS)
 
bool range_eq_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_eq (PG_FUNCTION_ARGS)
 
bool range_ne_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_ne (PG_FUNCTION_ARGS)
 
Datum range_contains (PG_FUNCTION_ARGS)
 
Datum range_contained_by (PG_FUNCTION_ARGS)
 
bool range_before_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_before (PG_FUNCTION_ARGS)
 
bool range_after_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_after (PG_FUNCTION_ARGS)
 
bool bounds_adjacent (TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
 
bool range_adjacent_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_adjacent (PG_FUNCTION_ARGS)
 
bool range_overlaps_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_overlaps (PG_FUNCTION_ARGS)
 
bool range_overleft_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_overleft (PG_FUNCTION_ARGS)
 
bool range_overright_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
Datum range_overright (PG_FUNCTION_ARGS)
 
Datum range_minus (PG_FUNCTION_ARGS)
 
RangeTyperange_minus_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
RangeTyperange_union_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
 
Datum range_union (PG_FUNCTION_ARGS)
 
Datum range_merge (PG_FUNCTION_ARGS)
 
Datum range_intersect (PG_FUNCTION_ARGS)
 
RangeTyperange_intersect_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_split_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2, RangeType **output1, RangeType **output2)
 
Datum range_intersect_agg_transfn (PG_FUNCTION_ARGS)
 
Datum range_cmp (PG_FUNCTION_ARGS)
 
Datum range_lt (PG_FUNCTION_ARGS)
 
Datum range_le (PG_FUNCTION_ARGS)
 
Datum range_ge (PG_FUNCTION_ARGS)
 
Datum range_gt (PG_FUNCTION_ARGS)
 
Datum hash_range (PG_FUNCTION_ARGS)
 
Datum hash_range_extended (PG_FUNCTION_ARGS)
 
Datum int4range_canonical (PG_FUNCTION_ARGS)
 
Datum int8range_canonical (PG_FUNCTION_ARGS)
 
Datum daterange_canonical (PG_FUNCTION_ARGS)
 
Datum int4range_subdiff (PG_FUNCTION_ARGS)
 
Datum int8range_subdiff (PG_FUNCTION_ARGS)
 
Datum numrange_subdiff (PG_FUNCTION_ARGS)
 
Datum daterange_subdiff (PG_FUNCTION_ARGS)
 
Datum tsrange_subdiff (PG_FUNCTION_ARGS)
 
Datum tstzrange_subdiff (PG_FUNCTION_ARGS)
 
TypeCacheEntryrange_get_typcache (FunctionCallInfo fcinfo, Oid rngtypid)
 
RangeTyperange_serialize (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
 
void range_deserialize (TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
 
char range_get_flags (const RangeType *range)
 
void range_set_contain_empty (RangeType *range)
 
RangeTypemake_range (TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
 
int range_cmp_bounds (TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
 
int range_cmp_bound_values (TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
 
int range_compare (const void *key1, const void *key2, void *arg)
 
RangeTypemake_empty_range (TypeCacheEntry *typcache)
 
bool range_contains_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_contained_by_internal (TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
 
bool range_contains_elem_internal (TypeCacheEntry *typcache, const RangeType *r, Datum val)
 

Macro Definition Documentation

◆ TYPE_IS_PACKABLE

#define TYPE_IS_PACKABLE (   typlen,
  typstorage 
)    ((typlen) == -1 && (typstorage) != TYPSTORAGE_PLAIN)

Definition at line 2520 of file rangetypes.c.

Referenced by datum_compute_size(), and datum_write().

Typedef Documentation

◆ RangeIOData

typedef struct RangeIOData RangeIOData

Function Documentation

◆ bounds_adjacent()

bool bounds_adjacent ( TypeCacheEntry typcache,
RangeBound  boundA,
RangeBound  boundB 
)

Definition at line 739 of file rangetypes.c.

References Assert, cmp(), FmgrInfo::fn_oid, RangeBound::inclusive, RangeBound::lower, make_range(), OidIsValid, range_cmp_bound_values(), RangeIsEmpty, and TypeCacheEntry::rng_canonical_finfo.

Referenced by adjacent_cmp_bounds(), multirange_adjacent_multirange(), range_adjacent_internal(), and range_adjacent_multirange_internal().

740 {
741  int cmp;
742 
743  Assert(!boundA.lower && boundB.lower);
744 
745  cmp = range_cmp_bound_values(typcache, &boundA, &boundB);
746  if (cmp < 0)
747  {
748  RangeType *r;
749 
750  /*
751  * Bounds do not overlap; see if there are points in between.
752  */
753 
754  /* in a continuous subtype, there are assumed to be points between */
755  if (!OidIsValid(typcache->rng_canonical_finfo.fn_oid))
756  return false;
757 
758  /*
759  * The bounds are of a discrete range type; so make a range A..B and
760  * see if it's empty.
761  */
762 
763  /* flip the inclusion flags */
764  boundA.inclusive = !boundA.inclusive;
765  boundB.inclusive = !boundB.inclusive;
766  /* change upper/lower labels to avoid Assert failures */
767  boundA.lower = true;
768  boundB.lower = false;
769  r = make_range(typcache, &boundA, &boundB, false);
770  return RangeIsEmpty(r);
771  }
772  else if (cmp == 0)
773  return boundA.inclusive != boundB.inclusive;
774  else
775  return false; /* bounds overlap */
776 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1998
#define OidIsValid(objectId)
Definition: c.h:710
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
FmgrInfo rng_canonical_finfo
Definition: typcache.h:101
Oid fn_oid
Definition: fmgr.h:59
#define Assert(condition)
Definition: c.h:804
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ daterange_canonical()

Datum daterange_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1508 of file rangetypes.c.

References DATE_NOT_FINITE, date_pli(), DatumGetDateADT, DirectFunctionCall2, RangeBound::inclusive, RangeBound::infinite, Int32GetDatum, lower(), PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_deserialize(), range_get_typcache(), range_serialize(), RangeTypeGetOid, RangeIOData::typcache, upper(), and RangeBound::val.

1509 {
1510  RangeType *r = PG_GETARG_RANGE_P(0);
1511  TypeCacheEntry *typcache;
1512  RangeBound lower;
1513  RangeBound upper;
1514  bool empty;
1515 
1516  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1517 
1518  range_deserialize(typcache, r, &lower, &upper, &empty);
1519 
1520  if (empty)
1521  PG_RETURN_RANGE_P(r);
1522 
1523  if (!lower.infinite && !DATE_NOT_FINITE(DatumGetDateADT(lower.val)) &&
1524  !lower.inclusive)
1525  {
1526  lower.val = DirectFunctionCall2(date_pli, lower.val, Int32GetDatum(1));
1527  lower.inclusive = true;
1528  }
1529 
1530  if (!upper.infinite && !DATE_NOT_FINITE(DatumGetDateADT(upper.val)) &&
1531  upper.inclusive)
1532  {
1533  upper.val = DirectFunctionCall2(date_pli, upper.val, Int32GetDatum(1));
1534  upper.inclusive = false;
1535  }
1536 
1537  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1538 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define DatumGetDateADT(X)
Definition: date.h:53
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
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
bool inclusive
Definition: rangetypes.h:66
#define DATE_NOT_FINITE(j)
Definition: date.h:43
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1659
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:65
#define Int32GetDatum(X)
Definition: postgres.h:523
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628
Datum date_pli(PG_FUNCTION_ARGS)
Definition: date.c:509

◆ daterange_subdiff()

Datum daterange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1587 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1588 {
1589  int32 v1 = PG_GETARG_INT32(0);
1590  int32 v2 = PG_GETARG_INT32(1);
1591 
1592  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1593 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
signed int int32
Definition: c.h:429
double float8
Definition: c.h:565

◆ datum_compute_size()

static Size datum_compute_size ( Size  sz,
Datum  datum,
bool  typbyval,
char  typalign,
int16  typlen,
char  typstorage 
)
static

Definition at line 2528 of file rangetypes.c.

References att_addlength_datum, att_align_datum, DatumGetPointer, TYPE_IS_PACKABLE, VARATT_CAN_MAKE_SHORT, and VARATT_CONVERTED_SHORT_SIZE.

Referenced by range_serialize().

2530 {
2531  if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2533  {
2534  /*
2535  * we're anticipating converting to a short varlena header, so adjust
2536  * length and don't count any alignment
2537  */
2539  }
2540  else
2541  {
2542  data_length = att_align_datum(data_length, typalign, typlen, val);
2543  data_length = att_addlength_datum(data_length, typlen, val);
2544  }
2545 
2546  return data_length;
2547 }
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2520
#define att_align_datum(cur_offset, attalign, attlen, attdatum)
Definition: tupmacs.h:105
char typalign
Definition: pg_type.h:176
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:295
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:298
#define DatumGetPointer(X)
Definition: postgres.h:593
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:164
long val
Definition: informix.c:664

◆ datum_write()

static Pointer datum_write ( Pointer  ptr,
Datum  datum,
bool  typbyval,
char  typalign,
int16  typlen,
char  typstorage 
)
static

Definition at line 2554 of file rangetypes.c.

References Assert, att_align_nominal, DatumGetCString, DatumGetPointer, elog, ERROR, SET_VARSIZE_SHORT, store_att_byval, TYPE_IS_PACKABLE, val, VARATT_CAN_MAKE_SHORT, VARATT_CONVERTED_SHORT_SIZE, VARATT_IS_EXTERNAL, VARATT_IS_SHORT, VARDATA, VARSIZE, and VARSIZE_SHORT.

Referenced by range_serialize().

2556 {
2557  Size data_length;
2558 
2559  if (typbyval)
2560  {
2561  /* pass-by-value */
2562  ptr = (char *) att_align_nominal(ptr, typalign);
2563  store_att_byval(ptr, datum, typlen);
2564  data_length = typlen;
2565  }
2566  else if (typlen == -1)
2567  {
2568  /* varlena */
2569  Pointer val = DatumGetPointer(datum);
2570 
2571  if (VARATT_IS_EXTERNAL(val))
2572  {
2573  /*
2574  * Throw error, because we must never put a toast pointer inside a
2575  * range object. Caller should have detoasted it.
2576  */
2577  elog(ERROR, "cannot store a toast pointer inside a range");
2578  data_length = 0; /* keep compiler quiet */
2579  }
2580  else if (VARATT_IS_SHORT(val))
2581  {
2582  /* no alignment for short varlenas */
2583  data_length = VARSIZE_SHORT(val);
2584  memcpy(ptr, val, data_length);
2585  }
2586  else if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2587  VARATT_CAN_MAKE_SHORT(val))
2588  {
2589  /* convert to short varlena -- no alignment */
2590  data_length = VARATT_CONVERTED_SHORT_SIZE(val);
2591  SET_VARSIZE_SHORT(ptr, data_length);
2592  memcpy(ptr + 1, VARDATA(val), data_length - 1);
2593  }
2594  else
2595  {
2596  /* full 4-byte header varlena */
2597  ptr = (char *) att_align_nominal(ptr, typalign);
2598  data_length = VARSIZE(val);
2599  memcpy(ptr, val, data_length);
2600  }
2601  }
2602  else if (typlen == -2)
2603  {
2604  /* cstring ... never needs alignment */
2605  Assert(typalign == TYPALIGN_CHAR);
2606  data_length = strlen(DatumGetCString(datum)) + 1;
2607  memcpy(ptr, DatumGetPointer(datum), data_length);
2608  }
2609  else
2610  {
2611  /* fixed-length pass-by-reference */
2612  ptr = (char *) att_align_nominal(ptr, typalign);
2613  Assert(typlen > 0);
2614  data_length = typlen;
2615  memcpy(ptr, DatumGetPointer(datum), data_length);
2616  }
2617 
2618  ptr += data_length;
2619 
2620  return ptr;
2621 }
#define SET_VARSIZE_SHORT(PTR, len)
Definition: postgres.h:343
#define VARDATA(PTR)
Definition: postgres.h:315
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:148
#define VARSIZE(PTR)
Definition: postgres.h:316
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2520
#define VARATT_IS_EXTERNAL(PTR)
Definition: postgres.h:326
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
#define ERROR
Definition: elog.h:46
#define DatumGetCString(X)
Definition: postgres.h:610
#define VARATT_IS_SHORT(PTR)
Definition: postgres.h:339
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:295
#define VARSIZE_SHORT(PTR)
Definition: postgres.h:318
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:298
#define store_att_byval(T, newdatum, attlen)
Definition: tupmacs.h:226
#define Assert(condition)
Definition: c.h:804
size_t Size
Definition: c.h:540
#define DatumGetPointer(X)
Definition: postgres.h:593
#define elog(elevel,...)
Definition: elog.h:232
long val
Definition: informix.c:664

◆ elem_contained_by_range()

Datum elem_contained_by_range ( PG_FUNCTION_ARGS  )

Definition at line 539 of file rangetypes.c.

References PG_GETARG_DATUM, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contains_elem_internal(), range_get_typcache(), RangeTypeGetOid, RangeIOData::typcache, and val.

540 {
543  TypeCacheEntry *typcache;
544 
545  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
546 
547  PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
548 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val)
Definition: rangetypes.c:2473
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
long val
Definition: informix.c:664

◆ get_range_io_data()

static RangeIOData * get_range_io_data ( FunctionCallInfo  fcinfo,
Oid  rngtypid,
IOFuncSelector  func 
)
static

Definition at line 299 of file rangetypes.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::rngelemtype, typalign, RangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_RANGE_INFO, RangeIOData::typioparam, and RangeIOData::typioproc.

Referenced by range_in(), range_out(), range_recv(), and range_send().

300 {
301  RangeIOData *cache = (RangeIOData *) fcinfo->flinfo->fn_extra;
302 
303  if (cache == NULL || cache->typcache->type_id != rngtypid)
304  {
305  int16 typlen;
306  bool typbyval;
307  char typalign;
308  char typdelim;
309  Oid typiofunc;
310 
311  cache = (RangeIOData *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
312  sizeof(RangeIOData));
313  cache->typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
314  if (cache->typcache->rngelemtype == NULL)
315  elog(ERROR, "type %u is not a range type", rngtypid);
316 
317  /* get_type_io_data does more than we need, but is convenient */
319  func,
320  &typlen,
321  &typbyval,
322  &typalign,
323  &typdelim,
324  &cache->typioparam,
325  &typiofunc);
326 
327  if (!OidIsValid(typiofunc))
328  {
329  /* this could only happen for receive or send */
330  if (func == IOFunc_receive)
331  ereport(ERROR,
332  (errcode(ERRCODE_UNDEFINED_FUNCTION),
333  errmsg("no binary input function available for type %s",
335  else
336  ereport(ERROR,
337  (errcode(ERRCODE_UNDEFINED_FUNCTION),
338  errmsg("no binary output function available for type %s",
340  }
341  fmgr_info_cxt(typiofunc, &cache->typioproc,
342  fcinfo->flinfo->fn_mcxt);
343 
344  fcinfo->flinfo->fn_extra = (void *) cache;
345  }
346 
347  return cache;
348 }
signed short int16
Definition: c.h:428
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:147
MemoryContext fn_mcxt
Definition: fmgr.h:65
int errcode(int sqlerrcode)
Definition: elog.c:698
TypeCacheEntry * typcache
Definition: rangetypes.c:49
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
FmgrInfo typioproc
Definition: rangetypes.c:50
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:136
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:338
#define ereport(elevel,...)
Definition: elog.h:157
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
Oid typioparam
Definition: rangetypes.c:51
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_range()

Datum hash_range ( PG_FUNCTION_ARGS  )

Definition at line 1312 of file rangetypes.c.

References check_stack_depth(), DatumGetUInt32, ereport, errcode(), errmsg(), ERROR, FmgrInfo::fn_oid, format_type_be(), FunctionCall1Coll(), TypeCacheEntry::hash_proc_finfo, hash_uint32(), lookup_type_cache(), lower(), OidIsValid, PG_GETARG_RANGE_P, PG_RETURN_INT32, range_deserialize(), range_get_flags(), range_get_typcache(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeTypeGetOid, TypeCacheEntry::rng_collation, TypeCacheEntry::rngelemtype, RangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_HASH_PROC_FINFO, upper(), and RangeBound::val.

1313 {
1314  RangeType *r = PG_GETARG_RANGE_P(0);
1315  uint32 result;
1316  TypeCacheEntry *typcache;
1317  TypeCacheEntry *scache;
1318  RangeBound lower;
1319  RangeBound upper;
1320  bool empty;
1321  char flags;
1322  uint32 lower_hash;
1323  uint32 upper_hash;
1324 
1325  check_stack_depth(); /* recurses when subtype is a range type */
1326 
1327  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1328 
1329  /* deserialize */
1330  range_deserialize(typcache, r, &lower, &upper, &empty);
1331  flags = range_get_flags(r);
1332 
1333  /*
1334  * Look up the element type's hash function, if not done already.
1335  */
1336  scache = typcache->rngelemtype;
1337  if (!OidIsValid(scache->hash_proc_finfo.fn_oid))
1338  {
1340  if (!OidIsValid(scache->hash_proc_finfo.fn_oid))
1341  ereport(ERROR,
1342  (errcode(ERRCODE_UNDEFINED_FUNCTION),
1343  errmsg("could not identify a hash function for type %s",
1344  format_type_be(scache->type_id))));
1345  }
1346 
1347  /*
1348  * Apply the hash function to each bound.
1349  */
1350  if (RANGE_HAS_LBOUND(flags))
1351  lower_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo,
1352  typcache->rng_collation,
1353  lower.val));
1354  else
1355  lower_hash = 0;
1356 
1357  if (RANGE_HAS_UBOUND(flags))
1358  upper_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo,
1359  typcache->rng_collation,
1360  upper.val));
1361  else
1362  upper_hash = 0;
1363 
1364  /* Merge hashes of flags and bounds */
1365  result = hash_uint32((uint32) flags);
1366  result ^= lower_hash;
1367  result = (result << 1) | (result >> 31);
1368  result ^= upper_hash;
1369 
1370  PG_RETURN_INT32(result);
1371 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
#define DatumGetUInt32(X)
Definition: postgres.h:530
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define TYPECACHE_HASH_PROC_FINFO
Definition: typcache.h:143
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
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 ERROR
Definition: elog.h:46
void check_stack_depth(void)
Definition: postgres.c:3441
unsigned int uint32
Definition: c.h:441
FmgrInfo hash_proc_finfo
Definition: typcache.h:77
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1131
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:338
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:157
static Datum hash_uint32(uint32 k)
Definition: hashfn.h:43
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
Oid rng_collation
Definition: typcache.h:99
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ hash_range_extended()

Datum hash_range_extended ( PG_FUNCTION_ARGS  )

Definition at line 1378 of file rangetypes.c.

References check_stack_depth(), DatumGetInt64, DatumGetUInt64, ereport, errcode(), errmsg(), ERROR, FmgrInfo::fn_oid, format_type_be(), FunctionCall2Coll(), TypeCacheEntry::hash_extended_proc_finfo, hash_uint32_extended(), lookup_type_cache(), lower(), OidIsValid, PG_GETARG_DATUM, PG_GETARG_RANGE_P, PG_RETURN_UINT64, range_deserialize(), range_get_flags(), range_get_typcache(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeTypeGetOid, TypeCacheEntry::rng_collation, TypeCacheEntry::rngelemtype, ROTATE_HIGH_AND_LOW_32BITS, RangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_HASH_EXTENDED_PROC_FINFO, upper(), and RangeBound::val.

1379 {
1380  RangeType *r = PG_GETARG_RANGE_P(0);
1381  Datum seed = PG_GETARG_DATUM(1);
1382  uint64 result;
1383  TypeCacheEntry *typcache;
1384  TypeCacheEntry *scache;
1385  RangeBound lower;
1386  RangeBound upper;
1387  bool empty;
1388  char flags;
1389  uint64 lower_hash;
1390  uint64 upper_hash;
1391 
1393 
1394  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1395 
1396  range_deserialize(typcache, r, &lower, &upper, &empty);
1397  flags = range_get_flags(r);
1398 
1399  scache = typcache->rngelemtype;
1401  {
1402  scache = lookup_type_cache(scache->type_id,
1405  ereport(ERROR,
1406  (errcode(ERRCODE_UNDEFINED_FUNCTION),
1407  errmsg("could not identify a hash function for type %s",
1408  format_type_be(scache->type_id))));
1409  }
1410 
1411  if (RANGE_HAS_LBOUND(flags))
1413  typcache->rng_collation,
1414  lower.val,
1415  seed));
1416  else
1417  lower_hash = 0;
1418 
1419  if (RANGE_HAS_UBOUND(flags))
1421  typcache->rng_collation,
1422  upper.val,
1423  seed));
1424  else
1425  upper_hash = 0;
1426 
1427  /* Merge hashes of flags and bounds */
1428  result = DatumGetUInt64(hash_uint32_extended((uint32) flags,
1429  DatumGetInt64(seed)));
1430  result ^= lower_hash;
1431  result = ROTATE_HIGH_AND_LOW_32BITS(result);
1432  result ^= upper_hash;
1433 
1434  PG_RETURN_UINT64(result);
1435 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define TYPECACHE_HASH_EXTENDED_PROC_FINFO
Definition: typcache.h:151
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
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:1151
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:369
#define OidIsValid(objectId)
Definition: c.h:710
#define ERROR
Definition: elog.h:46
#define DatumGetInt64(X)
Definition: postgres.h:651
void check_stack_depth(void)
Definition: postgres.c:3441
unsigned int uint32
Definition: c.h:441
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:338
Oid fn_oid
Definition: fmgr.h:59
#define ereport(elevel,...)
Definition: elog.h:157
#define DatumGetUInt64(X)
Definition: postgres.h:678
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
Oid rng_collation
Definition: typcache.h:99
int errmsg(const char *fmt,...)
Definition: elog.c:909
static Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfn.h:49

◆ int4range_canonical()

Datum int4range_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1446 of file rangetypes.c.

References DirectFunctionCall2, RangeBound::inclusive, RangeBound::infinite, Int32GetDatum, int4pl(), lower(), PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_deserialize(), range_get_typcache(), range_serialize(), RangeTypeGetOid, RangeIOData::typcache, upper(), and RangeBound::val.

1447 {
1448  RangeType *r = PG_GETARG_RANGE_P(0);
1449  TypeCacheEntry *typcache;
1450  RangeBound lower;
1451  RangeBound upper;
1452  bool empty;
1453 
1454  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1455 
1456  range_deserialize(typcache, r, &lower, &upper, &empty);
1457 
1458  if (empty)
1459  PG_RETURN_RANGE_P(r);
1460 
1461  if (!lower.infinite && !lower.inclusive)
1462  {
1463  lower.val = DirectFunctionCall2(int4pl, lower.val, Int32GetDatum(1));
1464  lower.inclusive = true;
1465  }
1466 
1467  if (!upper.infinite && upper.inclusive)
1468  {
1469  upper.val = DirectFunctionCall2(int4pl, upper.val, Int32GetDatum(1));
1470  upper.inclusive = false;
1471  }
1472 
1473  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1474 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
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
Datum int4pl(PG_FUNCTION_ARGS)
Definition: int.c:770
bool inclusive
Definition: rangetypes.h:66
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1659
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:65
#define Int32GetDatum(X)
Definition: postgres.h:523
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ int4range_subdiff()

Datum int4range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1553 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1554 {
1555  int32 v1 = PG_GETARG_INT32(0);
1556  int32 v2 = PG_GETARG_INT32(1);
1557 
1558  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1559 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
signed int int32
Definition: c.h:429
double float8
Definition: c.h:565

◆ int8range_canonical()

Datum int8range_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1477 of file rangetypes.c.

References DirectFunctionCall2, RangeBound::inclusive, RangeBound::infinite, Int64GetDatum(), int8pl(), lower(), PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_deserialize(), range_get_typcache(), range_serialize(), RangeTypeGetOid, RangeIOData::typcache, upper(), and RangeBound::val.

1478 {
1479  RangeType *r = PG_GETARG_RANGE_P(0);
1480  TypeCacheEntry *typcache;
1481  RangeBound lower;
1482  RangeBound upper;
1483  bool empty;
1484 
1485  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1486 
1487  range_deserialize(typcache, r, &lower, &upper, &empty);
1488 
1489  if (empty)
1490  PG_RETURN_RANGE_P(r);
1491 
1492  if (!lower.infinite && !lower.inclusive)
1493  {
1494  lower.val = DirectFunctionCall2(int8pl, lower.val, Int64GetDatum(1));
1495  lower.inclusive = true;
1496  }
1497 
1498  if (!upper.infinite && upper.inclusive)
1499  {
1500  upper.val = DirectFunctionCall2(int8pl, upper.val, Int64GetDatum(1));
1501  upper.inclusive = false;
1502  }
1503 
1504  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1505 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum int8pl(PG_FUNCTION_ARGS)
Definition: int8.c:548
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
bool inclusive
Definition: rangetypes.h:66
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1700
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1659
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:65
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ int8range_subdiff()

Datum int8range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1562 of file rangetypes.c.

References PG_GETARG_INT64, and PG_RETURN_FLOAT8.

1563 {
1564  int64 v1 = PG_GETARG_INT64(0);
1565  int64 v2 = PG_GETARG_INT64(1);
1566 
1567  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1568 }
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
double float8
Definition: c.h:565
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

◆ make_empty_range()

RangeType* make_empty_range ( TypeCacheEntry typcache)

Definition at line 2073 of file rangetypes.c.

References RangeBound::inclusive, RangeBound::infinite, lower(), RangeBound::lower, make_range(), upper(), and RangeBound::val.

Referenced by multirange_get_union_range(), range_intersect_internal(), range_merge_from_multirange(), and range_minus_internal().

2074 {
2075  RangeBound lower;
2076  RangeBound upper;
2077 
2078  lower.val = (Datum) 0;
2079  lower.infinite = false;
2080  lower.inclusive = false;
2081  lower.lower = true;
2082 
2083  upper.val = (Datum) 0;
2084  upper.infinite = false;
2085  upper.inclusive = false;
2086  upper.lower = false;
2087 
2088  return make_range(typcache, &lower, &upper, true);
2089 }
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
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
uintptr_t Datum
Definition: postgres.h:411
bool infinite
Definition: rangetypes.h:65

◆ make_range()

RangeType* make_range ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

Definition at line 1884 of file rangetypes.c.

References DatumGetRangeTypeP, FmgrInfo::fn_oid, FunctionCall1, OidIsValid, range(), range_serialize(), RangeIsEmpty, RangeTypePGetDatum, and TypeCacheEntry::rng_canonical_finfo.

Referenced by bounds_adjacent(), make_empty_range(), multirange_get_union_range(), range_constructor2(), range_constructor3(), range_in(), range_intersect_internal(), range_merge_from_multirange(), range_minus_internal(), range_recv(), range_split_internal(), range_super_union(), and range_union_internal().

1886 {
1887  RangeType *range;
1888 
1889  range = range_serialize(typcache, lower, upper, empty);
1890 
1891  /* no need to call canonical on empty ranges ... */
1892  if (OidIsValid(typcache->rng_canonical_finfo.fn_oid) &&
1893  !RangeIsEmpty(range))
1895  RangeTypePGetDatum(range)));
1896 
1897  return range;
1898 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:56
#define OidIsValid(objectId)
Definition: c.h:710
#define RangeTypePGetDatum(X)
Definition: rangetypes.h:75
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1659
FmgrInfo rng_canonical_finfo
Definition: typcache.h:101
Oid fn_oid
Definition: fmgr.h:59
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:73
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:644

◆ numrange_subdiff()

Datum numrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1571 of file rangetypes.c.

References DatumGetFloat8, DirectFunctionCall1, DirectFunctionCall2, numeric_float8(), numeric_sub(), PG_GETARG_DATUM, and PG_RETURN_FLOAT8.

1572 {
1573  Datum v1 = PG_GETARG_DATUM(0);
1574  Datum v2 = PG_GETARG_DATUM(1);
1575  Datum numresult;
1576  float8 floatresult;
1577 
1578  numresult = DirectFunctionCall2(numeric_sub, v1, v2);
1579 
1581  numresult));
1582 
1583  PG_RETURN_FLOAT8(floatresult);
1584 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:626
double float8
Definition: c.h:565
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:4367
#define DatumGetFloat8(X)
Definition: postgres.h:758
uintptr_t Datum
Definition: postgres.h:411
Datum numeric_sub(PG_FUNCTION_ARGS)
Definition: numeric.c:2788
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:628

◆ range_adjacent()

Datum range_adjacent ( PG_FUNCTION_ARGS  )

Definition at line 810 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_adjacent_internal(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

811 {
812  RangeType *r1 = PG_GETARG_RANGE_P(0);
813  RangeType *r2 = PG_GETARG_RANGE_P(1);
814  TypeCacheEntry *typcache;
815 
816  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
817 
818  PG_RETURN_BOOL(range_adjacent_internal(typcache, r1, r2));
819 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:780

◆ range_adjacent_internal()

bool range_adjacent_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 780 of file rangetypes.c.

References bounds_adjacent(), elog, ERROR, range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_canonicalize(), range_adjacent(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_union_internal(), and spg_range_quad_leaf_consistent().

781 {
782  RangeBound lower1,
783  lower2;
784  RangeBound upper1,
785  upper2;
786  bool empty1,
787  empty2;
788 
789  /* Different types should be prevented by ANYRANGE matching rules */
790  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
791  elog(ERROR, "range types do not match");
792 
793  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
794  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
795 
796  /* An empty range is not adjacent to any other range */
797  if (empty1 || empty2)
798  return false;
799 
800  /*
801  * Given two ranges A..B and C..D, the ranges are adjacent if and only if
802  * B is adjacent to C, or D is adjacent to A.
803  */
804  return (bounds_adjacent(typcache, upper1, lower2) ||
805  bounds_adjacent(typcache, upper2, lower1));
806 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
bool bounds_adjacent(TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
Definition: rangetypes.c:739
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232

◆ range_after()

Datum range_after ( PG_FUNCTION_ARGS  )

Definition at line 709 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_after_internal(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

710 {
711  RangeType *r1 = PG_GETARG_RANGE_P(0);
712  RangeType *r2 = PG_GETARG_RANGE_P(1);
713  TypeCacheEntry *typcache;
714 
715  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
716 
717  PG_RETURN_BOOL(range_after_internal(typcache, r1, r2));
718 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
bool range_after_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:684
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_after_internal()

bool range_after_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 684 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_after(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

685 {
686  RangeBound lower1,
687  lower2;
688  RangeBound upper1,
689  upper2;
690  bool empty1,
691  empty2;
692 
693  /* Different types should be prevented by ANYRANGE matching rules */
694  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
695  elog(ERROR, "range types do not match");
696 
697  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
698  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
699 
700  /* An empty range is neither before nor after any other range */
701  if (empty1 || empty2)
702  return false;
703 
704  return (range_cmp_bounds(typcache, &lower1, &upper2) > 0);
705 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_before()

Datum range_before ( PG_FUNCTION_ARGS  )

Definition at line 671 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_before_internal(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

672 {
673  RangeType *r1 = PG_GETARG_RANGE_P(0);
674  RangeType *r2 = PG_GETARG_RANGE_P(1);
675  TypeCacheEntry *typcache;
676 
677  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
678 
679  PG_RETURN_BOOL(range_before_internal(typcache, r1, r2));
680 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool range_before_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:646
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_before_internal()

bool range_before_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 646 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_canonicalize(), multirange_intersect_internal(), multirange_minus_internal(), range_before(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

647 {
648  RangeBound lower1,
649  lower2;
650  RangeBound upper1,
651  upper2;
652  bool empty1,
653  empty2;
654 
655  /* Different types should be prevented by ANYRANGE matching rules */
656  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
657  elog(ERROR, "range types do not match");
658 
659  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
660  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
661 
662  /* An empty range is neither before nor after any other range */
663  if (empty1 || empty2)
664  return false;
665 
666  return (range_cmp_bounds(typcache, &upper1, &lower2) < 0);
667 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_bound_escape()

static char * range_bound_escape ( const char *  value)
static

Definition at line 2383 of file rangetypes.c.

References appendStringInfoChar(), buf, StringInfoData::data, and initStringInfo().

Referenced by range_deparse().

2384 {
2385  bool nq;
2386  const char *ptr;
2388 
2389  initStringInfo(&buf);
2390 
2391  /* Detect whether we need double quotes for this value */
2392  nq = (value[0] == '\0'); /* force quotes for empty string */
2393  for (ptr = value; *ptr; ptr++)
2394  {
2395  char ch = *ptr;
2396 
2397  if (ch == '"' || ch == '\\' ||
2398  ch == '(' || ch == ')' ||
2399  ch == '[' || ch == ']' ||
2400  ch == ',' ||
2401  isspace((unsigned char) ch))
2402  {
2403  nq = true;
2404  break;
2405  }
2406  }
2407 
2408  /* And emit the string */
2409  if (nq)
2410  appendStringInfoChar(&buf, '"');
2411  for (ptr = value; *ptr; ptr++)
2412  {
2413  char ch = *ptr;
2414 
2415  if (ch == '"' || ch == '\\')
2416  appendStringInfoChar(&buf, ch);
2417  appendStringInfoChar(&buf, ch);
2418  }
2419  if (nq)
2420  appendStringInfoChar(&buf, '"');
2421 
2422  return buf.data;
2423 }
static struct @142 value
static char * buf
Definition: pg_test_fsync.c:68
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

◆ range_cmp()

Datum range_cmp ( PG_FUNCTION_ARGS  )

Definition at line 1231 of file rangetypes.c.

References check_stack_depth(), cmp(), elog, ERROR, PG_FREE_IF_COPY, PG_GETARG_RANGE_P, PG_RETURN_INT32, range_cmp_bounds(), range_deserialize(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

Referenced by range_ge(), range_gt(), range_le(), and range_lt().

1232 {
1233  RangeType *r1 = PG_GETARG_RANGE_P(0);
1234  RangeType *r2 = PG_GETARG_RANGE_P(1);
1235  TypeCacheEntry *typcache;
1236  RangeBound lower1,
1237  lower2;
1238  RangeBound upper1,
1239  upper2;
1240  bool empty1,
1241  empty2;
1242  int cmp;
1243 
1244  check_stack_depth(); /* recurses when subtype is a range type */
1245 
1246  /* Different types should be prevented by ANYRANGE matching rules */
1247  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1248  elog(ERROR, "range types do not match");
1249 
1250  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1251 
1252  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1253  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1254 
1255  /* For b-tree use, empty ranges sort before all else */
1256  if (empty1 && empty2)
1257  cmp = 0;
1258  else if (empty1)
1259  cmp = -1;
1260  else if (empty2)
1261  cmp = 1;
1262  else
1263  {
1264  cmp = range_cmp_bounds(typcache, &lower1, &lower2);
1265  if (cmp == 0)
1266  cmp = range_cmp_bounds(typcache, &upper1, &upper2);
1267  }
1268 
1269  PG_FREE_IF_COPY(r1, 0);
1270  PG_FREE_IF_COPY(r2, 1);
1271 
1272  PG_RETURN_INT32(cmp);
1273 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
#define ERROR
Definition: elog.h:46
void check_stack_depth(void)
Definition: postgres.c:3441
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define elog(elevel,...)
Definition: elog.h:232
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

◆ range_cmp_bound_values()

int range_cmp_bound_values ( TypeCacheEntry typcache,
const RangeBound b1,
const RangeBound b2 
)

Definition at line 1998 of file rangetypes.c.

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

Referenced by bounds_adjacent(), and range_serialize().

2000 {
2001  /*
2002  * First, handle cases involving infinity, which don't require invoking
2003  * the comparison proc.
2004  */
2005  if (b1->infinite && b2->infinite)
2006  {
2007  /*
2008  * Both are infinity, so they are equal unless one is lower and the
2009  * other not.
2010  */
2011  if (b1->lower == b2->lower)
2012  return 0;
2013  else
2014  return b1->lower ? -1 : 1;
2015  }
2016  else if (b1->infinite)
2017  return b1->lower ? -1 : 1;
2018  else if (b2->infinite)
2019  return b2->lower ? 1 : -1;
2020 
2021  /*
2022  * Both boundaries are finite, so compare the held values.
2023  */
2025  typcache->rng_collation,
2026  b1->val, b2->val));
2027 }
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:1151
bool lower
Definition: rangetypes.h:67
bool infinite
Definition: rangetypes.h:65
Oid rng_collation
Definition: typcache.h:99

◆ range_cmp_bounds()

int range_cmp_bounds ( TypeCacheEntry typcache,
const RangeBound b1,
const RangeBound b2 
)

Definition at line 1924 of file rangetypes.c.

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

Referenced by adjacent_cmp_bounds(), adjacent_inner_consistent(), bound_cmp(), calc_hist_selectivity_contained(), getQuadrant(), interval_cmp_lower(), interval_cmp_upper(), multirange_before_multirange_internal(), multirange_cmp(), multirange_contains_multirange_internal(), multirange_eq_internal(), multirange_overlaps_multirange_internal(), multirange_overleft_multirange(), multirange_overleft_range(), multirange_overright_multirange(), multirange_overright_range(), multirange_range_contains_bsearch_comparison(), multirange_range_overlaps_bsearch_comparison(), multirange_union_range_equal(), range_after_internal(), range_after_multirange_internal(), range_before_internal(), range_before_multirange_internal(), range_bound_qsort_cmp(), range_bounds_contains(), range_bounds_overlaps(), range_cmp(), range_compare(), range_contains_internal(), range_eq_internal(), range_gist_double_sorting_split(), range_gist_penalty(), range_intersect_internal(), range_minus_internal(), range_overlaps_internal(), range_overleft_internal(), range_overleft_multirange_internal(), range_overright_internal(), range_overright_multirange_internal(), range_split_internal(), range_super_union(), range_union_internal(), rbound_bsearch(), single_bound_cmp(), and spg_range_quad_inner_consistent().

1925 {
1926  int32 result;
1927 
1928  /*
1929  * First, handle cases involving infinity, which don't require invoking
1930  * the comparison proc.
1931  */
1932  if (b1->infinite && b2->infinite)
1933  {
1934  /*
1935  * Both are infinity, so they are equal unless one is lower and the
1936  * other not.
1937  */
1938  if (b1->lower == b2->lower)
1939  return 0;
1940  else
1941  return b1->lower ? -1 : 1;
1942  }
1943  else if (b1->infinite)
1944  return b1->lower ? -1 : 1;
1945  else if (b2->infinite)
1946  return b2->lower ? 1 : -1;
1947 
1948  /*
1949  * Both boundaries are finite, so compare the held values.
1950  */
1952  typcache->rng_collation,
1953  b1->val, b2->val));
1954 
1955  /*
1956  * If the comparison is anything other than equal, we're done. If they
1957  * compare equal though, we still have to consider whether the boundaries
1958  * are inclusive or exclusive.
1959  */
1960  if (result == 0)
1961  {
1962  if (!b1->inclusive && !b2->inclusive)
1963  {
1964  /* both are exclusive */
1965  if (b1->lower == b2->lower)
1966  return 0;
1967  else
1968  return b1->lower ? 1 : -1;
1969  }
1970  else if (!b1->inclusive)
1971  return b1->lower ? 1 : -1;
1972  else if (!b2->inclusive)
1973  return b2->lower ? -1 : 1;
1974  else
1975  {
1976  /*
1977  * Both are inclusive and the values held are equal, so they are
1978  * equal regardless of whether they are upper or lower boundaries,
1979  * or a mix.
1980  */
1981  return 0;
1982  }
1983  }
1984 
1985  return result;
1986 }
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:1151
signed int int32
Definition: c.h:429
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
bool infinite
Definition: rangetypes.h:65
Oid rng_collation
Definition: typcache.h:99

◆ range_compare()

int range_compare ( const void *  key1,
const void *  key2,
void *  arg 
)

Definition at line 2037 of file rangetypes.c.

References cmp(), range_cmp_bounds(), range_deserialize(), and RangeIOData::typcache.

Referenced by multirange_canonicalize().

2038 {
2039  RangeType *r1 = *(RangeType **) key1;
2040  RangeType *r2 = *(RangeType **) key2;
2041  TypeCacheEntry *typcache = (TypeCacheEntry *) arg;
2042  RangeBound lower1;
2043  RangeBound upper1;
2044  RangeBound lower2;
2045  RangeBound upper2;
2046  bool empty1;
2047  bool empty2;
2048  int cmp;
2049 
2050  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2051  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2052 
2053  if (empty1 && empty2)
2054  cmp = 0;
2055  else if (empty1)
2056  cmp = -1;
2057  else if (empty2)
2058  cmp = 1;
2059  else
2060  {
2061  cmp = range_cmp_bounds(typcache, &lower1, &lower2);
2062  if (cmp == 0)
2063  cmp = range_cmp_bounds(typcache, &upper1, &upper2);
2064  }
2065 
2066  return cmp;
2067 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
void * arg
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

◆ range_constructor2()

Datum range_constructor2 ( PG_FUNCTION_ARGS  )

Definition at line 359 of file rangetypes.c.

References get_fn_expr_rettype(), RangeBound::inclusive, RangeBound::infinite, lower(), RangeBound::lower, make_range(), PG_ARGISNULL, PG_GETARG_DATUM, PG_RETURN_RANGE_P, range(), range_get_typcache(), RangeIOData::typcache, upper(), and RangeBound::val.

360 {
361  Datum arg1 = PG_GETARG_DATUM(0);
362  Datum arg2 = PG_GETARG_DATUM(1);
363  Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
364  RangeType *range;
365  TypeCacheEntry *typcache;
368 
369  typcache = range_get_typcache(fcinfo, rngtypid);
370 
371  lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
372  lower.infinite = PG_ARGISNULL(0);
373  lower.inclusive = true;
374  lower.lower = true;
375 
376  upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
377  upper.infinite = PG_ARGISNULL(1);
378  upper.inclusive = false;
379  upper.lower = false;
380 
381  range = make_range(typcache, &lower, &upper, false);
382 
383  PG_RETURN_RANGE_P(range);
384 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum val
Definition: rangetypes.h:64
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
unsigned int Oid
Definition: postgres_ext.h:31
bool inclusive
Definition: rangetypes.h:66
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
bool lower
Definition: rangetypes.h:67
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
uintptr_t Datum
Definition: postgres.h:411
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1781
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
bool infinite
Definition: rangetypes.h:65

◆ range_constructor3()

Datum range_constructor3 ( PG_FUNCTION_ARGS  )

Definition at line 388 of file rangetypes.c.

References ereport, errcode(), errmsg(), ERROR, get_fn_expr_rettype(), RangeBound::inclusive, RangeBound::infinite, lower(), RangeBound::lower, make_range(), PG_ARGISNULL, PG_GETARG_DATUM, PG_GETARG_TEXT_PP, PG_RETURN_RANGE_P, range(), range_get_typcache(), RANGE_LB_INC, range_parse_flags(), RANGE_UB_INC, text_to_cstring(), RangeIOData::typcache, upper(), and RangeBound::val.

389 {
390  Datum arg1 = PG_GETARG_DATUM(0);
391  Datum arg2 = PG_GETARG_DATUM(1);
392  Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
393  RangeType *range;
394  TypeCacheEntry *typcache;
397  char flags;
398 
399  typcache = range_get_typcache(fcinfo, rngtypid);
400 
401  if (PG_ARGISNULL(2))
402  ereport(ERROR,
403  (errcode(ERRCODE_DATA_EXCEPTION),
404  errmsg("range constructor flags argument must not be null")));
405 
407 
408  lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
409  lower.infinite = PG_ARGISNULL(0);
410  lower.inclusive = (flags & RANGE_LB_INC) != 0;
411  lower.lower = true;
412 
413  upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
414  upper.infinite = PG_ARGISNULL(1);
415  upper.inclusive = (flags & RANGE_UB_INC) != 0;
416  upper.lower = false;
417 
418  range = make_range(typcache, &lower, &upper, false);
419 
420  PG_RETURN_RANGE_P(range);
421 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
static char range_parse_flags(const char *flags_str)
Definition: rangetypes.c:2103
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
bool inclusive
Definition: rangetypes.h:66
#define ERROR
Definition: elog.h:46
#define RANGE_UB_INC
Definition: rangetypes.h:40
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
bool lower
Definition: rangetypes.h:67
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
uintptr_t Datum
Definition: postgres.h:411
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1781
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define ereport(elevel,...)
Definition: elog.h:157
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
bool infinite
Definition: rangetypes.h:65
char * text_to_cstring(const text *t)
Definition: varlena.c:223
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ range_contained_by()

Datum range_contained_by ( PG_FUNCTION_ARGS  )

Definition at line 633 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contained_by_internal(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

634 {
635  RangeType *r1 = PG_GETARG_RANGE_P(0);
636  RangeType *r2 = PG_GETARG_RANGE_P(1);
637  TypeCacheEntry *typcache;
638 
639  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
640 
641  PG_RETURN_BOOL(range_contained_by_internal(typcache, r1, r2));
642 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool range_contained_by_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:2464
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_contained_by_internal()

bool range_contained_by_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 2464 of file rangetypes.c.

References range_contains_internal().

Referenced by range_contained_by(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

2465 {
2466  return range_contains_internal(typcache, r2, r1);
2467 }
bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:2432

◆ range_contains()

Datum range_contains ( PG_FUNCTION_ARGS  )

Definition at line 620 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contains_internal(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

621 {
622  RangeType *r1 = PG_GETARG_RANGE_P(0);
623  RangeType *r2 = PG_GETARG_RANGE_P(1);
624  TypeCacheEntry *typcache;
625 
626  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
627 
628  PG_RETURN_BOOL(range_contains_internal(typcache, r1, r2));
629 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
bool range_contains_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:2432
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_contains_elem()

Datum range_contains_elem ( PG_FUNCTION_ARGS  )

Definition at line 526 of file rangetypes.c.

References PG_GETARG_DATUM, PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contains_elem_internal(), range_get_typcache(), RangeTypeGetOid, RangeIOData::typcache, and val.

527 {
530  TypeCacheEntry *typcache;
531 
532  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
533 
534  PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
535 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
bool range_contains_elem_internal(TypeCacheEntry *typcache, const RangeType *r, Datum val)
Definition: rangetypes.c:2473
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
uintptr_t Datum
Definition: postgres.h:411
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
long val
Definition: informix.c:664

◆ range_contains_elem_internal()

bool range_contains_elem_internal ( TypeCacheEntry typcache,
const RangeType r,
Datum  val 
)

Definition at line 2473 of file rangetypes.c.

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

Referenced by elem_contained_by_range(), range_contains_elem(), range_gist_consistent_int_element(), range_gist_consistent_leaf_element(), and spg_range_quad_leaf_consistent().

2474 {
2475  RangeBound lower;
2476  RangeBound upper;
2477  bool empty;
2478  int32 cmp;
2479 
2480  range_deserialize(typcache, r, &lower, &upper, &empty);
2481 
2482  if (empty)
2483  return false;
2484 
2485  if (!lower.infinite)
2486  {
2488  typcache->rng_collation,
2489  lower.val, val));
2490  if (cmp > 0)
2491  return false;
2492  if (cmp == 0 && !lower.inclusive)
2493  return false;
2494  }
2495 
2496  if (!upper.infinite)
2497  {
2499  typcache->rng_collation,
2500  upper.val, val));
2501  if (cmp < 0)
2502  return false;
2503  if (cmp == 0 && !upper.inclusive)
2504  return false;
2505  }
2506 
2507  return true;
2508 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:100
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define DatumGetInt32(X)
Definition: postgres.h:516
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
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1151
signed int int32
Definition: c.h:429
bool inclusive
Definition: rangetypes.h:66
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

◆ range_contains_internal()

bool range_contains_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 2432 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_contained_by_internal(), range_contains(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), and spg_range_quad_leaf_consistent().

2433 {
2434  RangeBound lower1;
2435  RangeBound upper1;
2436  bool empty1;
2437  RangeBound lower2;
2438  RangeBound upper2;
2439  bool empty2;
2440 
2441  /* Different types should be prevented by ANYRANGE matching rules */
2442  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
2443  elog(ERROR, "range types do not match");
2444 
2445  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2446  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2447 
2448  /* If either range is empty, the answer is easy */
2449  if (empty2)
2450  return true;
2451  else if (empty1)
2452  return false;
2453 
2454  /* Else we must have lower1 <= lower2 and upper1 >= upper2 */
2455  if (range_cmp_bounds(typcache, &lower1, &lower2) > 0)
2456  return false;
2457  if (range_cmp_bounds(typcache, &upper1, &upper2) < 0)
2458  return false;
2459 
2460  return true;
2461 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_deparse()

static char * range_deparse ( char  flags,
const char *  lbound_str,
const char *  ubound_str 
)
static

Definition at line 2353 of file rangetypes.c.

References appendStringInfoChar(), appendStringInfoString(), buf, StringInfoData::data, initStringInfo(), pstrdup(), range_bound_escape(), RANGE_EMPTY, RANGE_EMPTY_LITERAL, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, and RANGE_UB_INC.

Referenced by range_out().

2354 {
2356 
2357  if (flags & RANGE_EMPTY)
2358  return pstrdup(RANGE_EMPTY_LITERAL);
2359 
2360  initStringInfo(&buf);
2361 
2362  appendStringInfoChar(&buf, (flags & RANGE_LB_INC) ? '[' : '(');
2363 
2364  if (RANGE_HAS_LBOUND(flags))
2365  appendStringInfoString(&buf, range_bound_escape(lbound_str));
2366 
2367  appendStringInfoChar(&buf, ',');
2368 
2369  if (RANGE_HAS_UBOUND(flags))
2370  appendStringInfoString(&buf, range_bound_escape(ubound_str));
2371 
2372  appendStringInfoChar(&buf, (flags & RANGE_UB_INC) ? ']' : ')');
2373 
2374  return buf.data;
2375 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.h:32
#define RANGE_EMPTY
Definition: rangetypes.h:38
char * pstrdup(const char *in)
Definition: mcxt.c:1299
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:176
static char * buf
Definition: pg_test_fsync.c:68
#define RANGE_UB_INC
Definition: rangetypes.h:40
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define RANGE_LB_INC
Definition: rangetypes.h:39
static char * range_bound_escape(const char *value)
Definition: rangetypes.c:2383

◆ range_deserialize()

void range_deserialize ( TypeCacheEntry typcache,
const RangeType range,
RangeBound lower,
RangeBound upper,
bool empty 
)

Definition at line 1788 of file rangetypes.c.

References Assert, att_addlength_pointer, att_align_pointer, fetch_att, RangeBound::inclusive, RangeBound::infinite, RangeBound::lower, RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, RangeTypeGetOid, TypeCacheEntry::rngelemtype, TypeCacheEntry::typalign, typalign, TypeCacheEntry::typbyval, TypeCacheEntry::type_id, TypeCacheEntry::typlen, RangeBound::val, and VARSIZE.

Referenced by daterange_canonical(), hash_range(), hash_range_extended(), int4range_canonical(), int8range_canonical(), range_adjacent_internal(), range_after_internal(), range_before_internal(), range_cmp(), range_compare(), range_contains_elem_internal(), range_contains_internal(), range_eq_internal(), range_intersect_internal(), range_lower(), range_minus_internal(), range_out(), range_overlaps_internal(), range_overleft_internal(), range_overright_internal(), range_send(), range_split_internal(), range_union_internal(), and range_upper().

1790 {
1791  char flags;
1792  int16 typlen;
1793  bool typbyval;
1794  char typalign;
1795  Pointer ptr;
1796  Datum lbound;
1797  Datum ubound;
1798 
1799  /* assert caller passed the right typcache entry */
1800  Assert(RangeTypeGetOid(range) == typcache->type_id);
1801 
1802  /* fetch the flag byte from datum's last byte */
1803  flags = *((const char *) range + VARSIZE(range) - 1);
1804 
1805  /* fetch information about range's element type */
1806  typlen = typcache->rngelemtype->typlen;
1807  typbyval = typcache->rngelemtype->typbyval;
1808  typalign = typcache->rngelemtype->typalign;
1809 
1810  /* initialize data pointer just after the range OID */
1811  ptr = (Pointer) (range + 1);
1812 
1813  /* fetch lower bound, if any */
1814  if (RANGE_HAS_LBOUND(flags))
1815  {
1816  /* att_align_pointer cannot be necessary here */
1817  lbound = fetch_att(ptr, typbyval, typlen);
1818  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
1819  }
1820  else
1821  lbound = (Datum) 0;
1822 
1823  /* fetch upper bound, if any */
1824  if (RANGE_HAS_UBOUND(flags))
1825  {
1826  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
1827  ubound = fetch_att(ptr, typbyval, typlen);
1828  /* no need for att_addlength_pointer */
1829  }
1830  else
1831  ubound = (Datum) 0;
1832 
1833  /* emit results */
1834 
1835  *empty = (flags & RANGE_EMPTY) != 0;
1836 
1837  lower->val = lbound;
1838  lower->infinite = (flags & RANGE_LB_INF) != 0;
1839  lower->inclusive = (flags & RANGE_LB_INC) != 0;
1840  lower->lower = true;
1841 
1842  upper->val = ubound;
1843  upper->infinite = (flags & RANGE_UB_INF) != 0;
1844  upper->inclusive = (flags & RANGE_UB_INC) != 0;
1845  upper->lower = false;
1846 }
#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
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define VARSIZE(PTR)
Definition: postgres.h:316
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
#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
#define RANGE_LB_INC
Definition: rangetypes.h:39
#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

◆ range_empty()

Datum range_empty ( PG_FUNCTION_ARGS  )

Definition at line 473 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, RANGE_EMPTY, and range_get_flags().

474 {
475  RangeType *r1 = PG_GETARG_RANGE_P(0);
476  char flags = range_get_flags(r1);
477 
478  PG_RETURN_BOOL(flags & RANGE_EMPTY);
479 }
#define RANGE_EMPTY
Definition: rangetypes.h:38
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_eq()

Datum range_eq ( PG_FUNCTION_ARGS  )

Definition at line 587 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_eq_internal(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

588 {
589  RangeType *r1 = PG_GETARG_RANGE_P(0);
590  RangeType *r2 = PG_GETARG_RANGE_P(1);
591  TypeCacheEntry *typcache;
592 
593  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
594 
595  PG_RETURN_BOOL(range_eq_internal(typcache, r1, r2));
596 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:555

◆ range_eq_internal()

bool range_eq_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 555 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_eq(), range_gist_consistent_leaf_range(), range_gist_same(), range_ne_internal(), and spg_range_quad_leaf_consistent().

556 {
557  RangeBound lower1,
558  lower2;
559  RangeBound upper1,
560  upper2;
561  bool empty1,
562  empty2;
563 
564  /* Different types should be prevented by ANYRANGE matching rules */
565  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
566  elog(ERROR, "range types do not match");
567 
568  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
569  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
570 
571  if (empty1 && empty2)
572  return true;
573  if (empty1 != empty2)
574  return false;
575 
576  if (range_cmp_bounds(typcache, &lower1, &lower2) != 0)
577  return false;
578 
579  if (range_cmp_bounds(typcache, &upper1, &upper2) != 0)
580  return false;
581 
582  return true;
583 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_ge()

Datum range_ge ( PG_FUNCTION_ARGS  )

Definition at line 1293 of file rangetypes.c.

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

1294 {
1295  int cmp = range_cmp(fcinfo);
1296 
1297  PG_RETURN_BOOL(cmp >= 0);
1298 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1231
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_get_flags()

char range_get_flags ( const RangeType range)

Definition at line 1855 of file rangetypes.c.

References VARSIZE.

Referenced by get_gist_range_class(), hash_range(), hash_range_extended(), range_empty(), range_gist_same(), range_lower_inc(), range_lower_inf(), range_out(), range_send(), range_super_union(), range_upper_inc(), and range_upper_inf().

1856 {
1857  /* fetch the flag byte from datum's last byte */
1858  return *((char *) range + VARSIZE(range) - 1);
1859 }
#define VARSIZE(PTR)
Definition: postgres.h:316

◆ range_get_typcache()

TypeCacheEntry* range_get_typcache ( FunctionCallInfo  fcinfo,
Oid  rngtypid 
)

Definition at line 1635 of file rangetypes.c.

References elog, ERROR, FunctionCallInfoBaseData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngelemtype, RangeIOData::typcache, TypeCacheEntry::type_id, and TYPECACHE_RANGE_INFO.

Referenced by daterange_canonical(), elem_contained_by_range(), hash_range(), hash_range_extended(), int4range_canonical(), int8range_canonical(), multirange_gist_consistent(), range_adjacent(), range_after(), range_before(), range_cmp(), range_constructor2(), range_constructor3(), range_contained_by(), range_contains(), range_contains_elem(), range_eq(), range_gist_consistent(), range_gist_penalty(), range_gist_picksplit(), range_gist_same(), range_gist_union(), range_intersect(), range_intersect_agg_transfn(), range_lower(), range_merge(), range_minus(), range_ne(), range_overlaps(), range_overleft(), range_overright(), range_typanalyze(), range_union(), range_upper(), rangesel(), spg_range_quad_choose(), spg_range_quad_inner_consistent(), spg_range_quad_leaf_consistent(), and spg_range_quad_picksplit().

1636 {
1637  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
1638 
1639  if (typcache == NULL ||
1640  typcache->type_id != rngtypid)
1641  {
1642  typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
1643  if (typcache->rngelemtype == NULL)
1644  elog(ERROR, "type %u is not a range type", rngtypid);
1645  fcinfo->flinfo->fn_extra = (void *) typcache;
1646  }
1647 
1648  return typcache;
1649 }
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:147
#define ERROR
Definition: elog.h:46
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:338
void * fn_extra
Definition: fmgr.h:64
#define elog(elevel,...)
Definition: elog.h:232

◆ range_gt()

Datum range_gt ( PG_FUNCTION_ARGS  )

Definition at line 1301 of file rangetypes.c.

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

1302 {
1303  int cmp = range_cmp(fcinfo);
1304 
1305  PG_RETURN_BOOL(cmp > 0);
1306 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1231
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_in()

Datum range_in ( PG_FUNCTION_ARGS  )

Definition at line 78 of file rangetypes.c.

References check_stack_depth(), get_range_io_data(), RangeBound::inclusive, RangeBound::infinite, InputFunctionCall(), IOFunc_input, lower(), RangeBound::lower, make_range(), PG_GETARG_CSTRING, PG_GETARG_INT32, PG_GETARG_OID, PG_RETURN_RANGE_P, range(), RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, range_parse(), RANGE_UB_INC, RANGE_UB_INF, RangeIOData::typcache, RangeIOData::typioparam, RangeIOData::typioproc, upper(), and RangeBound::val.

79 {
80  char *input_str = PG_GETARG_CSTRING(0);
81  Oid rngtypoid = PG_GETARG_OID(1);
82  Oid typmod = PG_GETARG_INT32(2);
84  RangeIOData *cache;
85  char flags;
86  char *lbound_str;
87  char *ubound_str;
90 
91  check_stack_depth(); /* recurses when subtype is a range type */
92 
93  cache = get_range_io_data(fcinfo, rngtypoid, IOFunc_input);
94 
95  /* parse */
96  range_parse(input_str, &flags, &lbound_str, &ubound_str);
97 
98  /* call element type's input function */
99  if (RANGE_HAS_LBOUND(flags))
100  lower.val = InputFunctionCall(&cache->typioproc, lbound_str,
101  cache->typioparam, typmod);
102  if (RANGE_HAS_UBOUND(flags))
103  upper.val = InputFunctionCall(&cache->typioproc, ubound_str,
104  cache->typioparam, typmod);
105 
106  lower.infinite = (flags & RANGE_LB_INF) != 0;
107  lower.inclusive = (flags & RANGE_LB_INC) != 0;
108  lower.lower = true;
109  upper.infinite = (flags & RANGE_UB_INF) != 0;
110  upper.inclusive = (flags & RANGE_UB_INC) != 0;
111  upper.lower = false;
112 
113  /* serialize and canonicalize */
114  range = make_range(cache->typcache, &lower, &upper, flags & RANGE_EMPTY);
115 
116  PG_RETURN_RANGE_P(range);
117 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define RANGE_EMPTY
Definition: rangetypes.h:38
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum val
Definition: rangetypes.h:64
static void range_parse(const char *input_str, char *flags, char **lbound_str, char **ubound_str)
Definition: rangetypes.c:2175
TypeCacheEntry * typcache
Definition: rangetypes.c:49
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
unsigned int Oid
Definition: postgres_ext.h:31
#define RANGE_LB_INF
Definition: rangetypes.h:41
bool inclusive
Definition: rangetypes.h:66
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
void check_stack_depth(void)
Definition: postgres.c:3441
#define RANGE_UB_INC
Definition: rangetypes.h:40
FmgrInfo typioproc
Definition: rangetypes.c:50
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
bool lower
Definition: rangetypes.h:67
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define RANGE_LB_INC
Definition: rangetypes.h:39
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1532
bool infinite
Definition: rangetypes.h:65
#define RANGE_UB_INF
Definition: rangetypes.h:42
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:299
Oid typioparam
Definition: rangetypes.c:51

◆ range_intersect()

Datum range_intersect ( PG_FUNCTION_ARGS  )

Definition at line 1109 of file rangetypes.c.

References elog, ERROR, PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_get_typcache(), range_intersect_internal(), RangeTypeGetOid, and RangeIOData::typcache.

1110 {
1111  RangeType *r1 = PG_GETARG_RANGE_P(0);
1112  RangeType *r2 = PG_GETARG_RANGE_P(1);
1113  TypeCacheEntry *typcache;
1114 
1115  /* Different types should be prevented by ANYRANGE matching rules */
1116  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1117  elog(ERROR, "range types do not match");
1118 
1119  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1120 
1121  PG_RETURN_RANGE_P(range_intersect_internal(typcache, r1, r2));
1122 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:1125
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define elog(elevel,...)
Definition: elog.h:232

◆ range_intersect_agg_transfn()

Datum range_intersect_agg_transfn ( PG_FUNCTION_ARGS  )

Definition at line 1201 of file rangetypes.c.

References AggCheckCallContext(), elog, ereport, errmsg(), ERROR, get_fn_expr_argtype(), PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_get_typcache(), range_intersect_internal(), RangeIOData::typcache, and type_is_range().

1202 {
1203  MemoryContext aggContext;
1204  Oid rngtypoid;
1205  TypeCacheEntry *typcache;
1206  RangeType *result;
1207  RangeType *current;
1208 
1209  if (!AggCheckCallContext(fcinfo, &aggContext))
1210  elog(ERROR, "range_intersect_agg_transfn called in non-aggregate context");
1211 
1212  rngtypoid = get_fn_expr_argtype(fcinfo->flinfo, 1);
1213  if (!type_is_range(rngtypoid))
1214  ereport(ERROR, (errmsg("range_intersect_agg must be called with a range")));
1215 
1216  typcache = range_get_typcache(fcinfo, rngtypoid);
1217 
1218  /* strictness ensures these are non-null */
1219  result = PG_GETARG_RANGE_P(0);
1220  current = PG_GETARG_RANGE_P(1);
1221 
1222  result = range_intersect_internal(typcache, result, current);
1223  PG_RETURN_RANGE_P(result);
1224 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
bool type_is_range(Oid typid)
Definition: lsyscache.c:2635
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:1803
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define ereport(elevel,...)
Definition: elog.h:157
RangeType * range_intersect_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:1125
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext *aggcontext)
Definition: nodeAgg.c:4587
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232

◆ range_intersect_internal()

RangeType* range_intersect_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 1125 of file rangetypes.c.

References make_empty_range(), make_range(), range_cmp_bounds(), range_deserialize(), and range_overlaps_internal().

Referenced by multirange_intersect_internal(), range_intersect(), and range_intersect_agg_transfn().

1126 {
1127  RangeBound lower1,
1128  lower2;
1129  RangeBound upper1,
1130  upper2;
1131  bool empty1,
1132  empty2;
1133  RangeBound *result_lower;
1134  RangeBound *result_upper;
1135 
1136  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1137  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1138 
1139  if (empty1 || empty2 || !range_overlaps_internal(typcache, r1, r2))
1140  return make_empty_range(typcache);
1141 
1142  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
1143  result_lower = &lower1;
1144  else
1145  result_lower = &lower2;
1146 
1147  if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
1148  result_upper = &upper1;
1149  else
1150  result_upper = &upper2;
1151 
1152  return make_range(typcache, result_lower, result_upper, false);
1153 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_le()

Datum range_le ( PG_FUNCTION_ARGS  )

Definition at line 1285 of file rangetypes.c.

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

1286 {
1287  int cmp = range_cmp(fcinfo);
1288 
1289  PG_RETURN_BOOL(cmp <= 0);
1290 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1231
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_lower()

Datum range_lower ( PG_FUNCTION_ARGS  )

Definition at line 428 of file rangetypes.c.

References RangeBound::infinite, lower(), PG_GETARG_RANGE_P, PG_RETURN_DATUM, PG_RETURN_NULL, range_deserialize(), range_get_typcache(), RangeTypeGetOid, RangeIOData::typcache, upper(), and RangeBound::val.

429 {
430  RangeType *r1 = PG_GETARG_RANGE_P(0);
431  TypeCacheEntry *typcache;
434  bool empty;
435 
436  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
437 
438  range_deserialize(typcache, r1, &lower, &upper, &empty);
439 
440  /* Return NULL if there's no finite lower bound */
441  if (empty || lower.infinite)
442  PG_RETURN_NULL();
443 
444  PG_RETURN_DATUM(lower.val);
445 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
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
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:65
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ range_lower_inc()

Datum range_lower_inc ( PG_FUNCTION_ARGS  )

Definition at line 483 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_flags(), and RANGE_LB_INC.

484 {
485  RangeType *r1 = PG_GETARG_RANGE_P(0);
486  char flags = range_get_flags(r1);
487 
488  PG_RETURN_BOOL(flags & RANGE_LB_INC);
489 }
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_lower_inf()

Datum range_lower_inf ( PG_FUNCTION_ARGS  )

Definition at line 503 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_flags(), and RANGE_LB_INF.

504 {
505  RangeType *r1 = PG_GETARG_RANGE_P(0);
506  char flags = range_get_flags(r1);
507 
508  PG_RETURN_BOOL(flags & RANGE_LB_INF);
509 }
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
#define RANGE_LB_INF
Definition: rangetypes.h:41
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_lt()

Datum range_lt ( PG_FUNCTION_ARGS  )

Definition at line 1277 of file rangetypes.c.

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

1278 {
1279  int cmp = range_cmp(fcinfo);
1280 
1281  PG_RETURN_BOOL(cmp < 0);
1282 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1231
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_merge()

Datum range_merge ( PG_FUNCTION_ARGS  )

Definition at line 1096 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_get_typcache(), range_union_internal(), RangeTypeGetOid, and RangeIOData::typcache.

1097 {
1098  RangeType *r1 = PG_GETARG_RANGE_P(0);
1099  RangeType *r2 = PG_GETARG_RANGE_P(1);
1100  TypeCacheEntry *typcache;
1101 
1102  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1103 
1104  PG_RETURN_RANGE_P(range_union_internal(typcache, r1, r2, false));
1105 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
Definition: rangetypes.c:1034
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_minus()

Datum range_minus ( PG_FUNCTION_ARGS  )

Definition at line 954 of file rangetypes.c.

References elog, ERROR, PG_GETARG_RANGE_P, PG_RETURN_NULL, PG_RETURN_RANGE_P, range_get_typcache(), range_minus_internal(), RangeTypeGetOid, and RangeIOData::typcache.

955 {
956  RangeType *r1 = PG_GETARG_RANGE_P(0);
957  RangeType *r2 = PG_GETARG_RANGE_P(1);
958  RangeType *ret;
959  TypeCacheEntry *typcache;
960 
961  /* Different types should be prevented by ANYRANGE matching rules */
962  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
963  elog(ERROR, "range types do not match");
964 
965  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
966 
967  ret = range_minus_internal(typcache, r1, r2);
968  if (ret)
969  PG_RETURN_RANGE_P(ret);
970  else
971  PG_RETURN_NULL();
972 }
RangeType * range_minus_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:975
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define elog(elevel,...)
Definition: elog.h:232
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ range_minus_internal()

RangeType* range_minus_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2 
)

Definition at line 975 of file rangetypes.c.

References elog, ereport, errcode(), errmsg(), ERROR, RangeBound::inclusive, RangeBound::lower, make_empty_range(), make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_minus_internal(), and range_minus().

976 {
977  RangeBound lower1,
978  lower2;
979  RangeBound upper1,
980  upper2;
981  bool empty1,
982  empty2;
983  int cmp_l1l2,
984  cmp_l1u2,
985  cmp_u1l2,
986  cmp_u1u2;
987 
988  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
989  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
990 
991  /* if either is empty, r1 is the correct answer */
992  if (empty1 || empty2)
993  return r1;
994 
995  cmp_l1l2 = range_cmp_bounds(typcache, &lower1, &lower2);
996  cmp_l1u2 = range_cmp_bounds(typcache, &lower1, &upper2);
997  cmp_u1l2 = range_cmp_bounds(typcache, &upper1, &lower2);
998  cmp_u1u2 = range_cmp_bounds(typcache, &upper1, &upper2);
999 
1000  if (cmp_l1l2 < 0 && cmp_u1u2 > 0)
1001  ereport(ERROR,
1002  (errcode(ERRCODE_DATA_EXCEPTION),
1003  errmsg("result of range difference would not be contiguous")));
1004 
1005  if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
1006  return r1;
1007 
1008  if (cmp_l1l2 >= 0 && cmp_u1u2 <= 0)
1009  return make_empty_range(typcache);
1010 
1011  if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0)
1012  {
1013  lower2.inclusive = !lower2.inclusive;
1014  lower2.lower = false; /* it will become the upper bound */
1015  return make_range(typcache, &lower1, &lower2, false);
1016  }
1017 
1018  if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0)
1019  {
1020  upper2.inclusive = !upper2.inclusive;
1021  upper2.lower = true; /* it will become the lower bound */
1022  return make_range(typcache, &upper2, &upper1, false);
1023  }
1024 
1025  elog(ERROR, "unexpected case in range_minus");
1026  return NULL;
1027 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
int errcode(int sqlerrcode)
Definition: elog.c:698
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:2073
bool inclusive
Definition: rangetypes.h:66
#define ERROR
Definition: elog.h:46
bool lower
Definition: rangetypes.h:67
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_ne()

Datum range_ne ( PG_FUNCTION_ARGS  )

Definition at line 607 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_ne_internal(), RangeTypeGetOid, and RangeIOData::typcache.

608 {
609  RangeType *r1 = PG_GETARG_RANGE_P(0);
610  RangeType *r2 = PG_GETARG_RANGE_P(1);
611  TypeCacheEntry *typcache;
612 
613  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
614 
615  PG_RETURN_BOOL(range_ne_internal(typcache, r1, r2));
616 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
bool range_ne_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:600
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_ne_internal()

bool range_ne_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 600 of file rangetypes.c.

References range_eq_internal().

Referenced by range_ne().

601 {
602  return (!range_eq_internal(typcache, r1, r2));
603 }
bool range_eq_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:555

◆ range_out()

Datum range_out ( PG_FUNCTION_ARGS  )

Definition at line 120 of file rangetypes.c.

References check_stack_depth(), get_range_io_data(), IOFunc_output, lower(), OutputFunctionCall(), PG_GETARG_RANGE_P, PG_RETURN_CSTRING, range(), range_deparse(), range_deserialize(), range_get_flags(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeTypeGetOid, RangeIOData::typcache, RangeIOData::typioproc, upper(), and RangeBound::val.

Referenced by anycompatiblerange_out(), and anyrange_out().

121 {
123  char *output_str;
124  RangeIOData *cache;
125  char flags;
126  char *lbound_str = NULL;
127  char *ubound_str = NULL;
130  bool empty;
131 
132  check_stack_depth(); /* recurses when subtype is a range type */
133 
134  cache = get_range_io_data(fcinfo, RangeTypeGetOid(range), IOFunc_output);
135 
136  /* deserialize */
137  range_deserialize(cache->typcache, range, &lower, &upper, &empty);
138  flags = range_get_flags(range);
139 
140  /* call element type's output function */
141  if (RANGE_HAS_LBOUND(flags))
142  lbound_str = OutputFunctionCall(&cache->typioproc, lower.val);
143  if (RANGE_HAS_UBOUND(flags))
144  ubound_str = OutputFunctionCall(&cache->typioproc, upper.val);
145 
146  /* construct result string */
147  output_str = range_deparse(flags, lbound_str, ubound_str);
148 
149  PG_RETURN_CSTRING(output_str);
150 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
Datum val
Definition: rangetypes.h:64
TypeCacheEntry * typcache
Definition: rangetypes.c:49
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1576
static char * range_deparse(char flags, const char *lbound_str, const char *ubound_str)
Definition: rangetypes.c:2353
void check_stack_depth(void)
Definition: postgres.c:3441
FmgrInfo typioproc
Definition: rangetypes.c:50
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:299

◆ range_overlaps()

Datum range_overlaps ( PG_FUNCTION_ARGS  )

Definition at line 856 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_overlaps_internal(), RangeTypeGetOid, and RangeIOData::typcache.

857 {
858  RangeType *r1 = PG_GETARG_RANGE_P(0);
859  RangeType *r2 = PG_GETARG_RANGE_P(1);
860  TypeCacheEntry *typcache;
861 
862  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
863 
864  PG_RETURN_BOOL(range_overlaps_internal(typcache, r1, r2));
865 }
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_overlaps_internal()

bool range_overlaps_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 823 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_intersect_internal(), multirange_minus_internal(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_intersect_internal(), range_overlaps(), range_union_internal(), and spg_range_quad_leaf_consistent().

824 {
825  RangeBound lower1,
826  lower2;
827  RangeBound upper1,
828  upper2;
829  bool empty1,
830  empty2;
831 
832  /* Different types should be prevented by ANYRANGE matching rules */
833  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
834  elog(ERROR, "range types do not match");
835 
836  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
837  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
838 
839  /* An empty range does not overlap any other range */
840  if (empty1 || empty2)
841  return false;
842 
843  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0 &&
844  range_cmp_bounds(typcache, &lower1, &upper2) <= 0)
845  return true;
846 
847  if (range_cmp_bounds(typcache, &lower2, &lower1) >= 0 &&
848  range_cmp_bounds(typcache, &lower2, &upper1) <= 0)
849  return true;
850 
851  return false;
852 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_overleft()

Datum range_overleft ( PG_FUNCTION_ARGS  )

Definition at line 897 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_overleft_internal(), RangeTypeGetOid, and RangeIOData::typcache.

898 {
899  RangeType *r1 = PG_GETARG_RANGE_P(0);
900  RangeType *r2 = PG_GETARG_RANGE_P(1);
901  TypeCacheEntry *typcache;
902 
903  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
904 
905  PG_RETURN_BOOL(range_overleft_internal(typcache, r1, r2));
906 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
bool range_overleft_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:869
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_overleft_internal()

bool range_overleft_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 869 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by multirange_intersect_internal(), range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_overleft(), and spg_range_quad_leaf_consistent().

870 {
871  RangeBound lower1,
872  lower2;
873  RangeBound upper1,
874  upper2;
875  bool empty1,
876  empty2;
877 
878  /* Different types should be prevented by ANYRANGE matching rules */
879  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
880  elog(ERROR, "range types do not match");
881 
882  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
883  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
884 
885  /* An empty range is neither before nor after any other range */
886  if (empty1 || empty2)
887  return false;
888 
889  if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
890  return true;
891 
892  return false;
893 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_overright()

Datum range_overright ( PG_FUNCTION_ARGS  )

Definition at line 938 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_overright_internal(), RangeTypeGetOid, and RangeIOData::typcache.

939 {
940  RangeType *r1 = PG_GETARG_RANGE_P(0);
941  RangeType *r2 = PG_GETARG_RANGE_P(1);
942  TypeCacheEntry *typcache;
943 
944  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
945 
946  PG_RETURN_BOOL(range_overright_internal(typcache, r1, r2));
947 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool range_overright_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:910

◆ range_overright_internal()

bool range_overright_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2 
)

Definition at line 910 of file rangetypes.c.

References elog, ERROR, range_cmp_bounds(), range_deserialize(), and RangeTypeGetOid.

Referenced by range_gist_consistent_int_range(), range_gist_consistent_leaf_range(), range_overright(), and spg_range_quad_leaf_consistent().

911 {
912  RangeBound lower1,
913  lower2;
914  RangeBound upper1,
915  upper2;
916  bool empty1,
917  empty2;
918 
919  /* Different types should be prevented by ANYRANGE matching rules */
920  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
921  elog(ERROR, "range types do not match");
922 
923  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
924  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
925 
926  /* An empty range is neither before nor after any other range */
927  if (empty1 || empty2)
928  return false;
929 
930  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
931  return true;
932 
933  return false;
934 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define ERROR
Definition: elog.h:46
#define elog(elevel,...)
Definition: elog.h:232
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_parse()

static void range_parse ( const char *  input_str,
char *  flags,
char **  lbound_str,
char **  ubound_str 
)
static

Definition at line 2175 of file rangetypes.c.

References ereport, errcode(), errdetail(), errmsg(), ERROR, pg_strncasecmp(), RANGE_EMPTY, RANGE_EMPTY_LITERAL, RANGE_LB_INC, RANGE_LB_INF, range_parse_bound(), RANGE_UB_INC, and RANGE_UB_INF.

Referenced by range_in().

2177 {
2178  const char *ptr = string;
2179  bool infinite;
2180 
2181  *flags = 0;
2182 
2183  /* consume whitespace */
2184  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2185  ptr++;
2186 
2187  /* check for empty range */
2189  strlen(RANGE_EMPTY_LITERAL)) == 0)
2190  {
2191  *flags = RANGE_EMPTY;
2192  *lbound_str = NULL;
2193  *ubound_str = NULL;
2194 
2195  ptr += strlen(RANGE_EMPTY_LITERAL);
2196 
2197  /* the rest should be whitespace */
2198  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2199  ptr++;
2200 
2201  /* should have consumed everything */
2202  if (*ptr != '\0')
2203  ereport(ERROR,
2204  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2205  errmsg("malformed range literal: \"%s\"",
2206  string),
2207  errdetail("Junk after \"empty\" key word.")));
2208 
2209  return;
2210  }
2211 
2212  if (*ptr == '[')
2213  {
2214  *flags |= RANGE_LB_INC;
2215  ptr++;
2216  }
2217  else if (*ptr == '(')
2218  ptr++;
2219  else
2220  ereport(ERROR,
2221  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2222  errmsg("malformed range literal: \"%s\"",
2223  string),
2224  errdetail("Missing left parenthesis or bracket.")));
2225 
2226  ptr = range_parse_bound(string, ptr, lbound_str, &infinite);
2227  if (infinite)
2228  *flags |= RANGE_LB_INF;
2229 
2230  if (*ptr == ',')
2231  ptr++;
2232  else
2233  ereport(ERROR,
2234  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2235  errmsg("malformed range literal: \"%s\"",
2236  string),
2237  errdetail("Missing comma after lower bound.")));
2238 
2239  ptr = range_parse_bound(string, ptr, ubound_str, &infinite);
2240  if (infinite)
2241  *flags |= RANGE_UB_INF;
2242 
2243  if (*ptr == ']')
2244  {
2245  *flags |= RANGE_UB_INC;
2246  ptr++;
2247  }
2248  else if (*ptr == ')')
2249  ptr++;
2250  else /* must be a comma */
2251  ereport(ERROR,
2252  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2253  errmsg("malformed range literal: \"%s\"",
2254  string),
2255  errdetail("Too many commas.")));
2256 
2257  /* consume whitespace */
2258  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2259  ptr++;
2260 
2261  if (*ptr != '\0')
2262  ereport(ERROR,
2263  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2264  errmsg("malformed range literal: \"%s\"",
2265  string),
2266  errdetail("Junk after right parenthesis or bracket.")));
2267 }
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.h:32
#define RANGE_EMPTY
Definition: rangetypes.h:38
int errcode(int sqlerrcode)
Definition: elog.c:698
#define RANGE_LB_INF
Definition: rangetypes.h:41
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define ERROR
Definition: elog.h:46
#define RANGE_UB_INC
Definition: rangetypes.h:40
int errdetail(const char *fmt,...)
Definition: elog.c:1042
char string[11]
Definition: preproc-type.c:46
static const char * range_parse_bound(const char *string, const char *ptr, char **bound_str, bool *infinite)
Definition: rangetypes.c:2284
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define ereport(elevel,...)
Definition: elog.h:157
#define RANGE_UB_INF
Definition: rangetypes.h:42
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ range_parse_bound()

static const char * range_parse_bound ( const char *  string,
const char *  ptr,
char **  bound_str,
bool infinite 
)
static

Definition at line 2284 of file rangetypes.c.

References appendStringInfoChar(), buf, StringInfoData::data, ereport, errcode(), errdetail(), errmsg(), ERROR, and initStringInfo().

Referenced by range_parse().

2286 {
2288 
2289  /* Check for null: completely empty input means null */
2290  if (*ptr == ',' || *ptr == ')' || *ptr == ']')
2291  {
2292  *bound_str = NULL;
2293  *infinite = true;
2294  }
2295  else
2296  {
2297  /* Extract string for this bound */
2298  bool inquote = false;
2299 
2300  initStringInfo(&buf);
2301  while (inquote || !(*ptr == ',' || *ptr == ')' || *ptr == ']'))
2302  {
2303  char ch = *ptr++;
2304 
2305  if (ch == '\0')
2306  ereport(ERROR,
2307  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2308  errmsg("malformed range literal: \"%s\"",
2309  string),
2310  errdetail("Unexpected end of input.")));
2311  if (ch == '\\')
2312  {
2313  if (*ptr == '\0')
2314  ereport(ERROR,
2315  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2316  errmsg("malformed range literal: \"%s\"",
2317  string),
2318  errdetail("Unexpected end of input.")));
2319  appendStringInfoChar(&buf, *ptr++);
2320  }
2321  else if (ch == '"')
2322  {
2323  if (!inquote)
2324  inquote = true;
2325  else if (*ptr == '"')
2326  {
2327  /* doubled quote within quote sequence */
2328  appendStringInfoChar(&buf, *ptr++);
2329  }
2330  else
2331  inquote = false;
2332  }
2333  else
2334  appendStringInfoChar(&buf, ch);
2335  }
2336 
2337  *bound_str = buf.data;
2338  *infinite = false;
2339  }
2340 
2341  return ptr;
2342 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
static char * buf
Definition: pg_test_fsync.c:68
int errdetail(const char *fmt,...)
Definition: elog.c:1042
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:188
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ range_parse_flags()

static char range_parse_flags ( const char *  flags_str)
static

Definition at line 2103 of file rangetypes.c.

References ereport, errcode(), errhint(), errmsg(), ERROR, RANGE_LB_INC, and RANGE_UB_INC.

Referenced by range_constructor3().

2104 {
2105  char flags = 0;
2106 
2107  if (flags_str[0] == '\0' ||
2108  flags_str[1] == '\0' ||
2109  flags_str[2] != '\0')
2110  ereport(ERROR,
2111  (errcode(ERRCODE_SYNTAX_ERROR),
2112  errmsg("invalid range bound flags"),
2113  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
2114 
2115  switch (flags_str[0])
2116  {
2117  case '[':
2118  flags |= RANGE_LB_INC;
2119  break;
2120  case '(':
2121  break;
2122  default:
2123  ereport(ERROR,
2124  (errcode(ERRCODE_SYNTAX_ERROR),
2125  errmsg("invalid range bound flags"),
2126  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
2127  }
2128 
2129  switch (flags_str[1])
2130  {
2131  case ']':
2132  flags |= RANGE_UB_INC;
2133  break;
2134  case ')':
2135  break;
2136  default:
2137  ereport(ERROR,
2138  (errcode(ERRCODE_SYNTAX_ERROR),
2139  errmsg("invalid range bound flags"),
2140  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
2141  }
2142 
2143  return flags;
2144 }
int errhint(const char *fmt,...)
Definition: elog.c:1156
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define RANGE_UB_INC
Definition: rangetypes.h:40
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ range_recv()

Datum range_recv ( PG_FUNCTION_ARGS  )

Definition at line 160 of file rangetypes.c.

References appendBinaryStringInfo(), buf, check_stack_depth(), StringInfoData::data, get_range_io_data(), RangeBound::inclusive, RangeBound::infinite, initStringInfo(), IOFunc_receive, lower(), RangeBound::lower, make_range(), pfree(), PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, PG_RETURN_RANGE_P, pq_getmsgbyte(), pq_getmsgbytes(), pq_getmsgend(), pq_getmsgint(), range(), RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, ReceiveFunctionCall(), RangeIOData::typcache, RangeIOData::typioparam, RangeIOData::typioproc, upper(), and RangeBound::val.

161 {
163  Oid rngtypoid = PG_GETARG_OID(1);
164  int32 typmod = PG_GETARG_INT32(2);
165  RangeType *range;
166  RangeIOData *cache;
167  char flags;
170 
171  check_stack_depth(); /* recurses when subtype is a range type */
172 
173  cache = get_range_io_data(fcinfo, rngtypoid, IOFunc_receive);
174 
175  /* receive the flags... */
176  flags = (unsigned char) pq_getmsgbyte(buf);
177 
178  /*
179  * Mask out any unsupported flags, particularly RANGE_xB_NULL which would
180  * confuse following tests. Note that range_serialize will take care of
181  * cleaning up any inconsistencies in the remaining flags.
182  */
183  flags &= (RANGE_EMPTY |
184  RANGE_LB_INC |
185  RANGE_LB_INF |
186  RANGE_UB_INC |
187  RANGE_UB_INF);
188 
189  /* receive the bounds ... */
190  if (RANGE_HAS_LBOUND(flags))
191  {
192  uint32 bound_len = pq_getmsgint(buf, 4);
193  const char *bound_data = pq_getmsgbytes(buf, bound_len);
194  StringInfoData bound_buf;
195 
196  initStringInfo(&bound_buf);
197  appendBinaryStringInfo(&bound_buf, bound_data, bound_len);
198 
199  lower.val = ReceiveFunctionCall(&cache->typioproc,
200  &bound_buf,
201  cache->typioparam,
202  typmod);
203  pfree(bound_buf.data);
204  }
205  else
206  lower.val = (Datum) 0;
207 
208  if (RANGE_HAS_UBOUND(flags))
209  {
210  uint32 bound_len = pq_getmsgint(buf, 4);
211  const char *bound_data = pq_getmsgbytes(buf, bound_len);
212  StringInfoData bound_buf;
213 
214  initStringInfo(&bound_buf);
215  appendBinaryStringInfo(&bound_buf, bound_data, bound_len);
216 
217  upper.val = ReceiveFunctionCall(&cache->typioproc,
218  &bound_buf,
219  cache->typioparam,
220  typmod);
221  pfree(bound_buf.data);
222  }
223  else
224  upper.val = (Datum) 0;
225 
226  pq_getmsgend(buf);
227 
228  /* finish constructing RangeBound representation */
229  lower.infinite = (flags & RANGE_LB_INF) != 0;
230  lower.inclusive = (flags & RANGE_LB_INC) != 0;
231  lower.lower = true;
232  upper.infinite = (flags & RANGE_UB_INF) != 0;
233  upper.inclusive = (flags & RANGE_UB_INC) != 0;
234  upper.lower = false;
235 
236  /* serialize and canonicalize */
237  range = make_range(cache->typcache, &lower, &upper, flags & RANGE_EMPTY);
238 
239  PG_RETURN_RANGE_P(range);
240 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define RANGE_EMPTY
Definition: rangetypes.h:38
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
StringInfoData * StringInfo
Definition: stringinfo.h:44
Datum val
Definition: rangetypes.h:64
TypeCacheEntry * typcache
Definition: rangetypes.c:49
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
unsigned int Oid
Definition: postgres_ext.h:31
#define RANGE_LB_INF
Definition: rangetypes.h:41
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:510
signed int int32
Definition: c.h:429
void pfree(void *pointer)
Definition: mcxt.c:1169
bool inclusive
Definition: rangetypes.h:66
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
Definition: fmgr.c:1590
static char * buf
Definition: pg_test_fsync.c:68
#define PG_GETARG_OID(n)
Definition: fmgr.h:275
void check_stack_depth(void)
Definition: postgres.c:3441
#define RANGE_UB_INC
Definition: rangetypes.h:40
unsigned int uint32
Definition: c.h:441
FmgrInfo typioproc
Definition: rangetypes.c:50
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
bool lower
Definition: rangetypes.h:67
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
uintptr_t Datum
Definition: postgres.h:411
#define RANGE_LB_INC
Definition: rangetypes.h:39
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:401
bool infinite
Definition: rangetypes.h:65
#define RANGE_UB_INF
Definition: rangetypes.h:42
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:417
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:637
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:299
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:227
Oid typioparam
Definition: rangetypes.c:51

◆ range_send()

Datum range_send ( PG_FUNCTION_ARGS  )

Definition at line 243 of file rangetypes.c.

References buf, check_stack_depth(), get_range_io_data(), IOFunc_send, lower(), makeStringInfo(), PG_GETARG_RANGE_P, PG_RETURN_BYTEA_P, PointerGetDatum, pq_begintypsend(), pq_endtypsend(), pq_sendbyte(), pq_sendbytes(), pq_sendint32(), range(), range_deserialize(), range_get_flags(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeTypeGetOid, SendFunctionCall(), RangeIOData::typcache, RangeIOData::typioproc, upper(), RangeBound::val, VARDATA, VARHDRSZ, and VARSIZE.

244 {
247  RangeIOData *cache;
248  char flags;
251  bool empty;
252 
253  check_stack_depth(); /* recurses when subtype is a range type */
254 
255  cache = get_range_io_data(fcinfo, RangeTypeGetOid(range), IOFunc_send);
256 
257  /* deserialize */
258  range_deserialize(cache->typcache, range, &lower, &upper, &empty);
259  flags = range_get_flags(range);
260 
261  /* construct output */
262  pq_begintypsend(buf);
263 
264  pq_sendbyte(buf, flags);
265 
266  if (RANGE_HAS_LBOUND(flags))
267  {
269  lower.val));
270  uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
271  char *bound_data = VARDATA(bound);
272 
273  pq_sendint32(buf, bound_len);
274  pq_sendbytes(buf, bound_data, bound_len);
275  }
276 
277  if (RANGE_HAS_UBOUND(flags))
278  {
280  upper.val));
281  uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
282  char *bound_data = VARDATA(bound);
283 
284  pq_sendint32(buf, bound_len);
285  pq_sendbytes(buf, bound_data, bound_len);
286  }
287 
289 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:52
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:48
#define VARDATA(PTR)
Definition: postgres.h:315
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:46
#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
Datum val
Definition: rangetypes.h:64
TypeCacheEntry * typcache
Definition: rangetypes.c:49
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:77
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
static void pq_sendbyte(StringInfo buf, uint8 byt)
Definition: pqformat.h:161
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:145
static char * buf
Definition: pg_test_fsync.c:68
void check_stack_depth(void)
Definition: postgres.c:3441
unsigned int uint32
Definition: c.h:441
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1637
FmgrInfo typioproc
Definition: rangetypes.c:50
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
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:299

◆ range_serialize()

RangeType* range_serialize ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

Definition at line 1659 of file rangetypes.c.

References Assert, cmp(), datum_compute_size(), datum_write(), ereport, errcode(), errmsg(), ERROR, RangeBound::inclusive, RangeBound::infinite, RangeBound::lower, MAXALIGN, palloc0(), PG_DETOAST_DATUM_PACKED, PointerGetDatum, range(), range_cmp_bound_values(), RANGE_EMPTY, RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RANGE_LB_INC, RANGE_LB_INF, RANGE_UB_INC, RANGE_UB_INF, RangeType::rangetypid, TypeCacheEntry::rngelemtype, SET_VARSIZE, TypeCacheEntry::typalign, typalign, TypeCacheEntry::typbyval, TypeCacheEntry::type_id, TypeCacheEntry::typlen, TypeCacheEntry::typstorage, and RangeBound::val.

Referenced by daterange_canonical(), int4range_canonical(), int8range_canonical(), and make_range().

1661 {
1662  RangeType *range;
1663  int cmp;
1664  Size msize;
1665  Pointer ptr;
1666  int16 typlen;
1667  bool typbyval;
1668  char typalign;
1669  char typstorage;
1670  char flags = 0;
1671 
1672  /*
1673  * Verify range is not invalid on its face, and construct flags value,
1674  * preventing any non-canonical combinations such as infinite+inclusive.
1675  */
1676  Assert(lower->lower);
1677  Assert(!upper->lower);
1678 
1679  if (empty)
1680  flags |= RANGE_EMPTY;
1681  else
1682  {
1683  cmp = range_cmp_bound_values(typcache, lower, upper);
1684 
1685  /* error check: if lower bound value is above upper, it's wrong */
1686  if (cmp > 0)
1687  ereport(ERROR,
1688  (errcode(ERRCODE_DATA_EXCEPTION),
1689  errmsg("range lower bound must be less than or equal to range upper bound")));
1690 
1691  /* if bounds are equal, and not both inclusive, range is empty */
1692  if (cmp == 0 && !(lower->inclusive && upper->inclusive))
1693  flags |= RANGE_EMPTY;
1694  else
1695  {
1696  /* infinite boundaries are never inclusive */
1697  if (lower->infinite)
1698  flags |= RANGE_LB_INF;
1699  else if (lower->inclusive)
1700  flags |= RANGE_LB_INC;
1701  if (upper->infinite)
1702  flags |= RANGE_UB_INF;
1703  else if (upper->inclusive)
1704  flags |= RANGE_UB_INC;
1705  }
1706  }
1707 
1708  /* Fetch information about range's element type */
1709  typlen = typcache->rngelemtype->typlen;
1710  typbyval = typcache->rngelemtype->typbyval;
1711  typalign = typcache->rngelemtype->typalign;
1712  typstorage = typcache->rngelemtype->typstorage;
1713 
1714  /* Count space for varlena header and range type's OID */
1715  msize = sizeof(RangeType);
1716  Assert(msize == MAXALIGN(msize));
1717 
1718  /* Count space for bounds */
1719  if (RANGE_HAS_LBOUND(flags))
1720  {
1721  /*
1722  * Make sure item to be inserted is not toasted. It is essential that
1723  * we not insert an out-of-line toast value pointer into a range
1724  * object, for the same reasons that arrays and records can't contain
1725  * them. It would work to store a compressed-in-line value, but we
1726  * prefer to decompress and then let compression be applied to the
1727  * whole range object if necessary. But, unlike arrays, we do allow
1728  * short-header varlena objects to stay as-is.
1729  */
1730  if (typlen == -1)
1731  lower->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(lower->val));
1732 
1733  msize = datum_compute_size(msize, lower->val, typbyval, typalign,
1734  typlen, typstorage);
1735  }
1736 
1737  if (RANGE_HAS_UBOUND(flags))
1738  {
1739  /* Make sure item to be inserted is not toasted */
1740  if (typlen == -1)
1741  upper->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(upper->val));
1742 
1743  msize = datum_compute_size(msize, upper->val, typbyval, typalign,
1744  typlen, typstorage);
1745  }
1746 
1747  /* Add space for flag byte */
1748  msize += sizeof(char);
1749 
1750  /* Note: zero-fill is required here, just as in heap tuples */
1751  range = (RangeType *) palloc0(msize);
1752  SET_VARSIZE(range, msize);
1753 
1754  /* Now fill in the datum */
1755  range->rangetypid = typcache->type_id;
1756 
1757  ptr = (char *) (range + 1);
1758 
1759  if (RANGE_HAS_LBOUND(flags))
1760  {
1761  Assert(lower->lower);
1762  ptr = datum_write(ptr, lower->val, typbyval, typalign, typlen,
1763  typstorage);
1764  }
1765 
1766  if (RANGE_HAS_UBOUND(flags))
1767  {
1768  Assert(!upper->lower);
1769  ptr = datum_write(ptr, upper->val, typbyval, typalign, typlen,
1770  typstorage);
1771  }
1772 
1773  *((char *) ptr) = flags;
1774 
1775  return range;
1776 }
#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
#define PointerGetDatum(X)
Definition: postgres.h:600
int range_cmp_bound_values(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1998
Datum val
Definition: rangetypes.h:64
int errcode(int sqlerrcode)
Definition: elog.c:698
int16 typlen
Definition: typcache.h:39
#define RANGE_LB_INF
Definition: rangetypes.h:41
bool typbyval
Definition: typcache.h:40
Oid rangetypid
Definition: rangetypes.h:28
char * Pointer
Definition: c.h:418
char typalign
Definition: pg_type.h:176
bool inclusive
Definition: rangetypes.h:66
#define ERROR
Definition: elog.h:46
#define PG_DETOAST_DATUM_PACKED(datum)
Definition: fmgr.h:248
static Size datum_compute_size(Size sz, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2528
char typstorage
Definition: typcache.h:42
#define RANGE_UB_INC
Definition: rangetypes.h:40
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:412
bool lower
Definition: rangetypes.h:67
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:98
void * palloc0(Size size)
Definition: mcxt.c:1093
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2554
#define RANGE_LB_INC
Definition: rangetypes.h:39
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
size_t Size
Definition: c.h:540
bool infinite
Definition: rangetypes.h:65
#define MAXALIGN(LEN)
Definition: c.h:757
#define RANGE_UB_INF
Definition: rangetypes.h:42
char typalign
Definition: typcache.h:41
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:747

◆ range_set_contain_empty()

void range_set_contain_empty ( RangeType range)

Definition at line 1869 of file rangetypes.c.

References RANGE_CONTAIN_EMPTY, and VARSIZE.

Referenced by range_super_union().

1870 {
1871  char *flagsp;
1872 
1873  /* flag byte is datum's last byte */
1874  flagsp = (char *) range + VARSIZE(range) - 1;
1875 
1876  *flagsp |= RANGE_CONTAIN_EMPTY;
1877 }
#define VARSIZE(PTR)
Definition: postgres.h:316
#define RANGE_CONTAIN_EMPTY
Definition: rangetypes.h:45

◆ range_split_internal()

bool range_split_internal ( TypeCacheEntry typcache,
const RangeType r1,
const RangeType r2,
RangeType **  output1,
RangeType **  output2 
)

Definition at line 1164 of file rangetypes.c.

References RangeBound::inclusive, RangeBound::lower, make_range(), range_cmp_bounds(), and range_deserialize().

Referenced by multirange_minus_internal().

1166 {
1167  RangeBound lower1,
1168  lower2;
1169  RangeBound upper1,
1170  upper2;
1171  bool empty1,
1172  empty2;
1173 
1174  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1175  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1176 
1177  if (range_cmp_bounds(typcache, &lower1, &lower2) < 0 &&
1178  range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1179  {
1180  /*
1181  * Need to invert inclusive/exclusive for the lower2 and upper2
1182  * points. They can't be infinite though. We're allowed to overwrite
1183  * these RangeBounds since they only exist locally.
1184  */
1185  lower2.inclusive = !lower2.inclusive;
1186  lower2.lower = false;
1187  upper2.inclusive = !upper2.inclusive;
1188  upper2.lower = true;
1189 
1190  *output1 = make_range(typcache, &lower1, &lower2, false);
1191  *output2 = make_range(typcache, &upper2, &upper1, false);
1192  return true;
1193  }
1194 
1195  return false;
1196 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
bool inclusive
Definition: rangetypes.h:66
bool lower
Definition: rangetypes.h:67
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_union()

Datum range_union ( PG_FUNCTION_ARGS  )

Definition at line 1080 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_get_typcache(), range_union_internal(), RangeTypeGetOid, and RangeIOData::typcache.

1081 {
1082  RangeType *r1 = PG_GETARG_RANGE_P(0);
1083  RangeType *r2 = PG_GETARG_RANGE_P(1);
1084  TypeCacheEntry *typcache;
1085 
1086  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1087 
1088  PG_RETURN_RANGE_P(range_union_internal(typcache, r1, r2, true));
1089 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:78
RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
Definition: rangetypes.c:1034
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_union_internal()

RangeType* range_union_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2,
bool  strict 
)

Definition at line 1034 of file rangetypes.c.

References DatumGetBool, elog, ereport, errcode(), errmsg(), ERROR, make_range(), range_adjacent_internal(), range_cmp_bounds(), range_deserialize(), range_overlaps_internal(), and RangeTypeGetOid.

Referenced by multirange_canonicalize(), range_merge(), and range_union().

1036 {
1037  RangeBound lower1,
1038  lower2;
1039  RangeBound upper1,
1040  upper2;
1041  bool empty1,
1042  empty2;
1043  RangeBound *result_lower;
1044  RangeBound *result_upper;
1045 
1046  /* Different types should be prevented by ANYRANGE matching rules */
1047  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1048  elog(ERROR, "range types do not match");
1049 
1050  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1051  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1052 
1053  /* if either is empty, the other is the correct answer */
1054  if (empty1)
1055  return r2;
1056  if (empty2)
1057  return r1;
1058 
1059  if (strict &&
1060  !DatumGetBool(range_overlaps_internal(typcache, r1, r2)) &&
1061  !DatumGetBool(range_adjacent_internal(typcache, r1, r2)))
1062  ereport(ERROR,
1063  (errcode(ERRCODE_DATA_EXCEPTION),
1064  errmsg("result of range union would not be contiguous")));
1065 
1066  if (range_cmp_bounds(typcache, &lower1, &lower2) < 0)
1067  result_lower = &lower1;
1068  else
1069  result_lower = &lower2;
1070 
1071  if (range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1072  result_upper = &upper1;
1073  else
1074  result_upper = &upper2;
1075 
1076  return make_range(typcache, result_lower, result_upper, false);
1077 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1884
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
bool range_overlaps_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:823
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
int errcode(int sqlerrcode)
Definition: elog.c:698
#define ERROR
Definition: elog.h:46
#define DatumGetBool(X)
Definition: postgres.h:437
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
bool range_adjacent_internal(TypeCacheEntry *typcache, const RangeType *r1, const RangeType *r2)
Definition: rangetypes.c:780
int range_cmp_bounds(TypeCacheEntry *typcache, const RangeBound *b1, const RangeBound *b2)
Definition: rangetypes.c:1924

◆ range_upper()

Datum range_upper ( PG_FUNCTION_ARGS  )

Definition at line 449 of file rangetypes.c.

References RangeBound::infinite, lower(), PG_GETARG_RANGE_P, PG_RETURN_DATUM, PG_RETURN_NULL, range_deserialize(), range_get_typcache(), RangeTypeGetOid, RangeIOData::typcache, upper(), and RangeBound::val.

450 {
451  RangeType *r1 = PG_GETARG_RANGE_P(0);
452  TypeCacheEntry *typcache;
455  bool empty;
456 
457  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
458 
459  range_deserialize(typcache, r1, &lower, &upper, &empty);
460 
461  /* Return NULL if there's no finite upper bound */
462  if (empty || upper.infinite)
463  PG_RETURN_NULL();
464 
465  PG_RETURN_DATUM(upper.val);
466 }
void range_deserialize(TypeCacheEntry *typcache, const RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1788
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1635
#define RangeTypeGetOid(r)
Definition: rangetypes.h:35
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
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:65
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ range_upper_inc()

Datum range_upper_inc ( PG_FUNCTION_ARGS  )

Definition at line 493 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_flags(), and RANGE_UB_INC.

494 {
495  RangeType *r1 = PG_GETARG_RANGE_P(0);
496  char flags = range_get_flags(r1);
497 
498  PG_RETURN_BOOL(flags & RANGE_UB_INC);
499 }
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
#define RANGE_UB_INC
Definition: rangetypes.h:40
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76

◆ range_upper_inf()

Datum range_upper_inf ( PG_FUNCTION_ARGS  )

Definition at line 513 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_flags(), and RANGE_UB_INF.

514 {
515  RangeType *r1 = PG_GETARG_RANGE_P(0);
516  char flags = range_get_flags(r1);
517 
518  PG_RETURN_BOOL(flags & RANGE_UB_INF);
519 }
char range_get_flags(const RangeType *range)
Definition: rangetypes.c:1855
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:76
#define RANGE_UB_INF
Definition: rangetypes.h:42

◆ tsrange_subdiff()

Datum tsrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1596 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1597 {
1600  float8 result;
1601 
1602  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1603  PG_RETURN_FLOAT8(result);
1604 }
#define USECS_PER_SEC
Definition: timestamp.h:94
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:35
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
double float8
Definition: c.h:565
int64 Timestamp
Definition: timestamp.h:38

◆ tstzrange_subdiff()

Datum tstzrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1607 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1608 {
1611  float8 result;
1612 
1613  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1614  PG_RETURN_FLOAT8(result);
1615 }
#define USECS_PER_SEC
Definition: timestamp.h:94
#define PG_GETARG_TIMESTAMP(n)
Definition: timestamp.h:35
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
double float8
Definition: c.h:565
int64 Timestamp
Definition: timestamp.h:38