PostgreSQL Source Code  git master
rangetypes.c File Reference
#include "postgres.h"
#include "access/tupmacs.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/hashutils.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 RANGE_EMPTY_LITERAL   "empty"
 
#define TYPE_IS_PACKABLE(typlen, typstorage)   ((typlen) == -1 && (typstorage) != 'p')
 

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, RangeType *r1, RangeType *r2)
 
Datum range_eq (PG_FUNCTION_ARGS)
 
bool range_ne_internal (TypeCacheEntry *typcache, RangeType *r1, 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, RangeType *r1, RangeType *r2)
 
Datum range_before (PG_FUNCTION_ARGS)
 
bool range_after_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
Datum range_after (PG_FUNCTION_ARGS)
 
bool bounds_adjacent (TypeCacheEntry *typcache, RangeBound boundA, RangeBound boundB)
 
bool range_adjacent_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
Datum range_adjacent (PG_FUNCTION_ARGS)
 
bool range_overlaps_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
Datum range_overlaps (PG_FUNCTION_ARGS)
 
bool range_overleft_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
Datum range_overleft (PG_FUNCTION_ARGS)
 
bool range_overright_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
Datum range_overright (PG_FUNCTION_ARGS)
 
Datum range_minus (PG_FUNCTION_ARGS)
 
static 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)
 
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, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
 
char range_get_flags (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, RangeBound *b1, RangeBound *b2)
 
int range_cmp_bound_values (TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
 
RangeTypemake_empty_range (TypeCacheEntry *typcache)
 
bool range_contains_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
bool range_contained_by_internal (TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
 
bool range_contains_elem_internal (TypeCacheEntry *typcache, RangeType *r, Datum val)
 

Macro Definition Documentation

◆ RANGE_EMPTY_LITERAL

#define RANGE_EMPTY_LITERAL   "empty"

Definition at line 46 of file rangetypes.c.

Referenced by range_deparse(), and range_parse().

◆ TYPE_IS_PACKABLE

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

Definition at line 2391 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 741 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(), and range_adjacent_internal().

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

◆ daterange_canonical()

Datum daterange_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1419 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.

1420 {
1421  RangeType *r = PG_GETARG_RANGE_P(0);
1422  TypeCacheEntry *typcache;
1423  RangeBound lower;
1424  RangeBound upper;
1425  bool empty;
1426 
1427  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1428 
1429  range_deserialize(typcache, r, &lower, &upper, &empty);
1430 
1431  if (empty)
1432  PG_RETURN_RANGE_P(r);
1433 
1434  if (!lower.infinite && !DATE_NOT_FINITE(DatumGetDateADT(lower.val)) &&
1435  !lower.inclusive)
1436  {
1437  lower.val = DirectFunctionCall2(date_pli, lower.val, Int32GetDatum(1));
1438  lower.inclusive = true;
1439  }
1440 
1441  if (!upper.infinite && !DATE_NOT_FINITE(DatumGetDateADT(upper.val)) &&
1442  upper.inclusive)
1443  {
1444  upper.val = DirectFunctionCall2(date_pli, upper.val, Int32GetDatum(1));
1445  upper.inclusive = false;
1446  }
1447 
1448  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1449 }
#define DatumGetDateADT(X)
Definition: date.h:53
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
bool inclusive
Definition: rangetypes.h:64
#define DATE_NOT_FINITE(j)
Definition: date.h:43
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1570
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define Int32GetDatum(X)
Definition: postgres.h:479
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619
Datum date_pli(PG_FUNCTION_ARGS)
Definition: date.c:508

◆ daterange_subdiff()

Datum daterange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1498 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1499 {
1500  int32 v1 = PG_GETARG_INT32(0);
1501  int32 v2 = PG_GETARG_INT32(1);
1502 
1503  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1504 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:356
signed int int32
Definition: c.h:346
double float8
Definition: c.h:491

◆ datum_compute_size()

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

Definition at line 2399 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().

2401 {
2402  if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2404  {
2405  /*
2406  * we're anticipating converting to a short varlena header, so adjust
2407  * length and don't count any alignment
2408  */
2410  }
2411  else
2412  {
2413  data_length = att_align_datum(data_length, typalign, typlen, val);
2414  data_length = att_addlength_datum(data_length, typlen, val);
2415  }
2416 
2417  return data_length;
2418 }
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2391
#define att_align_datum(cur_offset, attalign, attlen, attdatum)
Definition: tupmacs.h:103
char typalign
Definition: pg_type.h:170
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:270
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:273
#define DatumGetPointer(X)
Definition: postgres.h:549
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:162
long val
Definition: informix.c:684

◆ datum_write()

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

Definition at line 2425 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().

2427 {
2428  Size data_length;
2429 
2430  if (typbyval)
2431  {
2432  /* pass-by-value */
2433  ptr = (char *) att_align_nominal(ptr, typalign);
2434  store_att_byval(ptr, datum, typlen);
2435  data_length = typlen;
2436  }
2437  else if (typlen == -1)
2438  {
2439  /* varlena */
2440  Pointer val = DatumGetPointer(datum);
2441 
2442  if (VARATT_IS_EXTERNAL(val))
2443  {
2444  /*
2445  * Throw error, because we must never put a toast pointer inside a
2446  * range object. Caller should have detoasted it.
2447  */
2448  elog(ERROR, "cannot store a toast pointer inside a range");
2449  data_length = 0; /* keep compiler quiet */
2450  }
2451  else if (VARATT_IS_SHORT(val))
2452  {
2453  /* no alignment for short varlenas */
2454  data_length = VARSIZE_SHORT(val);
2455  memcpy(ptr, val, data_length);
2456  }
2457  else if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2458  VARATT_CAN_MAKE_SHORT(val))
2459  {
2460  /* convert to short varlena -- no alignment */
2461  data_length = VARATT_CONVERTED_SHORT_SIZE(val);
2462  SET_VARSIZE_SHORT(ptr, data_length);
2463  memcpy(ptr + 1, VARDATA(val), data_length - 1);
2464  }
2465  else
2466  {
2467  /* full 4-byte header varlena */
2468  ptr = (char *) att_align_nominal(ptr, typalign);
2469  data_length = VARSIZE(val);
2470  memcpy(ptr, val, data_length);
2471  }
2472  }
2473  else if (typlen == -2)
2474  {
2475  /* cstring ... never needs alignment */
2476  Assert(typalign == 'c');
2477  data_length = strlen(DatumGetCString(datum)) + 1;
2478  memcpy(ptr, DatumGetPointer(datum), data_length);
2479  }
2480  else
2481  {
2482  /* fixed-length pass-by-reference */
2483  ptr = (char *) att_align_nominal(ptr, typalign);
2484  Assert(typlen > 0);
2485  data_length = typlen;
2486  memcpy(ptr, DatumGetPointer(datum), data_length);
2487  }
2488 
2489  ptr += data_length;
2490 
2491  return ptr;
2492 }
#define SET_VARSIZE_SHORT(PTR, len)
Definition: postgres.h:330
#define VARDATA(PTR)
Definition: postgres.h:302
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:146
#define VARSIZE(PTR)
Definition: postgres.h:303
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2391
#define VARATT_IS_EXTERNAL(PTR)
Definition: postgres.h:313
char * Pointer
Definition: c.h:335
char typalign
Definition: pg_type.h:170
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:566
#define VARATT_IS_SHORT(PTR)
Definition: postgres.h:326
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:270
#define VARSIZE_SHORT(PTR)
Definition: postgres.h:305
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:273
#define store_att_byval(T, newdatum, attlen)
Definition: tupmacs.h:224
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
#define DatumGetPointer(X)
Definition: postgres.h:549
#define elog(elevel,...)
Definition: elog.h:226
long val
Definition: informix.c:684

◆ elem_contained_by_range()

Datum elem_contained_by_range ( PG_FUNCTION_ARGS  )

Definition at line 541 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.

542 {
545  TypeCacheEntry *typcache;
546 
547  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
548 
549  PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
550 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Definition: rangetypes.c:2344
long val
Definition: informix.c:684

◆ get_range_io_data()

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

Definition at line 302 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, RangeIOData::proc, TypeCacheEntry::rngelemtype, typalign, RangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_RANGE_INFO, RangeIOData::typiofunc, and RangeIOData::typioparam.

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

303 {
304  RangeIOData *cache = (RangeIOData *) fcinfo->flinfo->fn_extra;
305 
306  if (cache == NULL || cache->typcache->type_id != rngtypid)
307  {
308  int16 typlen;
309  bool typbyval;
310  char typalign;
311  char typdelim;
312 
313  cache = (RangeIOData *) MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
314  sizeof(RangeIOData));
315  cache->typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
316  if (cache->typcache->rngelemtype == NULL)
317  elog(ERROR, "type %u is not a range type", rngtypid);
318 
319  /* get_type_io_data does more than we need, but is convenient */
321  func,
322  &typlen,
323  &typbyval,
324  &typalign,
325  &typdelim,
326  &cache->typioparam,
327  &cache->typiofunc);
328 
329  if (!OidIsValid(cache->typiofunc))
330  {
331  /* this could only happen for receive or send */
332  if (func == IOFunc_receive)
333  ereport(ERROR,
334  (errcode(ERRCODE_UNDEFINED_FUNCTION),
335  errmsg("no binary input function available for type %s",
337  else
338  ereport(ERROR,
339  (errcode(ERRCODE_UNDEFINED_FUNCTION),
340  errmsg("no binary output function available for type %s",
342  }
343  fmgr_info_cxt(cache->typiofunc, &cache->proc,
344  fcinfo->flinfo->fn_mcxt);
345 
346  fcinfo->flinfo->fn_extra = (void *) cache;
347  }
348 
349  return cache;
350 }
signed short int16
Definition: c.h:345
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:139
MemoryContext fn_mcxt
Definition: fmgr.h:65
Oid typiofunc
Definition: rangetypes.c:52
int errcode(int sqlerrcode)
Definition: elog.c:570
TypeCacheEntry * typcache
Definition: rangetypes.c:51
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
#define OidIsValid(objectId)
Definition: c.h:638
char typalign
Definition: pg_type.h:170
#define ERROR
Definition: elog.h:43
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:134
#define ereport(elevel, rest)
Definition: elog.h:141
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:95
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:322
FmgrInfo proc
Definition: rangetypes.c:54
void * fn_extra
Definition: fmgr.h:64
int errmsg(const char *fmt,...)
Definition: elog.c:784
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
#define elog(elevel,...)
Definition: elog.h:226
Oid typioparam
Definition: rangetypes.c:53
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:2103

◆ hash_range()

Datum hash_range ( PG_FUNCTION_ARGS  )

Definition at line 1223 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.

1224 {
1225  RangeType *r = PG_GETARG_RANGE_P(0);
1226  uint32 result;
1227  TypeCacheEntry *typcache;
1228  TypeCacheEntry *scache;
1229  RangeBound lower;
1230  RangeBound upper;
1231  bool empty;
1232  char flags;
1233  uint32 lower_hash;
1234  uint32 upper_hash;
1235 
1236  check_stack_depth(); /* recurses when subtype is a range type */
1237 
1238  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1239 
1240  /* deserialize */
1241  range_deserialize(typcache, r, &lower, &upper, &empty);
1242  flags = range_get_flags(r);
1243 
1244  /*
1245  * Look up the element type's hash function, if not done already.
1246  */
1247  scache = typcache->rngelemtype;
1248  if (!OidIsValid(scache->hash_proc_finfo.fn_oid))
1249  {
1251  if (!OidIsValid(scache->hash_proc_finfo.fn_oid))
1252  ereport(ERROR,
1253  (errcode(ERRCODE_UNDEFINED_FUNCTION),
1254  errmsg("could not identify a hash function for type %s",
1255  format_type_be(scache->type_id))));
1256  }
1257 
1258  /*
1259  * Apply the hash function to each bound.
1260  */
1261  if (RANGE_HAS_LBOUND(flags))
1262  lower_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo,
1263  typcache->rng_collation,
1264  lower.val));
1265  else
1266  lower_hash = 0;
1267 
1268  if (RANGE_HAS_UBOUND(flags))
1269  upper_hash = DatumGetUInt32(FunctionCall1Coll(&scache->hash_proc_finfo,
1270  typcache->rng_collation,
1271  upper.val));
1272  else
1273  upper_hash = 0;
1274 
1275  /* Merge hashes of flags and bounds */
1276  result = hash_uint32((uint32) flags);
1277  result ^= lower_hash;
1278  result = (result << 1) | (result >> 31);
1279  result ^= upper_hash;
1280 
1281  PG_RETURN_INT32(result);
1282 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
#define DatumGetUInt32(X)
Definition: postgres.h:486
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
#define TYPECACHE_HASH_PROC_FINFO
Definition: typcache.h:135
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:570
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
Datum hash_uint32(uint32 k)
Definition: hashfn.c:613
void check_stack_depth(void)
Definition: postgres.c:3262
unsigned int uint32
Definition: c.h:358
FmgrInfo hash_proc_finfo
Definition: typcache.h:74
#define ereport(elevel, rest)
Definition: elog.h:141
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:95
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1130
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:322
Oid fn_oid
Definition: fmgr.h:59
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
Oid rng_collation
Definition: typcache.h:96
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ hash_range_extended()

Datum hash_range_extended ( PG_FUNCTION_ARGS  )

Definition at line 1289 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.

1290 {
1291  RangeType *r = PG_GETARG_RANGE_P(0);
1292  Datum seed = PG_GETARG_DATUM(1);
1293  uint64 result;
1294  TypeCacheEntry *typcache;
1295  TypeCacheEntry *scache;
1296  RangeBound lower;
1297  RangeBound upper;
1298  bool empty;
1299  char flags;
1300  uint64 lower_hash;
1301  uint64 upper_hash;
1302 
1304 
1305  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1306 
1307  range_deserialize(typcache, r, &lower, &upper, &empty);
1308  flags = range_get_flags(r);
1309 
1310  scache = typcache->rngelemtype;
1312  {
1313  scache = lookup_type_cache(scache->type_id,
1316  ereport(ERROR,
1317  (errcode(ERRCODE_UNDEFINED_FUNCTION),
1318  errmsg("could not identify a hash function for type %s",
1319  format_type_be(scache->type_id))));
1320  }
1321 
1322  if (RANGE_HAS_LBOUND(flags))
1324  typcache->rng_collation,
1325  lower.val,
1326  seed));
1327  else
1328  lower_hash = 0;
1329 
1330  if (RANGE_HAS_UBOUND(flags))
1332  typcache->rng_collation,
1333  upper.val,
1334  seed));
1335  else
1336  upper_hash = 0;
1337 
1338  /* Merge hashes of flags and bounds */
1339  result = DatumGetUInt64(hash_uint32_extended((uint32) flags,
1340  DatumGetInt64(seed)));
1341  result ^= lower_hash;
1342  result = ROTATE_HIGH_AND_LOW_32BITS(result);
1343  result ^= upper_hash;
1344 
1345  PG_RETURN_UINT64(result);
1346 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define TYPECACHE_HASH_EXTENDED_PROC_FINFO
Definition: typcache.h:143
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:570
char * format_type_be(Oid type_oid)
Definition: format_type.c:326
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1150
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:358
#define OidIsValid(objectId)
Definition: c.h:638
#define ERROR
Definition: elog.h:43
#define DatumGetInt64(X)
Definition: postgres.h:607
void check_stack_depth(void)
Definition: postgres.c:3262
unsigned int uint32
Definition: c.h:358
#define ereport(elevel, rest)
Definition: elog.h:141
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:95
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
FmgrInfo hash_extended_proc_finfo
Definition: typcache.h:75
uintptr_t Datum
Definition: postgres.h:367
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Definition: hashutils.h:18
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:322
Oid fn_oid
Definition: fmgr.h:59
#define DatumGetUInt64(X)
Definition: postgres.h:634
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
Oid rng_collation
Definition: typcache.h:96
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766
int errmsg(const char *fmt,...)
Definition: elog.c:784
Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfn.c:634

◆ int4range_canonical()

Datum int4range_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1357 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.

1358 {
1359  RangeType *r = PG_GETARG_RANGE_P(0);
1360  TypeCacheEntry *typcache;
1361  RangeBound lower;
1362  RangeBound upper;
1363  bool empty;
1364 
1365  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1366 
1367  range_deserialize(typcache, r, &lower, &upper, &empty);
1368 
1369  if (empty)
1370  PG_RETURN_RANGE_P(r);
1371 
1372  if (!lower.infinite && !lower.inclusive)
1373  {
1374  lower.val = DirectFunctionCall2(int4pl, lower.val, Int32GetDatum(1));
1375  lower.inclusive = true;
1376  }
1377 
1378  if (!upper.infinite && upper.inclusive)
1379  {
1380  upper.val = DirectFunctionCall2(int4pl, upper.val, Int32GetDatum(1));
1381  upper.inclusive = false;
1382  }
1383 
1384  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1385 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
Datum int4pl(PG_FUNCTION_ARGS)
Definition: int.c:772
bool inclusive
Definition: rangetypes.h:64
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1570
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define Int32GetDatum(X)
Definition: postgres.h:479
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619

◆ int4range_subdiff()

Datum int4range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1464 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1465 {
1466  int32 v1 = PG_GETARG_INT32(0);
1467  int32 v2 = PG_GETARG_INT32(1);
1468 
1469  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1470 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:356
signed int int32
Definition: c.h:346
double float8
Definition: c.h:491

◆ int8range_canonical()

Datum int8range_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1388 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.

1389 {
1390  RangeType *r = PG_GETARG_RANGE_P(0);
1391  TypeCacheEntry *typcache;
1392  RangeBound lower;
1393  RangeBound upper;
1394  bool empty;
1395 
1396  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1397 
1398  range_deserialize(typcache, r, &lower, &upper, &empty);
1399 
1400  if (empty)
1401  PG_RETURN_RANGE_P(r);
1402 
1403  if (!lower.infinite && !lower.inclusive)
1404  {
1405  lower.val = DirectFunctionCall2(int8pl, lower.val, Int64GetDatum(1));
1406  lower.inclusive = true;
1407  }
1408 
1409  if (!upper.infinite && upper.inclusive)
1410  {
1411  upper.val = DirectFunctionCall2(int8pl, upper.val, Int64GetDatum(1));
1412  upper.inclusive = false;
1413  }
1414 
1415  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1416 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum int8pl(PG_FUNCTION_ARGS)
Definition: int8.c:543
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
bool inclusive
Definition: rangetypes.h:64
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1699
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1570
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619

◆ int8range_subdiff()

Datum int8range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1473 of file rangetypes.c.

References PG_GETARG_INT64, and PG_RETURN_FLOAT8.

1474 {
1475  int64 v1 = PG_GETARG_INT64(0);
1476  int64 v2 = PG_GETARG_INT64(1);
1477 
1478  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1479 }
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:356
double float8
Definition: c.h:491
#define PG_GETARG_INT64(n)
Definition: fmgr.h:277

◆ make_empty_range()

RangeType* make_empty_range ( TypeCacheEntry typcache)

Definition at line 1944 of file rangetypes.c.

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

Referenced by range_intersect(), and range_minus().

1945 {
1946  RangeBound lower;
1947  RangeBound upper;
1948 
1949  lower.val = (Datum) 0;
1950  lower.infinite = false;
1951  lower.inclusive = false;
1952  lower.lower = true;
1953 
1954  upper.val = (Datum) 0;
1955  upper.infinite = false;
1956  upper.inclusive = false;
1957  upper.lower = false;
1958 
1959  return make_range(typcache, &lower, &upper, true);
1960 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
bool inclusive
Definition: rangetypes.h:64
bool lower
Definition: rangetypes.h:65
uintptr_t Datum
Definition: postgres.h:367
bool infinite
Definition: rangetypes.h:63

◆ make_range()

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

Definition at line 1795 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(), range_constructor2(), range_constructor3(), range_in(), range_intersect(), range_minus(), range_recv(), range_super_union(), and range_union_internal().

1797 {
1798  RangeType *range;
1799 
1800  range = range_serialize(typcache, lower, upper, empty);
1801 
1802  /* no need to call canonical on empty ranges ... */
1803  if (OidIsValid(typcache->rng_canonical_finfo.fn_oid) &&
1804  !RangeIsEmpty(range))
1806  RangeTypePGetDatum(range)));
1807 
1808  return range;
1809 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:54
#define OidIsValid(objectId)
Definition: c.h:638
#define RangeTypePGetDatum(X)
Definition: rangetypes.h:73
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1570
FmgrInfo rng_canonical_finfo
Definition: typcache.h:98
Oid fn_oid
Definition: fmgr.h:59
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:71
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:635

◆ numrange_subdiff()

Datum numrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1482 of file rangetypes.c.

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

1483 {
1484  Datum v1 = PG_GETARG_DATUM(0);
1485  Datum v2 = PG_GETARG_DATUM(1);
1486  Datum numresult;
1487  float8 floatresult;
1488 
1489  numresult = DirectFunctionCall2(numeric_sub, v1, v2);
1490 
1492  numresult));
1493 
1494  PG_RETURN_FLOAT8(floatresult);
1495 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:356
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:617
double float8
Definition: c.h:491
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:3414
#define DatumGetFloat8(X)
Definition: postgres.h:728
uintptr_t Datum
Definition: postgres.h:367
Datum numeric_sub(PG_FUNCTION_ARGS)
Definition: numeric.c:2464
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:619

◆ range_adjacent()

Datum range_adjacent ( PG_FUNCTION_ARGS  )

Definition at line 812 of file rangetypes.c.

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

813 {
814  RangeType *r1 = PG_GETARG_RANGE_P(0);
815  RangeType *r2 = PG_GETARG_RANGE_P(1);
816  TypeCacheEntry *typcache;
817 
818  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
819 
820  PG_RETURN_BOOL(range_adjacent_internal(typcache, r1, r2));
821 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:782
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_adjacent_internal()

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

Definition at line 782 of file rangetypes.c.

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

Referenced by range_adjacent(), range_gist_consistent_int(), range_gist_consistent_leaf(), range_union_internal(), and spg_range_quad_leaf_consistent().

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

◆ range_after()

Datum range_after ( PG_FUNCTION_ARGS  )

Definition at line 711 of file rangetypes.c.

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

712 {
713  RangeType *r1 = PG_GETARG_RANGE_P(0);
714  RangeType *r2 = PG_GETARG_RANGE_P(1);
715  TypeCacheEntry *typcache;
716 
717  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
718 
719  PG_RETURN_BOOL(range_after_internal(typcache, r1, r2));
720 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:686
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_after_internal()

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

Definition at line 686 of file rangetypes.c.

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

Referenced by range_after(), range_gist_consistent_int(), range_gist_consistent_leaf(), and spg_range_quad_leaf_consistent().

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

◆ range_before()

Datum range_before ( PG_FUNCTION_ARGS  )

Definition at line 673 of file rangetypes.c.

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

674 {
675  RangeType *r1 = PG_GETARG_RANGE_P(0);
676  RangeType *r2 = PG_GETARG_RANGE_P(1);
677  TypeCacheEntry *typcache;
678 
679  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
680 
681  PG_RETURN_BOOL(range_before_internal(typcache, r1, r2));
682 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:648
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_before_internal()

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

Definition at line 648 of file rangetypes.c.

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

Referenced by range_before(), range_gist_consistent_int(), range_gist_consistent_leaf(), and spg_range_quad_leaf_consistent().

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

◆ range_bound_escape()

static char * range_bound_escape ( const char *  value)
static

Definition at line 2254 of file rangetypes.c.

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

Referenced by range_deparse().

2255 {
2256  bool nq;
2257  const char *ptr;
2259 
2260  initStringInfo(&buf);
2261 
2262  /* Detect whether we need double quotes for this value */
2263  nq = (value[0] == '\0'); /* force quotes for empty string */
2264  for (ptr = value; *ptr; ptr++)
2265  {
2266  char ch = *ptr;
2267 
2268  if (ch == '"' || ch == '\\' ||
2269  ch == '(' || ch == ')' ||
2270  ch == '[' || ch == ']' ||
2271  ch == ',' ||
2272  isspace((unsigned char) ch))
2273  {
2274  nq = true;
2275  break;
2276  }
2277  }
2278 
2279  /* And emit the string */
2280  if (nq)
2281  appendStringInfoChar(&buf, '"');
2282  for (ptr = value; *ptr; ptr++)
2283  {
2284  char ch = *ptr;
2285 
2286  if (ch == '"' || ch == '\\')
2287  appendStringInfoChar(&buf, ch);
2288  appendStringInfoChar(&buf, ch);
2289  }
2290  if (nq)
2291  appendStringInfoChar(&buf, '"');
2292 
2293  return buf.data;
2294 }
static struct @145 value
static char * buf
Definition: pg_test_fsync.c:68
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46

◆ range_cmp()

Datum range_cmp ( PG_FUNCTION_ARGS  )

Definition at line 1142 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().

1143 {
1144  RangeType *r1 = PG_GETARG_RANGE_P(0);
1145  RangeType *r2 = PG_GETARG_RANGE_P(1);
1146  TypeCacheEntry *typcache;
1147  RangeBound lower1,
1148  lower2;
1149  RangeBound upper1,
1150  upper2;
1151  bool empty1,
1152  empty2;
1153  int cmp;
1154 
1155  check_stack_depth(); /* recurses when subtype is a range type */
1156 
1157  /* Different types should be prevented by ANYRANGE matching rules */
1158  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1159  elog(ERROR, "range types do not match");
1160 
1161  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1162 
1163  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1164  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1165 
1166  /* For b-tree use, empty ranges sort before all else */
1167  if (empty1 && empty2)
1168  cmp = 0;
1169  else if (empty1)
1170  cmp = -1;
1171  else if (empty2)
1172  cmp = 1;
1173  else
1174  {
1175  cmp = range_cmp_bounds(typcache, &lower1, &lower2);
1176  if (cmp == 0)
1177  cmp = range_cmp_bounds(typcache, &upper1, &upper2);
1178  }
1179 
1180  PG_FREE_IF_COPY(r1, 0);
1181  PG_FREE_IF_COPY(r2, 1);
1182 
1183  PG_RETURN_INT32(cmp);
1184 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1835
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_RETURN_INT32(x)
Definition: fmgr.h:344
#define ERROR
Definition: elog.h:43
void check_stack_depth(void)
Definition: postgres.c:3262
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:255
#define elog(elevel,...)
Definition: elog.h:226
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_cmp_bound_values()

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

Definition at line 1909 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().

1911 {
1912  /*
1913  * First, handle cases involving infinity, which don't require invoking
1914  * the comparison proc.
1915  */
1916  if (b1->infinite && b2->infinite)
1917  {
1918  /*
1919  * Both are infinity, so they are equal unless one is lower and the
1920  * other not.
1921  */
1922  if (b1->lower == b2->lower)
1923  return 0;
1924  else
1925  return b1->lower ? -1 : 1;
1926  }
1927  else if (b1->infinite)
1928  return b1->lower ? -1 : 1;
1929  else if (b2->infinite)
1930  return b2->lower ? 1 : -1;
1931 
1932  /*
1933  * Both boundaries are finite, so compare the held values.
1934  */
1936  typcache->rng_collation,
1937  b1->val, b2->val));
1938 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:97
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum val
Definition: rangetypes.h:62
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1150
bool lower
Definition: rangetypes.h:65
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:96

◆ range_cmp_bounds()

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

Definition at line 1835 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(), range_after_internal(), range_before_internal(), range_bound_qsort_cmp(), range_cmp(), range_contains_internal(), range_eq_internal(), range_gist_double_sorting_split(), range_gist_penalty(), range_intersect(), range_minus(), range_overlaps_internal(), range_overleft_internal(), range_overright_internal(), range_super_union(), range_union_internal(), rbound_bsearch(), single_bound_cmp(), and spg_range_quad_inner_consistent().

1836 {
1837  int32 result;
1838 
1839  /*
1840  * First, handle cases involving infinity, which don't require invoking
1841  * the comparison proc.
1842  */
1843  if (b1->infinite && b2->infinite)
1844  {
1845  /*
1846  * Both are infinity, so they are equal unless one is lower and the
1847  * other not.
1848  */
1849  if (b1->lower == b2->lower)
1850  return 0;
1851  else
1852  return b1->lower ? -1 : 1;
1853  }
1854  else if (b1->infinite)
1855  return b1->lower ? -1 : 1;
1856  else if (b2->infinite)
1857  return b2->lower ? 1 : -1;
1858 
1859  /*
1860  * Both boundaries are finite, so compare the held values.
1861  */
1863  typcache->rng_collation,
1864  b1->val, b2->val));
1865 
1866  /*
1867  * If the comparison is anything other than equal, we're done. If they
1868  * compare equal though, we still have to consider whether the boundaries
1869  * are inclusive or exclusive.
1870  */
1871  if (result == 0)
1872  {
1873  if (!b1->inclusive && !b2->inclusive)
1874  {
1875  /* both are exclusive */
1876  if (b1->lower == b2->lower)
1877  return 0;
1878  else
1879  return b1->lower ? 1 : -1;
1880  }
1881  else if (!b1->inclusive)
1882  return b1->lower ? 1 : -1;
1883  else if (!b2->inclusive)
1884  return b2->lower ? -1 : 1;
1885  else
1886  {
1887  /*
1888  * Both are inclusive and the values held are equal, so they are
1889  * equal regardless of whether they are upper or lower boundaries,
1890  * or a mix.
1891  */
1892  return 0;
1893  }
1894  }
1895 
1896  return result;
1897 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:97
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum val
Definition: rangetypes.h:62
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1150
signed int int32
Definition: c.h:346
bool inclusive
Definition: rangetypes.h:64
bool lower
Definition: rangetypes.h:65
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:96

◆ range_constructor2()

Datum range_constructor2 ( PG_FUNCTION_ARGS  )

Definition at line 361 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.

362 {
363  Datum arg1 = PG_GETARG_DATUM(0);
364  Datum arg2 = PG_GETARG_DATUM(1);
365  Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
366  RangeType *range;
367  TypeCacheEntry *typcache;
370 
371  typcache = range_get_typcache(fcinfo, rngtypid);
372 
373  lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
374  lower.infinite = PG_ARGISNULL(0);
375  lower.inclusive = true;
376  lower.lower = true;
377 
378  upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
379  upper.infinite = PG_ARGISNULL(1);
380  upper.inclusive = false;
381  upper.lower = false;
382 
383  range = make_range(typcache, &lower, &upper, false);
384 
385  PG_RETURN_RANGE_P(range);
386 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
unsigned int Oid
Definition: postgres_ext.h:31
bool inclusive
Definition: rangetypes.h:64
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
bool lower
Definition: rangetypes.h:65
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
uintptr_t Datum
Definition: postgres.h:367
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1795
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
bool infinite
Definition: rangetypes.h:63

◆ range_constructor3()

Datum range_constructor3 ( PG_FUNCTION_ARGS  )

Definition at line 390 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.

391 {
392  Datum arg1 = PG_GETARG_DATUM(0);
393  Datum arg2 = PG_GETARG_DATUM(1);
394  Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
395  RangeType *range;
396  TypeCacheEntry *typcache;
399  char flags;
400 
401  typcache = range_get_typcache(fcinfo, rngtypid);
402 
403  if (PG_ARGISNULL(2))
404  ereport(ERROR,
405  (errcode(ERRCODE_DATA_EXCEPTION),
406  errmsg("range constructor flags argument must not be null")));
407 
409 
410  lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
411  lower.infinite = PG_ARGISNULL(0);
412  lower.inclusive = (flags & RANGE_LB_INC) != 0;
413  lower.lower = true;
414 
415  upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
416  upper.infinite = PG_ARGISNULL(1);
417  upper.inclusive = (flags & RANGE_UB_INC) != 0;
418  upper.lower = false;
419 
420  range = make_range(typcache, &lower, &upper, false);
421 
422  PG_RETURN_RANGE_P(range);
423 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
static char range_parse_flags(const char *flags_str)
Definition: rangetypes.c:1974
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:570
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:303
bool inclusive
Definition: rangetypes.h:64
#define ERROR
Definition: elog.h:43
#define RANGE_UB_INC
Definition: rangetypes.h:38
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
#define ereport(elevel, rest)
Definition: elog.h:141
bool lower
Definition: rangetypes.h:65
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
uintptr_t Datum
Definition: postgres.h:367
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1795
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define PG_ARGISNULL(n)
Definition: fmgr.h:204
bool infinite
Definition: rangetypes.h:63
char * text_to_cstring(const text *t)
Definition: varlena.c:204
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ range_contained_by()

Datum range_contained_by ( PG_FUNCTION_ARGS  )

Definition at line 635 of file rangetypes.c.

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

636 {
637  RangeType *r1 = PG_GETARG_RANGE_P(0);
638  RangeType *r2 = PG_GETARG_RANGE_P(1);
639  TypeCacheEntry *typcache;
640 
641  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
642 
643  PG_RETURN_BOOL(range_contained_by_internal(typcache, r1, r2));
644 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2335
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_contained_by_internal()

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

Definition at line 2335 of file rangetypes.c.

References range_contains_internal().

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

2336 {
2337  return range_contains_internal(typcache, r2, r1);
2338 }
bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2303

◆ range_contains()

Datum range_contains ( PG_FUNCTION_ARGS  )

Definition at line 622 of file rangetypes.c.

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

623 {
624  RangeType *r1 = PG_GETARG_RANGE_P(0);
625  RangeType *r2 = PG_GETARG_RANGE_P(1);
626  TypeCacheEntry *typcache;
627 
628  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
629 
630  PG_RETURN_BOOL(range_contains_internal(typcache, r1, r2));
631 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2303

◆ range_contains_elem()

Datum range_contains_elem ( PG_FUNCTION_ARGS  )

Definition at line 528 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.

529 {
532  TypeCacheEntry *typcache;
533 
534  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
535 
536  PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
537 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:263
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
uintptr_t Datum
Definition: postgres.h:367
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Definition: rangetypes.c:2344
long val
Definition: informix.c:684

◆ range_contains_elem_internal()

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

Definition at line 2344 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(), range_gist_consistent_leaf(), and spg_range_quad_leaf_consistent().

2345 {
2346  RangeBound lower;
2347  RangeBound upper;
2348  bool empty;
2349  int32 cmp;
2350 
2351  range_deserialize(typcache, r, &lower, &upper, &empty);
2352 
2353  if (empty)
2354  return false;
2355 
2356  if (!lower.infinite)
2357  {
2359  typcache->rng_collation,
2360  lower.val, val));
2361  if (cmp > 0)
2362  return false;
2363  if (cmp == 0 && !lower.inclusive)
2364  return false;
2365  }
2366 
2367  if (!upper.infinite)
2368  {
2370  typcache->rng_collation,
2371  upper.val, val));
2372  if (cmp < 0)
2373  return false;
2374  if (cmp == 0 && !upper.inclusive)
2375  return false;
2376  }
2377 
2378  return true;
2379 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:97
#define DatumGetInt32(X)
Definition: postgres.h:472
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1150
signed int int32
Definition: c.h:346
bool inclusive
Definition: rangetypes.h:64
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:96
long val
Definition: informix.c:684
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_contains_internal()

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

Definition at line 2303 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_gist_consistent_leaf(), and spg_range_quad_leaf_consistent().

2304 {
2305  RangeBound lower1;
2306  RangeBound upper1;
2307  bool empty1;
2308  RangeBound lower2;
2309  RangeBound upper2;
2310  bool empty2;
2311 
2312  /* Different types should be prevented by ANYRANGE matching rules */
2313  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
2314  elog(ERROR, "range types do not match");
2315 
2316  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2317  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2318 
2319  /* If either range is empty, the answer is easy */
2320  if (empty2)
2321  return true;
2322  else if (empty1)
2323  return false;
2324 
2325  /* Else we must have lower1 <= lower2 and upper1 >= upper2 */
2326  if (range_cmp_bounds(typcache, &lower1, &lower2) > 0)
2327  return false;
2328  if (range_cmp_bounds(typcache, &upper1, &upper2) < 0)
2329  return false;
2330 
2331  return true;
2332 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1835
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define ERROR
Definition: elog.h:43
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define elog(elevel,...)
Definition: elog.h:226

◆ range_deparse()

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

Definition at line 2224 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().

2225 {
2227 
2228  if (flags & RANGE_EMPTY)
2229  return pstrdup(RANGE_EMPTY_LITERAL);
2230 
2231  initStringInfo(&buf);
2232 
2233  appendStringInfoChar(&buf, (flags & RANGE_LB_INC) ? '[' : '(');
2234 
2235  if (RANGE_HAS_LBOUND(flags))
2236  appendStringInfoString(&buf, range_bound_escape(lbound_str));
2237 
2238  appendStringInfoChar(&buf, ',');
2239 
2240  if (RANGE_HAS_UBOUND(flags))
2241  appendStringInfoString(&buf, range_bound_escape(ubound_str));
2242 
2243  appendStringInfoChar(&buf, (flags & RANGE_UB_INC) ? ']' : ')');
2244 
2245  return buf.data;
2246 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RANGE_EMPTY
Definition: rangetypes.h:36
char * pstrdup(const char *in)
Definition: mcxt.c:1186
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.c:46
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:163
static char * buf
Definition: pg_test_fsync.c:68
#define RANGE_UB_INC
Definition: rangetypes.h:38
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define RANGE_LB_INC
Definition: rangetypes.h:37
static char * range_bound_escape(const char *value)
Definition: rangetypes.c:2254

◆ range_deserialize()

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

Definition at line 1699 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 calc_hist_selectivity(), compute_range_stats(), daterange_canonical(), getQuadrant(), hash_range(), hash_range_extended(), int4range_canonical(), int8range_canonical(), range_adjacent_internal(), range_after_internal(), range_before_internal(), range_cmp(), range_contains_elem_internal(), range_contains_internal(), range_eq_internal(), range_gist_double_sorting_split(), range_gist_penalty(), range_gist_single_sorting_split(), range_intersect(), range_lower(), range_minus(), range_out(), range_overlaps_internal(), range_overleft_internal(), range_overright_internal(), range_send(), range_super_union(), range_union_internal(), range_upper(), spg_range_quad_inner_consistent(), and spg_range_quad_picksplit().

1701 {
1702  char flags;
1703  int16 typlen;
1704  bool typbyval;
1705  char typalign;
1706  Pointer ptr;
1707  Datum lbound;
1708  Datum ubound;
1709 
1710  /* assert caller passed the right typcache entry */
1711  Assert(RangeTypeGetOid(range) == typcache->type_id);
1712 
1713  /* fetch the flag byte from datum's last byte */
1714  flags = *((char *) range + VARSIZE(range) - 1);
1715 
1716  /* fetch information about range's element type */
1717  typlen = typcache->rngelemtype->typlen;
1718  typbyval = typcache->rngelemtype->typbyval;
1719  typalign = typcache->rngelemtype->typalign;
1720 
1721  /* initialize data pointer just after the range OID */
1722  ptr = (Pointer) (range + 1);
1723 
1724  /* fetch lower bound, if any */
1725  if (RANGE_HAS_LBOUND(flags))
1726  {
1727  /* att_align_pointer cannot be necessary here */
1728  lbound = fetch_att(ptr, typbyval, typlen);
1729  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
1730  }
1731  else
1732  lbound = (Datum) 0;
1733 
1734  /* fetch upper bound, if any */
1735  if (RANGE_HAS_UBOUND(flags))
1736  {
1737  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
1738  ubound = fetch_att(ptr, typbyval, typlen);
1739  /* no need for att_addlength_pointer */
1740  }
1741  else
1742  ubound = (Datum) 0;
1743 
1744  /* emit results */
1745 
1746  *empty = (flags & RANGE_EMPTY) != 0;
1747 
1748  lower->val = lbound;
1749  lower->infinite = (flags & RANGE_LB_INF) != 0;
1750  lower->inclusive = (flags & RANGE_LB_INC) != 0;
1751  lower->lower = true;
1752 
1753  upper->val = ubound;
1754  upper->infinite = (flags & RANGE_UB_INF) != 0;
1755  upper->inclusive = (flags & RANGE_UB_INC) != 0;
1756  upper->lower = false;
1757 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
signed short int16
Definition: c.h:345
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RANGE_EMPTY
Definition: rangetypes.h:36
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define VARSIZE(PTR)
Definition: postgres.h:303
Datum val
Definition: rangetypes.h:62
int16 typlen
Definition: typcache.h:37
#define RANGE_LB_INF
Definition: rangetypes.h:39
bool typbyval
Definition: typcache.h:38
char * Pointer
Definition: c.h:335
char typalign
Definition: pg_type.h:170
bool inclusive
Definition: rangetypes.h:64
#define RANGE_UB_INC
Definition: rangetypes.h:38
#define att_addlength_pointer(cur_offset, attlen, attptr)
Definition: tupmacs.h:174
bool lower
Definition: rangetypes.h:65
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:95
uintptr_t Datum
Definition: postgres.h:367
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:124
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define Assert(condition)
Definition: c.h:732
bool infinite
Definition: rangetypes.h:63
#define RANGE_UB_INF
Definition: rangetypes.h:40
char typalign
Definition: typcache.h:39
#define fetch_att(T, attbyval, attlen)
Definition: tupmacs.h:73

◆ range_empty()

Datum range_empty ( PG_FUNCTION_ARGS  )

Definition at line 475 of file rangetypes.c.

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

476 {
477  RangeType *r1 = PG_GETARG_RANGE_P(0);
478  char flags = range_get_flags(r1);
479 
480  PG_RETURN_BOOL(flags & RANGE_EMPTY);
481 }
#define RANGE_EMPTY
Definition: rangetypes.h:36
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766

◆ range_eq()

Datum range_eq ( PG_FUNCTION_ARGS  )

Definition at line 589 of file rangetypes.c.

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

590 {
591  RangeType *r1 = PG_GETARG_RANGE_P(0);
592  RangeType *r2 = PG_GETARG_RANGE_P(1);
593  TypeCacheEntry *typcache;
594 
595  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
596 
597  PG_RETURN_BOOL(range_eq_internal(typcache, r1, r2));
598 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:557
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_eq_internal()

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

Definition at line 557 of file rangetypes.c.

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

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

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

◆ range_ge()

Datum range_ge ( PG_FUNCTION_ARGS  )

Definition at line 1204 of file rangetypes.c.

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

1205 {
1206  int cmp = range_cmp(fcinfo);
1207 
1208  PG_RETURN_BOOL(cmp >= 0);
1209 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1142
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_get_flags()

char range_get_flags ( RangeType range)

Definition at line 1766 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().

1767 {
1768  /* fetch the flag byte from datum's last byte */
1769  return *((char *) range + VARSIZE(range) - 1);
1770 }
#define VARSIZE(PTR)
Definition: postgres.h:303

◆ range_get_typcache()

TypeCacheEntry* range_get_typcache ( FunctionCallInfo  fcinfo,
Oid  rngtypid 
)

Definition at line 1546 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(), 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_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().

1547 {
1548  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
1549 
1550  if (typcache == NULL ||
1551  typcache->type_id != rngtypid)
1552  {
1553  typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
1554  if (typcache->rngelemtype == NULL)
1555  elog(ERROR, "type %u is not a range type", rngtypid);
1556  fcinfo->flinfo->fn_extra = (void *) typcache;
1557  }
1558 
1559  return typcache;
1560 }
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:139
#define ERROR
Definition: elog.h:43
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:95
FmgrInfo * flinfo
Definition: fmgr.h:87
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:322
void * fn_extra
Definition: fmgr.h:64
#define elog(elevel,...)
Definition: elog.h:226

◆ range_gt()

Datum range_gt ( PG_FUNCTION_ARGS  )

Definition at line 1212 of file rangetypes.c.

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

1213 {
1214  int cmp = range_cmp(fcinfo);
1215 
1216  PG_RETURN_BOOL(cmp > 0);
1217 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1142
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_in()

Datum range_in ( PG_FUNCTION_ARGS  )

Definition at line 81 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, RangeIOData::proc, 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, upper(), and RangeBound::val.

82 {
83  char *input_str = PG_GETARG_CSTRING(0);
84  Oid rngtypoid = PG_GETARG_OID(1);
85  Oid typmod = PG_GETARG_INT32(2);
87  RangeIOData *cache;
88  char flags;
89  char *lbound_str;
90  char *ubound_str;
93 
94  check_stack_depth(); /* recurses when subtype is a range type */
95 
96  cache = get_range_io_data(fcinfo, rngtypoid, IOFunc_input);
97 
98  /* parse */
99  range_parse(input_str, &flags, &lbound_str, &ubound_str);
100 
101  /* call element type's input function */
102  if (RANGE_HAS_LBOUND(flags))
103  lower.val = InputFunctionCall(&cache->proc, lbound_str,
104  cache->typioparam, typmod);
105  if (RANGE_HAS_UBOUND(flags))
106  upper.val = InputFunctionCall(&cache->proc, ubound_str,
107  cache->typioparam, typmod);
108 
109  lower.infinite = (flags & RANGE_LB_INF) != 0;
110  lower.inclusive = (flags & RANGE_LB_INC) != 0;
111  lower.lower = true;
112  upper.infinite = (flags & RANGE_UB_INF) != 0;
113  upper.inclusive = (flags & RANGE_UB_INC) != 0;
114  upper.lower = false;
115 
116  /* serialize and canonicalize */
117  range = make_range(cache->typcache, &lower, &upper, flags & RANGE_EMPTY);
118 
119  PG_RETURN_RANGE_P(range);
120 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RANGE_EMPTY
Definition: rangetypes.h:36
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
static void range_parse(const char *input_str, char *flags, char **lbound_str, char **ubound_str)
Definition: rangetypes.c:2046
TypeCacheEntry * typcache
Definition: rangetypes.c:51
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
unsigned int Oid
Definition: postgres_ext.h:31
#define RANGE_LB_INF
Definition: rangetypes.h:39
bool inclusive
Definition: rangetypes.h:64
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
void check_stack_depth(void)
Definition: postgres.c:3262
#define RANGE_UB_INC
Definition: rangetypes.h:38
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
bool lower
Definition: rangetypes.h:65
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
#define RANGE_LB_INC
Definition: rangetypes.h:37
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1531
FmgrInfo proc
Definition: rangetypes.c:54
bool infinite
Definition: rangetypes.h:63
#define RANGE_UB_INF
Definition: rangetypes.h:40
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:272
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:302
Oid typioparam
Definition: rangetypes.c:53

◆ range_intersect()

Datum range_intersect ( PG_FUNCTION_ARGS  )

Definition at line 1099 of file rangetypes.c.

References DatumGetBool, elog, ERROR, make_empty_range(), make_range(), PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_cmp_bounds(), range_deserialize(), range_get_typcache(), range_overlaps(), RangeTypeGetOid, and RangeIOData::typcache.

1100 {
1101  RangeType *r1 = PG_GETARG_RANGE_P(0);
1102  RangeType *r2 = PG_GETARG_RANGE_P(1);
1103  TypeCacheEntry *typcache;
1104  RangeBound lower1,
1105  lower2;
1106  RangeBound upper1,
1107  upper2;
1108  bool empty1,
1109  empty2;
1110  RangeBound *result_lower;
1111  RangeBound *result_upper;
1112 
1113  /* Different types should be prevented by ANYRANGE matching rules */
1114  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1115  elog(ERROR, "range types do not match");
1116 
1117  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1118 
1119  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1120  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1121 
1122  if (empty1 || empty2 || !DatumGetBool(range_overlaps(fcinfo)))
1124 
1125  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
1126  result_lower = &lower1;
1127  else
1128  result_lower = &lower2;
1129 
1130  if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
1131  result_upper = &upper1;
1132  else
1133  result_upper = &upper2;
1134 
1135  PG_RETURN_RANGE_P(make_range(typcache, result_lower, result_upper, false));
1136 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1835
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum range_overlaps(PG_FUNCTION_ARGS)
Definition: rangetypes.c:858
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:1944
#define ERROR
Definition: elog.h:43
#define DatumGetBool(X)
Definition: postgres.h:393
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
#define elog(elevel,...)
Definition: elog.h:226

◆ range_le()

Datum range_le ( PG_FUNCTION_ARGS  )

Definition at line 1196 of file rangetypes.c.

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

1197 {
1198  int cmp = range_cmp(fcinfo);
1199 
1200  PG_RETURN_BOOL(cmp <= 0);
1201 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1142
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_lower()

Datum range_lower ( PG_FUNCTION_ARGS  )

Definition at line 430 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.

431 {
432  RangeType *r1 = PG_GETARG_RANGE_P(0);
433  TypeCacheEntry *typcache;
436  bool empty;
437 
438  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
439 
440  range_deserialize(typcache, r1, &lower, &upper, &empty);
441 
442  /* Return NULL if there's no finite lower bound */
443  if (empty || lower.infinite)
444  PG_RETURN_NULL();
445 
446  PG_RETURN_DATUM(lower.val);
447 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ range_lower_inc()

Datum range_lower_inc ( PG_FUNCTION_ARGS  )

Definition at line 485 of file rangetypes.c.

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

486 {
487  RangeType *r1 = PG_GETARG_RANGE_P(0);
488  char flags = range_get_flags(r1);
489 
490  PG_RETURN_BOOL(flags & RANGE_LB_INC);
491 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766

◆ range_lower_inf()

Datum range_lower_inf ( PG_FUNCTION_ARGS  )

Definition at line 505 of file rangetypes.c.

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

506 {
507  RangeType *r1 = PG_GETARG_RANGE_P(0);
508  char flags = range_get_flags(r1);
509 
510  PG_RETURN_BOOL(flags & RANGE_LB_INF);
511 }
#define RANGE_LB_INF
Definition: rangetypes.h:39
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766

◆ range_lt()

Datum range_lt ( PG_FUNCTION_ARGS  )

Definition at line 1188 of file rangetypes.c.

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

1189 {
1190  int cmp = range_cmp(fcinfo);
1191 
1192  PG_RETURN_BOOL(cmp < 0);
1193 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1142
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_merge()

Datum range_merge ( PG_FUNCTION_ARGS  )

Definition at line 1086 of file rangetypes.c.

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

1087 {
1088  RangeType *r1 = PG_GETARG_RANGE_P(0);
1089  RangeType *r2 = PG_GETARG_RANGE_P(1);
1090  TypeCacheEntry *typcache;
1091 
1092  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1093 
1094  PG_RETURN_RANGE_P(range_union_internal(typcache, r1, r2, false));
1095 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
static RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
Definition: rangetypes.c:1024
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_minus()

Datum range_minus ( PG_FUNCTION_ARGS  )

Definition at line 956 of file rangetypes.c.

References elog, ereport, errcode(), errmsg(), ERROR, RangeBound::inclusive, RangeBound::lower, make_empty_range(), make_range(), PG_GETARG_RANGE_P, PG_RETURN_NULL, PG_RETURN_RANGE_P, range_cmp_bounds(), range_deserialize(), range_get_typcache(), RangeTypeGetOid, and RangeIOData::typcache.

957 {
958  RangeType *r1 = PG_GETARG_RANGE_P(0);
959  RangeType *r2 = PG_GETARG_RANGE_P(1);
960  TypeCacheEntry *typcache;
961  RangeBound lower1,
962  lower2;
963  RangeBound upper1,
964  upper2;
965  bool empty1,
966  empty2;
967  int cmp_l1l2,
968  cmp_l1u2,
969  cmp_u1l2,
970  cmp_u1u2;
971 
972  /* Different types should be prevented by ANYRANGE matching rules */
973  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
974  elog(ERROR, "range types do not match");
975 
976  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
977 
978  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
979  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
980 
981  /* if either is empty, r1 is the correct answer */
982  if (empty1 || empty2)
983  PG_RETURN_RANGE_P(r1);
984 
985  cmp_l1l2 = range_cmp_bounds(typcache, &lower1, &lower2);
986  cmp_l1u2 = range_cmp_bounds(typcache, &lower1, &upper2);
987  cmp_u1l2 = range_cmp_bounds(typcache, &upper1, &lower2);
988  cmp_u1u2 = range_cmp_bounds(typcache, &upper1, &upper2);
989 
990  if (cmp_l1l2 < 0 && cmp_u1u2 > 0)
991  ereport(ERROR,
992  (errcode(ERRCODE_DATA_EXCEPTION),
993  errmsg("result of range difference would not be contiguous")));
994 
995  if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
996  PG_RETURN_RANGE_P(r1);
997 
998  if (cmp_l1l2 >= 0 && cmp_u1u2 <= 0)
1000 
1001  if (cmp_l1l2 <= 0 && cmp_u1l2 >= 0 && cmp_u1u2 <= 0)
1002  {
1003  lower2.inclusive = !lower2.inclusive;
1004  lower2.lower = false; /* it will become the upper bound */
1005  PG_RETURN_RANGE_P(make_range(typcache, &lower1, &lower2, false));
1006  }
1007 
1008  if (cmp_l1l2 >= 0 && cmp_u1u2 >= 0 && cmp_l1u2 <= 0)
1009  {
1010  upper2.inclusive = !upper2.inclusive;
1011  upper2.lower = true; /* it will become the lower bound */
1012  PG_RETURN_RANGE_P(make_range(typcache, &upper2, &upper1, false));
1013  }
1014 
1015  elog(ERROR, "unexpected case in range_minus");
1016  PG_RETURN_NULL();
1017 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1835
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
int errcode(int sqlerrcode)
Definition: elog.c:570
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:1944
bool inclusive
Definition: rangetypes.h:64
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:141
bool lower
Definition: rangetypes.h:65
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ range_ne()

Datum range_ne ( PG_FUNCTION_ARGS  )

Definition at line 609 of file rangetypes.c.

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

610 {
611  RangeType *r1 = PG_GETARG_RANGE_P(0);
612  RangeType *r2 = PG_GETARG_RANGE_P(1);
613  TypeCacheEntry *typcache;
614 
615  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
616 
617  PG_RETURN_BOOL(range_ne_internal(typcache, r1, r2));
618 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:602
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_ne_internal()

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

Definition at line 602 of file rangetypes.c.

References range_eq_internal().

Referenced by range_ne().

603 {
604  return (!range_eq_internal(typcache, r1, r2));
605 }
bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:557

◆ range_out()

Datum range_out ( PG_FUNCTION_ARGS  )

Definition at line 123 of file rangetypes.c.

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

Referenced by anyrange_out().

124 {
126  char *output_str;
127  RangeIOData *cache;
128  char flags;
129  char *lbound_str = NULL;
130  char *ubound_str = NULL;
133  bool empty;
134 
135  check_stack_depth(); /* recurses when subtype is a range type */
136 
137  cache = get_range_io_data(fcinfo, RangeTypeGetOid(range), IOFunc_output);
138 
139  /* deserialize */
140  range_deserialize(cache->typcache, range, &lower, &upper, &empty);
141  flags = range_get_flags(range);
142 
143  /* call element type's output function */
144  if (RANGE_HAS_LBOUND(flags))
145  lbound_str = OutputFunctionCall(&cache->proc, lower.val);
146  if (RANGE_HAS_UBOUND(flags))
147  ubound_str = OutputFunctionCall(&cache->proc, upper.val);
148 
149  /* construct result string */
150  output_str = range_deparse(flags, lbound_str, ubound_str);
151 
152  PG_RETURN_CSTRING(output_str);
153 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:51
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1575
static char * range_deparse(char flags, const char *lbound_str, const char *ubound_str)
Definition: rangetypes.c:2224
void check_stack_depth(void)
Definition: postgres.c:3262
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
FmgrInfo proc
Definition: rangetypes.c:54
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:352
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:302

◆ range_overlaps()

Datum range_overlaps ( PG_FUNCTION_ARGS  )

Definition at line 858 of file rangetypes.c.

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

Referenced by range_intersect().

859 {
860  RangeType *r1 = PG_GETARG_RANGE_P(0);
861  RangeType *r2 = PG_GETARG_RANGE_P(1);
862  TypeCacheEntry *typcache;
863 
864  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
865 
866  PG_RETURN_BOOL(range_overlaps_internal(typcache, r1, r2));
867 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:825

◆ range_overlaps_internal()

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

Definition at line 825 of file rangetypes.c.

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

Referenced by range_gist_consistent_int(), range_gist_consistent_leaf(), range_overlaps(), range_union_internal(), and spg_range_quad_leaf_consistent().

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

◆ range_overleft()

Datum range_overleft ( PG_FUNCTION_ARGS  )

Definition at line 899 of file rangetypes.c.

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

900 {
901  RangeType *r1 = PG_GETARG_RANGE_P(0);
902  RangeType *r2 = PG_GETARG_RANGE_P(1);
903  TypeCacheEntry *typcache;
904 
905  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
906 
907  PG_RETURN_BOOL(range_overleft_internal(typcache, r1, r2));
908 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:871
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_overleft_internal()

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

Definition at line 871 of file rangetypes.c.

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

Referenced by range_gist_consistent_int(), range_gist_consistent_leaf(), range_overleft(), and spg_range_quad_leaf_consistent().

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

◆ range_overright()

Datum range_overright ( PG_FUNCTION_ARGS  )

Definition at line 940 of file rangetypes.c.

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

941 {
942  RangeType *r1 = PG_GETARG_RANGE_P(0);
943  RangeType *r2 = PG_GETARG_RANGE_P(1);
944  TypeCacheEntry *typcache;
945 
946  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
947 
948  PG_RETURN_BOOL(range_overright_internal(typcache, r1, r2));
949 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:912
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_overright_internal()

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

Definition at line 912 of file rangetypes.c.

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

Referenced by range_gist_consistent_int(), range_gist_consistent_leaf(), range_overright(), and spg_range_quad_leaf_consistent().

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

◆ range_parse()

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

Definition at line 2046 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().

2048 {
2049  const char *ptr = string;
2050  bool infinite;
2051 
2052  *flags = 0;
2053 
2054  /* consume whitespace */
2055  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2056  ptr++;
2057 
2058  /* check for empty range */
2060  strlen(RANGE_EMPTY_LITERAL)) == 0)
2061  {
2062  *flags = RANGE_EMPTY;
2063  *lbound_str = NULL;
2064  *ubound_str = NULL;
2065 
2066  ptr += strlen(RANGE_EMPTY_LITERAL);
2067 
2068  /* the rest should be whitespace */
2069  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2070  ptr++;
2071 
2072  /* should have consumed everything */
2073  if (*ptr != '\0')
2074  ereport(ERROR,
2075  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2076  errmsg("malformed range literal: \"%s\"",
2077  string),
2078  errdetail("Junk after \"empty\" key word.")));
2079 
2080  return;
2081  }
2082 
2083  if (*ptr == '[')
2084  {
2085  *flags |= RANGE_LB_INC;
2086  ptr++;
2087  }
2088  else if (*ptr == '(')
2089  ptr++;
2090  else
2091  ereport(ERROR,
2092  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2093  errmsg("malformed range literal: \"%s\"",
2094  string),
2095  errdetail("Missing left parenthesis or bracket.")));
2096 
2097  ptr = range_parse_bound(string, ptr, lbound_str, &infinite);
2098  if (infinite)
2099  *flags |= RANGE_LB_INF;
2100 
2101  if (*ptr == ',')
2102  ptr++;
2103  else
2104  ereport(ERROR,
2105  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2106  errmsg("malformed range literal: \"%s\"",
2107  string),
2108  errdetail("Missing comma after lower bound.")));
2109 
2110  ptr = range_parse_bound(string, ptr, ubound_str, &infinite);
2111  if (infinite)
2112  *flags |= RANGE_UB_INF;
2113 
2114  if (*ptr == ']')
2115  {
2116  *flags |= RANGE_UB_INC;
2117  ptr++;
2118  }
2119  else if (*ptr == ')')
2120  ptr++;
2121  else /* must be a comma */
2122  ereport(ERROR,
2123  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2124  errmsg("malformed range literal: \"%s\"",
2125  string),
2126  errdetail("Too many commas.")));
2127 
2128  /* consume whitespace */
2129  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2130  ptr++;
2131 
2132  if (*ptr != '\0')
2133  ereport(ERROR,
2134  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2135  errmsg("malformed range literal: \"%s\"",
2136  string),
2137  errdetail("Junk after right parenthesis or bracket.")));
2138 }
#define RANGE_EMPTY
Definition: rangetypes.h:36
int errcode(int sqlerrcode)
Definition: elog.c:570
#define RANGE_LB_INF
Definition: rangetypes.h:39
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.c:46
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
#define ERROR
Definition: elog.h:43
#define RANGE_UB_INC
Definition: rangetypes.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:860
char string[11]
Definition: preproc-type.c:46
#define ereport(elevel, rest)
Definition: elog.h:141
static const char * range_parse_bound(const char *string, const char *ptr, char **bound_str, bool *infinite)
Definition: rangetypes.c:2155
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define RANGE_UB_INF
Definition: rangetypes.h:40
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ range_parse_bound()

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

Definition at line 2155 of file rangetypes.c.

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

Referenced by range_parse().

2157 {
2159 
2160  /* Check for null: completely empty input means null */
2161  if (*ptr == ',' || *ptr == ')' || *ptr == ']')
2162  {
2163  *bound_str = NULL;
2164  *infinite = true;
2165  }
2166  else
2167  {
2168  /* Extract string for this bound */
2169  bool inquote = false;
2170 
2171  initStringInfo(&buf);
2172  while (inquote || !(*ptr == ',' || *ptr == ')' || *ptr == ']'))
2173  {
2174  char ch = *ptr++;
2175 
2176  if (ch == '\0')
2177  ereport(ERROR,
2178  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2179  errmsg("malformed range literal: \"%s\"",
2180  string),
2181  errdetail("Unexpected end of input.")));
2182  if (ch == '\\')
2183  {
2184  if (*ptr == '\0')
2185  ereport(ERROR,
2186  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2187  errmsg("malformed range literal: \"%s\"",
2188  string),
2189  errdetail("Unexpected end of input.")));
2190  appendStringInfoChar(&buf, *ptr++);
2191  }
2192  else if (ch == '"')
2193  {
2194  if (!inquote)
2195  inquote = true;
2196  else if (*ptr == '"')
2197  {
2198  /* doubled quote within quote sequence */
2199  appendStringInfoChar(&buf, *ptr++);
2200  }
2201  else
2202  inquote = false;
2203  }
2204  else
2205  appendStringInfoChar(&buf, ch);
2206  }
2207 
2208  *bound_str = buf.data;
2209  *infinite = false;
2210  }
2211 
2212  return ptr;
2213 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:68
int errdetail(const char *fmt,...)
Definition: elog.c:860
#define ereport(elevel, rest)
Definition: elog.h:141
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:175
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ range_parse_flags()

static char range_parse_flags ( const char *  flags_str)
static

Definition at line 1974 of file rangetypes.c.

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

Referenced by range_constructor3().

1975 {
1976  char flags = 0;
1977 
1978  if (flags_str[0] == '\0' ||
1979  flags_str[1] == '\0' ||
1980  flags_str[2] != '\0')
1981  ereport(ERROR,
1982  (errcode(ERRCODE_SYNTAX_ERROR),
1983  errmsg("invalid range bound flags"),
1984  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
1985 
1986  switch (flags_str[0])
1987  {
1988  case '[':
1989  flags |= RANGE_LB_INC;
1990  break;
1991  case '(':
1992  break;
1993  default:
1994  ereport(ERROR,
1995  (errcode(ERRCODE_SYNTAX_ERROR),
1996  errmsg("invalid range bound flags"),
1997  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
1998  }
1999 
2000  switch (flags_str[1])
2001  {
2002  case ']':
2003  flags |= RANGE_UB_INC;
2004  break;
2005  case ')':
2006  break;
2007  default:
2008  ereport(ERROR,
2009  (errcode(ERRCODE_SYNTAX_ERROR),
2010  errmsg("invalid range bound flags"),
2011  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
2012  }
2013 
2014  return flags;
2015 }
int errhint(const char *fmt,...)
Definition: elog.c:974
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define RANGE_UB_INC
Definition: rangetypes.h:38
#define ereport(elevel, rest)
Definition: elog.h:141
#define RANGE_LB_INC
Definition: rangetypes.h:37
int errmsg(const char *fmt,...)
Definition: elog.c:784

◆ range_recv()

Datum range_recv ( PG_FUNCTION_ARGS  )

Definition at line 163 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(), RangeIOData::proc, 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, upper(), and RangeBound::val.

164 {
166  Oid rngtypoid = PG_GETARG_OID(1);
167  int32 typmod = PG_GETARG_INT32(2);
168  RangeType *range;
169  RangeIOData *cache;
170  char flags;
173 
174  check_stack_depth(); /* recurses when subtype is a range type */
175 
176  cache = get_range_io_data(fcinfo, rngtypoid, IOFunc_receive);
177 
178  /* receive the flags... */
179  flags = (unsigned char) pq_getmsgbyte(buf);
180 
181  /*
182  * Mask out any unsupported flags, particularly RANGE_xB_NULL which would
183  * confuse following tests. Note that range_serialize will take care of
184  * cleaning up any inconsistencies in the remaining flags.
185  */
186  flags &= (RANGE_EMPTY |
187  RANGE_LB_INC |
188  RANGE_LB_INF |
189  RANGE_UB_INC |
190  RANGE_UB_INF);
191 
192  /* receive the bounds ... */
193  if (RANGE_HAS_LBOUND(flags))
194  {
195  uint32 bound_len = pq_getmsgint(buf, 4);
196  const char *bound_data = pq_getmsgbytes(buf, bound_len);
197  StringInfoData bound_buf;
198 
199  initStringInfo(&bound_buf);
200  appendBinaryStringInfo(&bound_buf, bound_data, bound_len);
201 
202  lower.val = ReceiveFunctionCall(&cache->proc,
203  &bound_buf,
204  cache->typioparam,
205  typmod);
206  pfree(bound_buf.data);
207  }
208  else
209  lower.val = (Datum) 0;
210 
211  if (RANGE_HAS_UBOUND(flags))
212  {
213  uint32 bound_len = pq_getmsgint(buf, 4);
214  const char *bound_data = pq_getmsgbytes(buf, bound_len);
215  StringInfoData bound_buf;
216 
217  initStringInfo(&bound_buf);
218  appendBinaryStringInfo(&bound_buf, bound_data, bound_len);
219 
220  upper.val = ReceiveFunctionCall(&cache->proc,
221  &bound_buf,
222  cache->typioparam,
223  typmod);
224  pfree(bound_buf.data);
225  }
226  else
227  upper.val = (Datum) 0;
228 
229  pq_getmsgend(buf);
230 
231  /* finish constructing RangeBound representation */
232  lower.infinite = (flags & RANGE_LB_INF) != 0;
233  lower.inclusive = (flags & RANGE_LB_INC) != 0;
234  lower.lower = true;
235  upper.infinite = (flags & RANGE_UB_INF) != 0;
236  upper.inclusive = (flags & RANGE_UB_INC) != 0;
237  upper.lower = false;
238 
239  /* serialize and canonicalize */
240  range = make_range(cache->typcache, &lower, &upper, flags & RANGE_EMPTY);
241 
242  PG_RETURN_RANGE_P(range);
243 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
#define PG_GETARG_INT32(n)
Definition: fmgr.h:264
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RANGE_EMPTY
Definition: rangetypes.h:36
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
StringInfoData * StringInfo
Definition: stringinfo.h:43
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:51
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:271
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
unsigned int Oid
Definition: postgres_ext.h:31
#define RANGE_LB_INF
Definition: rangetypes.h:39
const char * pq_getmsgbytes(StringInfo msg, int datalen)
Definition: pqformat.c:510
signed int int32
Definition: c.h:346
void pfree(void *pointer)
Definition: mcxt.c:1056
bool inclusive
Definition: rangetypes.h:64
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
Definition: fmgr.c:1589
static char * buf
Definition: pg_test_fsync.c:68
#define PG_GETARG_OID(n)
Definition: fmgr.h:270
void check_stack_depth(void)
Definition: postgres.c:3262
#define RANGE_UB_INC
Definition: rangetypes.h:38
unsigned int uint32
Definition: c.h:358
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
bool lower
Definition: rangetypes.h:65
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
uintptr_t Datum
Definition: postgres.h:367
#define RANGE_LB_INC
Definition: rangetypes.h:37
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:401
FmgrInfo proc
Definition: rangetypes.c:54
bool infinite
Definition: rangetypes.h:63
#define RANGE_UB_INF
Definition: rangetypes.h:40
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:302
void appendBinaryStringInfo(StringInfo str, const char *data, int datalen)
Definition: stringinfo.c:214
Oid typioparam
Definition: rangetypes.c:53

◆ range_send()

Datum range_send ( PG_FUNCTION_ARGS  )

Definition at line 246 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(), RangeIOData::proc, range(), range_deserialize(), range_get_flags(), RANGE_HAS_LBOUND, RANGE_HAS_UBOUND, RangeTypeGetOid, SendFunctionCall(), RangeIOData::typcache, upper(), RangeBound::val, VARDATA, VARHDRSZ, and VARSIZE.

247 {
250  RangeIOData *cache;
251  char flags;
254  bool empty;
255 
256  check_stack_depth(); /* recurses when subtype is a range type */
257 
258  cache = get_range_io_data(fcinfo, RangeTypeGetOid(range), IOFunc_send);
259 
260  /* deserialize */
261  range_deserialize(cache->typcache, range, &lower, &upper, &empty);
262  flags = range_get_flags(range);
263 
264  /* construct output */
265  pq_begintypsend(buf);
266 
267  pq_sendbyte(buf, flags);
268 
269  if (RANGE_HAS_LBOUND(flags))
270  {
271  Datum bound = PointerGetDatum(SendFunctionCall(&cache->proc,
272  lower.val));
273  uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
274  char *bound_data = VARDATA(bound);
275 
276  pq_sendint32(buf, bound_len);
277  pq_sendbytes(buf, bound_data, bound_len);
278  }
279 
280  if (RANGE_HAS_UBOUND(flags))
281  {
282  Datum bound = PointerGetDatum(SendFunctionCall(&cache->proc,
283  upper.val));
284  uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
285  char *bound_data = VARDATA(bound);
286 
287  pq_sendint32(buf, bound_len);
288  pq_sendbytes(buf, bound_data, bound_len);
289  }
290 
292 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define VARDATA(PTR)
Definition: postgres.h:302
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
#define VARSIZE(PTR)
Definition: postgres.h:303
#define PointerGetDatum(X)
Definition: postgres.h:556
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
#define VARHDRSZ
Definition: c.h:555
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:51
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:360
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
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:3262
unsigned int uint32
Definition: c.h:358
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1636
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
uintptr_t Datum
Definition: postgres.h:367
FmgrInfo proc
Definition: rangetypes.c:54
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:125
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:302

◆ range_serialize()

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

Definition at line 1570 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 compute_range_stats(), daterange_canonical(), int4range_canonical(), int8range_canonical(), make_range(), rangesel(), and spg_range_quad_picksplit().

1572 {
1573  RangeType *range;
1574  int cmp;
1575  Size msize;
1576  Pointer ptr;
1577  int16 typlen;
1578  bool typbyval;
1579  char typalign;
1580  char typstorage;
1581  char flags = 0;
1582 
1583  /*
1584  * Verify range is not invalid on its face, and construct flags value,
1585  * preventing any non-canonical combinations such as infinite+inclusive.
1586  */
1587  Assert(lower->lower);
1588  Assert(!upper->lower);
1589 
1590  if (empty)
1591  flags |= RANGE_EMPTY;
1592  else
1593  {
1594  cmp = range_cmp_bound_values(typcache, lower, upper);
1595 
1596  /* error check: if lower bound value is above upper, it's wrong */
1597  if (cmp > 0)
1598  ereport(ERROR,
1599  (errcode(ERRCODE_DATA_EXCEPTION),
1600  errmsg("range lower bound must be less than or equal to range upper bound")));
1601 
1602  /* if bounds are equal, and not both inclusive, range is empty */
1603  if (cmp == 0 && !(lower->inclusive && upper->inclusive))
1604  flags |= RANGE_EMPTY;
1605  else
1606  {
1607  /* infinite boundaries are never inclusive */
1608  if (lower->infinite)
1609  flags |= RANGE_LB_INF;
1610  else if (lower->inclusive)
1611  flags |= RANGE_LB_INC;
1612  if (upper->infinite)
1613  flags |= RANGE_UB_INF;
1614  else if (upper->inclusive)
1615  flags |= RANGE_UB_INC;
1616  }
1617  }
1618 
1619  /* Fetch information about range's element type */
1620  typlen = typcache->rngelemtype->typlen;
1621  typbyval = typcache->rngelemtype->typbyval;
1622  typalign = typcache->rngelemtype->typalign;
1623  typstorage = typcache->rngelemtype->typstorage;
1624 
1625  /* Count space for varlena header and range type's OID */
1626  msize = sizeof(RangeType);
1627  Assert(msize == MAXALIGN(msize));
1628 
1629  /* Count space for bounds */
1630  if (RANGE_HAS_LBOUND(flags))
1631  {
1632  /*
1633  * Make sure item to be inserted is not toasted. It is essential that
1634  * we not insert an out-of-line toast value pointer into a range
1635  * object, for the same reasons that arrays and records can't contain
1636  * them. It would work to store a compressed-in-line value, but we
1637  * prefer to decompress and then let compression be applied to the
1638  * whole range object if necessary. But, unlike arrays, we do allow
1639  * short-header varlena objects to stay as-is.
1640  */
1641  if (typlen == -1)
1642  lower->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(lower->val));
1643 
1644  msize = datum_compute_size(msize, lower->val, typbyval, typalign,
1645  typlen, typstorage);
1646  }
1647 
1648  if (RANGE_HAS_UBOUND(flags))
1649  {
1650  /* Make sure item to be inserted is not toasted */
1651  if (typlen == -1)
1652  upper->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(upper->val));
1653 
1654  msize = datum_compute_size(msize, upper->val, typbyval, typalign,
1655  typlen, typstorage);
1656  }
1657 
1658  /* Add space for flag byte */
1659  msize += sizeof(char);
1660 
1661  /* Note: zero-fill is required here, just as in heap tuples */
1662  range = (RangeType *) palloc0(msize);
1663  SET_VARSIZE(range, msize);
1664 
1665  /* Now fill in the datum */
1666  range->rangetypid = typcache->type_id;
1667 
1668  ptr = (char *) (range + 1);
1669 
1670  if (RANGE_HAS_LBOUND(flags))
1671  {
1672  Assert(lower->lower);
1673  ptr = datum_write(ptr, lower->val, typbyval, typalign, typlen,
1674  typstorage);
1675  }
1676 
1677  if (RANGE_HAS_UBOUND(flags))
1678  {
1679  Assert(!upper->lower);
1680  ptr = datum_write(ptr, upper->val, typbyval, typalign, typlen,
1681  typstorage);
1682  }
1683 
1684  *((char *) ptr) = flags;
1685 
1686  return range;
1687 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
signed short int16
Definition: c.h:345
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RANGE_EMPTY
Definition: rangetypes.h:36
#define PointerGetDatum(X)
Definition: postgres.h:556
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:570
int16 typlen
Definition: typcache.h:37
#define RANGE_LB_INF
Definition: rangetypes.h:39
bool typbyval
Definition: typcache.h:38
Oid rangetypid
Definition: rangetypes.h:28
char * Pointer
Definition: c.h:335
char typalign
Definition: pg_type.h:170
bool inclusive
Definition: rangetypes.h:64
#define ERROR
Definition: elog.h:43
#define PG_DETOAST_DATUM_PACKED(datum)
Definition: fmgr.h:243
static Size datum_compute_size(Size sz, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2399
char typstorage
Definition: typcache.h:40
#define RANGE_UB_INC
Definition: rangetypes.h:38
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
#define ereport(elevel, rest)
Definition: elog.h:141
bool lower
Definition: rangetypes.h:65
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:95
void * palloc0(Size size)
Definition: mcxt.c:980
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2425
#define RANGE_LB_INC
Definition: rangetypes.h:37
int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1909
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
bool infinite
Definition: rangetypes.h:63
#define MAXALIGN(LEN)
Definition: c.h:685
#define RANGE_UB_INF
Definition: rangetypes.h:40
char typalign
Definition: typcache.h:39
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:329
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742

◆ range_set_contain_empty()

void range_set_contain_empty ( RangeType range)

Definition at line 1780 of file rangetypes.c.

References RANGE_CONTAIN_EMPTY, and VARSIZE.

Referenced by range_super_union().

1781 {
1782  char *flagsp;
1783 
1784  /* flag byte is datum's last byte */
1785  flagsp = (char *) range + VARSIZE(range) - 1;
1786 
1787  *flagsp |= RANGE_CONTAIN_EMPTY;
1788 }
#define VARSIZE(PTR)
Definition: postgres.h:303
#define RANGE_CONTAIN_EMPTY
Definition: rangetypes.h:43

◆ range_union()

Datum range_union ( PG_FUNCTION_ARGS  )

Definition at line 1070 of file rangetypes.c.

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

1071 {
1072  RangeType *r1 = PG_GETARG_RANGE_P(0);
1073  RangeType *r2 = PG_GETARG_RANGE_P(1);
1074  TypeCacheEntry *typcache;
1075 
1076  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1077 
1078  PG_RETURN_RANGE_P(range_union_internal(typcache, r1, r2, true));
1079 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
static RangeType * range_union_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2, bool strict)
Definition: rangetypes.c:1024
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74

◆ range_union_internal()

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

Definition at line 1024 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 range_merge(), and range_union().

1026 {
1027  RangeBound lower1,
1028  lower2;
1029  RangeBound upper1,
1030  upper2;
1031  bool empty1,
1032  empty2;
1033  RangeBound *result_lower;
1034  RangeBound *result_upper;
1035 
1036  /* Different types should be prevented by ANYRANGE matching rules */
1037  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
1038  elog(ERROR, "range types do not match");
1039 
1040  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
1041  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
1042 
1043  /* if either is empty, the other is the correct answer */
1044  if (empty1)
1045  return r2;
1046  if (empty2)
1047  return r1;
1048 
1049  if (strict &&
1050  !DatumGetBool(range_overlaps_internal(typcache, r1, r2)) &&
1051  !DatumGetBool(range_adjacent_internal(typcache, r1, r2)))
1052  ereport(ERROR,
1053  (errcode(ERRCODE_DATA_EXCEPTION),
1054  errmsg("result of range union would not be contiguous")));
1055 
1056  if (range_cmp_bounds(typcache, &lower1, &lower2) < 0)
1057  result_lower = &lower1;
1058  else
1059  result_lower = &lower2;
1060 
1061  if (range_cmp_bounds(typcache, &upper1, &upper2) > 0)
1062  result_upper = &upper1;
1063  else
1064  result_upper = &upper2;
1065 
1066  return make_range(typcache, result_lower, result_upper, false);
1067 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1795
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1835
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
int errcode(int sqlerrcode)
Definition: elog.c:570
#define ERROR
Definition: elog.h:43
#define DatumGetBool(X)
Definition: postgres.h:393
#define ereport(elevel, rest)
Definition: elog.h:141
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:782
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
bool range_overlaps_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:825

◆ range_upper()

Datum range_upper ( PG_FUNCTION_ARGS  )

Definition at line 451 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.

452 {
453  RangeType *r1 = PG_GETARG_RANGE_P(0);
454  TypeCacheEntry *typcache;
457  bool empty;
458 
459  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
460 
461  range_deserialize(typcache, r1, &lower, &upper, &empty);
462 
463  /* Return NULL if there's no finite upper bound */
464  if (empty || upper.infinite)
465  PG_RETURN_NULL();
466 
467  PG_RETURN_DATUM(upper.val);
468 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1546
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:44
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:75
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1699
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:343
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define PG_RETURN_NULL()
Definition: fmgr.h:335

◆ range_upper_inc()

Datum range_upper_inc ( PG_FUNCTION_ARGS  )

Definition at line 495 of file rangetypes.c.

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

496 {
497  RangeType *r1 = PG_GETARG_RANGE_P(0);
498  char flags = range_get_flags(r1);
499 
500  PG_RETURN_BOOL(flags & RANGE_UB_INC);
501 }
#define RANGE_UB_INC
Definition: rangetypes.h:38
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766

◆ range_upper_inf()

Datum range_upper_inf ( PG_FUNCTION_ARGS  )

Definition at line 515 of file rangetypes.c.

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

516 {
517  RangeType *r1 = PG_GETARG_RANGE_P(0);
518  char flags = range_get_flags(r1);
519 
520  PG_RETURN_BOOL(flags & RANGE_UB_INF);
521 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:349
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
#define RANGE_UB_INF
Definition: rangetypes.h:40
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1766

◆ tsrange_subdiff()

Datum tsrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1507 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1508 {
1511  float8 result;
1512 
1513  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1514  PG_RETURN_FLOAT8(result);
1515 }
#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:356
double float8
Definition: c.h:491
int64 Timestamp
Definition: timestamp.h:38

◆ tstzrange_subdiff()

Datum tstzrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1518 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1519 {
1522  float8 result;
1523 
1524  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1525  PG_RETURN_FLOAT8(result);
1526 }
#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:356
double float8
Definition: c.h:491
int64 Timestamp
Definition: timestamp.h:38