PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
rangetypes.c File Reference
#include "postgres.h"
#include "access/hash.h"
#include "lib/stringinfo.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/date.h"
#include "utils/int8.h"
#include "utils/lsyscache.h"
#include "utils/rangetypes.h"
#include "utils/timestamp.h"
Include dependency graph for rangetypes.c:

Go to the source code of this file.

Data Structures

struct  RangeIOData
 

Macros

#define 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

#define RANGE_EMPTY_LITERAL   "empty"

Definition at line 45 of file rangetypes.c.

Referenced by range_deparse(), and range_parse().

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

Definition at line 2388 of file rangetypes.c.

Referenced by datum_compute_size(), and datum_write().

Typedef Documentation

Function Documentation

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

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

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

Definition at line 1418 of file rangetypes.c.

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

1419 {
1420  RangeType *r = PG_GETARG_RANGE_P(0);
1421  TypeCacheEntry *typcache;
1422  RangeBound lower;
1423  RangeBound upper;
1424  bool empty;
1425 
1426  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1427 
1428  range_deserialize(typcache, r, &lower, &upper, &empty);
1429 
1430  if (empty)
1431  PG_RETURN_RANGE_P(r);
1432 
1433  if (!lower.infinite && !lower.inclusive)
1434  {
1435  lower.val = DirectFunctionCall2(date_pli, lower.val, Int32GetDatum(1));
1436  lower.inclusive = true;
1437  }
1438 
1439  if (!upper.infinite && upper.inclusive)
1440  {
1441  upper.val = DirectFunctionCall2(date_pli, upper.val, Int32GetDatum(1));
1442  upper.inclusive = false;
1443  }
1444 
1445  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1446 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
bool inclusive
Definition: rangetypes.h:64
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1567
#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:1696
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define Int32GetDatum(X)
Definition: postgres.h:485
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum date_pli(PG_FUNCTION_ARGS)
Definition: date.c:523
Datum daterange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1495 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1496 {
1497  int32 v1 = PG_GETARG_INT32(0);
1498  int32 v2 = PG_GETARG_INT32(1);
1499 
1500  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1501 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:326
signed int int32
Definition: c.h:246
double float8
Definition: c.h:375
static Size datum_compute_size ( Size  sz,
Datum  datum,
bool  typbyval,
char  typalign,
int16  typlen,
char  typstorage 
)
static

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

2398 {
2399  if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2401  {
2402  /*
2403  * we're anticipating converting to a short varlena header, so adjust
2404  * length and don't count any alignment
2405  */
2407  }
2408  else
2409  {
2410  data_length = att_align_datum(data_length, typalign, typlen, val);
2411  data_length = att_addlength_datum(data_length, typlen, val);
2412  }
2413 
2414  return data_length;
2415 }
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2388
#define att_align_datum(cur_offset, attalign, attlen, attdatum)
Definition: tupmacs.h:101
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:271
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:274
#define DatumGetPointer(X)
Definition: postgres.h:555
#define att_addlength_datum(cur_offset, attlen, attdatum)
Definition: tupmacs.h:160
long val
Definition: informix.c:689
static Pointer datum_write ( Pointer  ptr,
Datum  datum,
bool  typbyval,
char  typalign,
int16  typlen,
char  typstorage 
)
static

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

2424 {
2425  Size data_length;
2426 
2427  if (typbyval)
2428  {
2429  /* pass-by-value */
2430  ptr = (char *) att_align_nominal(ptr, typalign);
2431  store_att_byval(ptr, datum, typlen);
2432  data_length = typlen;
2433  }
2434  else if (typlen == -1)
2435  {
2436  /* varlena */
2437  Pointer val = DatumGetPointer(datum);
2438 
2439  if (VARATT_IS_EXTERNAL(val))
2440  {
2441  /*
2442  * Throw error, because we must never put a toast pointer inside a
2443  * range object. Caller should have detoasted it.
2444  */
2445  elog(ERROR, "cannot store a toast pointer inside a range");
2446  data_length = 0; /* keep compiler quiet */
2447  }
2448  else if (VARATT_IS_SHORT(val))
2449  {
2450  /* no alignment for short varlenas */
2451  data_length = VARSIZE_SHORT(val);
2452  memcpy(ptr, val, data_length);
2453  }
2454  else if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2455  VARATT_CAN_MAKE_SHORT(val))
2456  {
2457  /* convert to short varlena -- no alignment */
2458  data_length = VARATT_CONVERTED_SHORT_SIZE(val);
2459  SET_VARSIZE_SHORT(ptr, data_length);
2460  memcpy(ptr + 1, VARDATA(val), data_length - 1);
2461  }
2462  else
2463  {
2464  /* full 4-byte header varlena */
2465  ptr = (char *) att_align_nominal(ptr, typalign);
2466  data_length = VARSIZE(val);
2467  memcpy(ptr, val, data_length);
2468  }
2469  }
2470  else if (typlen == -2)
2471  {
2472  /* cstring ... never needs alignment */
2473  Assert(typalign == 'c');
2474  data_length = strlen(DatumGetCString(datum)) + 1;
2475  memcpy(ptr, DatumGetPointer(datum), data_length);
2476  }
2477  else
2478  {
2479  /* fixed-length pass-by-reference */
2480  ptr = (char *) att_align_nominal(ptr, typalign);
2481  Assert(typlen > 0);
2482  data_length = typlen;
2483  memcpy(ptr, DatumGetPointer(datum), data_length);
2484  }
2485 
2486  ptr += data_length;
2487 
2488  return ptr;
2489 }
#define SET_VARSIZE_SHORT(PTR, len)
Definition: postgres.h:329
#define VARDATA(PTR)
Definition: postgres.h:303
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
#define VARSIZE(PTR)
Definition: postgres.h:304
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2388
#define VARATT_IS_EXTERNAL(PTR)
Definition: postgres.h:314
char * Pointer
Definition: c.h:235
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:572
#define VARATT_IS_SHORT(PTR)
Definition: postgres.h:325
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:271
#define VARSIZE_SHORT(PTR)
Definition: postgres.h:306
#define VARATT_CONVERTED_SHORT_SIZE(PTR)
Definition: postgres.h:274
#define store_att_byval(T, newdatum, attlen)
Definition: tupmacs.h:222
#define Assert(condition)
Definition: c.h:681
size_t Size
Definition: c.h:350
#define DatumGetPointer(X)
Definition: postgres.h:555
#define elog
Definition: elog.h:219
long val
Definition: informix.c:689
Datum elem_contained_by_range ( PG_FUNCTION_ARGS  )

Definition at line 540 of file rangetypes.c.

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

541 {
544  TypeCacheEntry *typcache;
545 
546  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
547 
548  PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
549 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Definition: rangetypes.c:2341
long val
Definition: informix.c:689
static RangeIOData * get_range_io_data ( FunctionCallInfo  fcinfo,
Oid  rngtypid,
IOFuncSelector  func 
)
static

Definition at line 301 of file rangetypes.c.

References elog, ereport, errcode(), errmsg(), ERROR, FunctionCallInfoData::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, RangeIOData::typcache, TypeCacheEntry::type_id, TYPECACHE_RANGE_INFO, RangeIOData::typiofunc, and RangeIOData::typioparam.

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

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

Definition at line 1222 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, TypeCacheEntry::type_id, TYPECACHE_HASH_PROC_FINFO, upper(), and RangeBound::val.

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

Definition at line 1288 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, TypeCacheEntry::type_id, TYPECACHE_HASH_EXTENDED_PROC_FINFO, upper(), and RangeBound::val.

1289 {
1290  RangeType *r = PG_GETARG_RANGE_P(0);
1291  Datum seed = PG_GETARG_DATUM(1);
1292  uint64 result;
1293  TypeCacheEntry *typcache;
1294  TypeCacheEntry *scache;
1295  RangeBound lower;
1296  RangeBound upper;
1297  bool empty;
1298  char flags;
1299  uint64 lower_hash;
1300  uint64 upper_hash;
1301 
1303 
1304  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1305 
1306  range_deserialize(typcache, r, &lower, &upper, &empty);
1307  flags = range_get_flags(r);
1308 
1309  scache = typcache->rngelemtype;
1311  {
1312  scache = lookup_type_cache(scache->type_id,
1315  ereport(ERROR,
1316  (errcode(ERRCODE_UNDEFINED_FUNCTION),
1317  errmsg("could not identify a hash function for type %s",
1318  format_type_be(scache->type_id))));
1319  }
1320 
1321  if (RANGE_HAS_LBOUND(flags))
1323  typcache->rng_collation,
1324  lower.val,
1325  seed));
1326  else
1327  lower_hash = 0;
1328 
1329  if (RANGE_HAS_UBOUND(flags))
1331  typcache->rng_collation,
1332  upper.val,
1333  seed));
1334  else
1335  upper_hash = 0;
1336 
1337  /* Merge hashes of flags and bounds */
1338  result = DatumGetUInt64(hash_uint32_extended((uint32) flags,
1339  DatumGetInt64(seed)));
1340  result ^= lower_hash;
1341  result = ROTATE_HIGH_AND_LOW_32BITS(result);
1342  result ^= upper_hash;
1343 
1344  PG_RETURN_UINT64(result);
1345 }
#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:1543
#define TYPECACHE_HASH_EXTENDED_PROC_FINFO
Definition: typcache.h:128
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
Datum hash_uint32_extended(uint32 k, uint64 seed)
Definition: hashfunc.c:874
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1042
#define PG_RETURN_UINT64(x)
Definition: fmgr.h:328
#define OidIsValid(objectId)
Definition: c.h:532
#define ROTATE_HIGH_AND_LOW_32BITS(v)
Definition: hash.h:48
#define ERROR
Definition: elog.h:43
#define DatumGetInt64(X)
Definition: postgres.h:613
void check_stack_depth(void)
Definition: postgres.c:3150
unsigned int uint32
Definition: c.h:258
#define ereport(elevel, rest)
Definition: elog.h:122
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:88
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1696
FmgrInfo hash_extended_proc_finfo
Definition: typcache.h:73
uintptr_t Datum
Definition: postgres.h:372
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:310
Oid fn_oid
Definition: fmgr.h:59
#define DatumGetUInt64(X)
Definition: postgres.h:640
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
Oid rng_collation
Definition: typcache.h:89
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1763
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum int4range_canonical ( PG_FUNCTION_ARGS  )

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

1357 {
1358  RangeType *r = PG_GETARG_RANGE_P(0);
1359  TypeCacheEntry *typcache;
1360  RangeBound lower;
1361  RangeBound upper;
1362  bool empty;
1363 
1364  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1365 
1366  range_deserialize(typcache, r, &lower, &upper, &empty);
1367 
1368  if (empty)
1369  PG_RETURN_RANGE_P(r);
1370 
1371  if (!lower.infinite && !lower.inclusive)
1372  {
1373  lower.val = DirectFunctionCall2(int4pl, lower.val, Int32GetDatum(1));
1374  lower.inclusive = true;
1375  }
1376 
1377  if (!upper.infinite && upper.inclusive)
1378  {
1379  upper.val = DirectFunctionCall2(int4pl, upper.val, Int32GetDatum(1));
1380  upper.inclusive = false;
1381  }
1382 
1383  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1384 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
Datum int4pl(PG_FUNCTION_ARGS)
Definition: int.c:621
bool inclusive
Definition: rangetypes.h:64
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1567
#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:1696
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define Int32GetDatum(X)
Definition: postgres.h:485
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum int4range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1461 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1462 {
1463  int32 v1 = PG_GETARG_INT32(0);
1464  int32 v2 = PG_GETARG_INT32(1);
1465 
1466  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1467 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:326
signed int int32
Definition: c.h:246
double float8
Definition: c.h:375
Datum int8range_canonical ( PG_FUNCTION_ARGS  )

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

1388 {
1389  RangeType *r = PG_GETARG_RANGE_P(0);
1390  TypeCacheEntry *typcache;
1391  RangeBound lower;
1392  RangeBound upper;
1393  bool empty;
1394 
1395  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1396 
1397  range_deserialize(typcache, r, &lower, &upper, &empty);
1398 
1399  if (empty)
1400  PG_RETURN_RANGE_P(r);
1401 
1402  if (!lower.infinite && !lower.inclusive)
1403  {
1404  lower.val = DirectFunctionCall2(int8pl, lower.val, Int64GetDatum(1));
1405  lower.inclusive = true;
1406  }
1407 
1408  if (!upper.infinite && upper.inclusive)
1409  {
1410  upper.val = DirectFunctionCall2(int8pl, upper.val, Int64GetDatum(1));
1411  upper.inclusive = false;
1412  }
1413 
1414  PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false));
1415 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
Datum int8pl(PG_FUNCTION_ARGS)
Definition: int8.c:513
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
bool inclusive
Definition: rangetypes.h:64
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:1786
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1567
#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:1696
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool infinite
Definition: rangetypes.h:63
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum int8range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1470 of file rangetypes.c.

References PG_GETARG_INT64, and PG_RETURN_FLOAT8.

1471 {
1472  int64 v1 = PG_GETARG_INT64(0);
1473  int64 v2 = PG_GETARG_INT64(1);
1474 
1475  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1476 }
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:326
double float8
Definition: c.h:375
#define PG_GETARG_INT64(n)
Definition: fmgr.h:247
RangeType* make_empty_range ( TypeCacheEntry typcache)

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

1942 {
1943  RangeBound lower;
1944  RangeBound upper;
1945 
1946  lower.val = (Datum) 0;
1947  lower.infinite = false;
1948  lower.inclusive = false;
1949  lower.lower = true;
1950 
1951  upper.val = (Datum) 0;
1952  upper.infinite = false;
1953  upper.inclusive = false;
1954  upper.lower = false;
1955 
1956  return make_range(typcache, &lower, &upper, true);
1957 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1792
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
bool inclusive
Definition: rangetypes.h:64
bool lower
Definition: rangetypes.h:65
uintptr_t Datum
Definition: postgres.h:372
bool infinite
Definition: rangetypes.h:63
RangeType* make_range ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

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

1794 {
1795  RangeType *range;
1796 
1797  range = range_serialize(typcache, lower, upper, empty);
1798 
1799  /* no need to call canonical on empty ranges ... */
1800  if (OidIsValid(typcache->rng_canonical_finfo.fn_oid) &&
1801  !RangeIsEmpty(range))
1803  RangeTypePGetDatum(range)));
1804 
1805  return range;
1806 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:54
#define OidIsValid(objectId)
Definition: c.h:532
#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:1567
FmgrInfo rng_canonical_finfo
Definition: typcache.h:91
Oid fn_oid
Definition: fmgr.h:59
#define DatumGetRangeTypeP(X)
Definition: rangetypes.h:71
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:603
Datum numrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1479 of file rangetypes.c.

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

1480 {
1481  Datum v1 = PG_GETARG_DATUM(0);
1482  Datum v2 = PG_GETARG_DATUM(1);
1483  Datum numresult;
1484  float8 floatresult;
1485 
1486  numresult = DirectFunctionCall2(numeric_sub, v1, v2);
1487 
1489  numresult));
1490 
1491  PG_RETURN_FLOAT8(floatresult);
1492 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:326
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:585
double float8
Definition: c.h:375
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:3167
#define DatumGetFloat8(X)
Definition: postgres.h:734
uintptr_t Datum
Definition: postgres.h:372
Datum numeric_sub(PG_FUNCTION_ARGS)
Definition: numeric.c:2356
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:587
Datum range_adjacent ( PG_FUNCTION_ARGS  )

Definition at line 811 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_adjacent_internal(), range_get_typcache(), and RangeTypeGetOid.

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

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

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

Definition at line 710 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_after_internal(), range_get_typcache(), and RangeTypeGetOid.

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

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

686 {
687  RangeBound lower1,
688  lower2;
689  RangeBound upper1,
690  upper2;
691  bool empty1,
692  empty2;
693 
694  /* Different types should be prevented by ANYRANGE matching rules */
695  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
696  elog(ERROR, "range types do not match");
697 
698  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
699  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
700 
701  /* An empty range is neither before nor after any other range */
702  if (empty1 || empty2)
703  return false;
704 
705  return (range_cmp_bounds(typcache, &lower1, &upper2) > 0);
706 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
Datum range_before ( PG_FUNCTION_ARGS  )

Definition at line 672 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_before_internal(), range_get_typcache(), and RangeTypeGetOid.

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

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

648 {
649  RangeBound lower1,
650  lower2;
651  RangeBound upper1,
652  upper2;
653  bool empty1,
654  empty2;
655 
656  /* Different types should be prevented by ANYRANGE matching rules */
657  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
658  elog(ERROR, "range types do not match");
659 
660  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
661  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
662 
663  /* An empty range is neither before nor after any other range */
664  if (empty1 || empty2)
665  return false;
666 
667  return (range_cmp_bounds(typcache, &upper1, &lower2) < 0);
668 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
static char * range_bound_escape ( const char *  value)
static

Definition at line 2251 of file rangetypes.c.

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

Referenced by range_deparse().

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

Definition at line 1141 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(), and RangeTypeGetOid.

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

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

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

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

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

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

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

361 {
362  Datum arg1 = PG_GETARG_DATUM(0);
363  Datum arg2 = PG_GETARG_DATUM(1);
364  Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
365  RangeType *range;
366  TypeCacheEntry *typcache;
369 
370  typcache = range_get_typcache(fcinfo, rngtypid);
371 
372  lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
373  lower.infinite = PG_ARGISNULL(0);
374  lower.inclusive = true;
375  lower.lower = true;
376 
377  upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
378  upper.infinite = PG_ARGISNULL(1);
379  upper.inclusive = false;
380  upper.lower = false;
381 
382  range = make_range(typcache, &lower, &upper, false);
383 
384  PG_RETURN_RANGE_P(range);
385 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1792
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
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:372
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1882
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
bool infinite
Definition: rangetypes.h:63
Datum range_constructor3 ( PG_FUNCTION_ARGS  )

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

390 {
391  Datum arg1 = PG_GETARG_DATUM(0);
392  Datum arg2 = PG_GETARG_DATUM(1);
393  Oid rngtypid = get_fn_expr_rettype(fcinfo->flinfo);
394  RangeType *range;
395  TypeCacheEntry *typcache;
398  char flags;
399 
400  typcache = range_get_typcache(fcinfo, rngtypid);
401 
402  if (PG_ARGISNULL(2))
403  ereport(ERROR,
404  (errcode(ERRCODE_DATA_EXCEPTION),
405  errmsg("range constructor flags argument must not be null")));
406 
408 
409  lower.val = PG_ARGISNULL(0) ? (Datum) 0 : arg1;
410  lower.infinite = PG_ARGISNULL(0);
411  lower.inclusive = (flags & RANGE_LB_INC) != 0;
412  lower.lower = true;
413 
414  upper.val = PG_ARGISNULL(1) ? (Datum) 0 : arg2;
415  upper.infinite = PG_ARGISNULL(1);
416  upper.inclusive = (flags & RANGE_UB_INC) != 0;
417  upper.lower = false;
418 
419  range = make_range(typcache, &lower, &upper, false);
420 
421  PG_RETURN_RANGE_P(range);
422 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1792
static char range_parse_flags(const char *flags_str)
Definition: rangetypes.c:1971
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:273
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:122
bool lower
Definition: rangetypes.h:65
#define PG_RETURN_RANGE_P(x)
Definition: rangetypes.h:76
uintptr_t Datum
Definition: postgres.h:372
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:1882
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define PG_ARGISNULL(n)
Definition: fmgr.h:174
bool infinite
Definition: rangetypes.h:63
char * text_to_cstring(const text *t)
Definition: varlena.c:182
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum range_contained_by ( PG_FUNCTION_ARGS  )

Definition at line 634 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contained_by_internal(), range_get_typcache(), and RangeTypeGetOid.

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

Definition at line 2332 of file rangetypes.c.

References range_contains_internal().

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

2333 {
2334  return range_contains_internal(typcache, r2, r1);
2335 }
bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2300
Datum range_contains ( PG_FUNCTION_ARGS  )

Definition at line 621 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_contains_internal(), range_get_typcache(), and RangeTypeGetOid.

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

Definition at line 527 of file rangetypes.c.

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

528 {
531  TypeCacheEntry *typcache;
532 
533  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
534 
535  PG_RETURN_BOOL(range_contains_elem_internal(typcache, r, val));
536 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1543
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:233
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
uintptr_t Datum
Definition: postgres.h:372
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Definition: rangetypes.c:2341
long val
Definition: informix.c:689
bool range_contains_elem_internal ( TypeCacheEntry typcache,
RangeType r,
Datum  val 
)

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

2342 {
2343  RangeBound lower;
2344  RangeBound upper;
2345  bool empty;
2346  int32 cmp;
2347 
2348  range_deserialize(typcache, r, &lower, &upper, &empty);
2349 
2350  if (empty)
2351  return false;
2352 
2353  if (!lower.infinite)
2354  {
2356  typcache->rng_collation,
2357  lower.val, val));
2358  if (cmp > 0)
2359  return false;
2360  if (cmp == 0 && !lower.inclusive)
2361  return false;
2362  }
2363 
2364  if (!upper.infinite)
2365  {
2367  typcache->rng_collation,
2368  upper.val, val));
2369  if (cmp < 0)
2370  return false;
2371  if (cmp == 0 && !upper.inclusive)
2372  return false;
2373  }
2374 
2375  return true;
2376 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:90
#define DatumGetInt32(X)
Definition: postgres.h:478
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
Datum val
Definition: rangetypes.h:62
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1042
signed int int32
Definition: c.h:246
bool inclusive
Definition: rangetypes.h:64
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1696
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:89
long val
Definition: informix.c:689
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742
bool range_contains_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2 
)

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

2301 {
2302  RangeBound lower1;
2303  RangeBound upper1;
2304  bool empty1;
2305  RangeBound lower2;
2306  RangeBound upper2;
2307  bool empty2;
2308 
2309  /* Different types should be prevented by ANYRANGE matching rules */
2310  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
2311  elog(ERROR, "range types do not match");
2312 
2313  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2314  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2315 
2316  /* If either range is empty, the answer is easy */
2317  if (empty2)
2318  return true;
2319  else if (empty1)
2320  return false;
2321 
2322  /* Else we must have lower1 <= lower2 and upper1 >= upper2 */
2323  if (range_cmp_bounds(typcache, &lower1, &lower2) > 0)
2324  return false;
2325  if (range_cmp_bounds(typcache, &upper1, &upper2) < 0)
2326  return false;
2327 
2328  return true;
2329 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
static char * range_deparse ( char  flags,
const char *  lbound_str,
const char *  ubound_str 
)
static

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

2222 {
2224 
2225  if (flags & RANGE_EMPTY)
2226  return pstrdup(RANGE_EMPTY_LITERAL);
2227 
2228  initStringInfo(&buf);
2229 
2230  appendStringInfoChar(&buf, (flags & RANGE_LB_INC) ? '[' : '(');
2231 
2232  if (RANGE_HAS_LBOUND(flags))
2233  appendStringInfoString(&buf, range_bound_escape(lbound_str));
2234 
2235  appendStringInfoChar(&buf, ',');
2236 
2237  if (RANGE_HAS_UBOUND(flags))
2238  appendStringInfoString(&buf, range_bound_escape(ubound_str));
2239 
2240  appendStringInfoChar(&buf, (flags & RANGE_UB_INC) ? ']' : ')');
2241 
2242  return buf.data;
2243 }
#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:1076
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.c:45
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:157
static char * buf
Definition: pg_test_fsync.c:67
#define RANGE_UB_INC
Definition: rangetypes.h:38
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:169
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:2251
void range_deserialize ( TypeCacheEntry typcache,
RangeType range,
RangeBound lower,
RangeBound upper,
bool empty 
)

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

1698 {
1699  char flags;
1700  int16 typlen;
1701  bool typbyval;
1702  char typalign;
1703  Pointer ptr;
1704  Datum lbound;
1705  Datum ubound;
1706 
1707  /* assert caller passed the right typcache entry */
1708  Assert(RangeTypeGetOid(range) == typcache->type_id);
1709 
1710  /* fetch the flag byte from datum's last byte */
1711  flags = *((char *) range + VARSIZE(range) - 1);
1712 
1713  /* fetch information about range's element type */
1714  typlen = typcache->rngelemtype->typlen;
1715  typbyval = typcache->rngelemtype->typbyval;
1716  typalign = typcache->rngelemtype->typalign;
1717 
1718  /* initialize data pointer just after the range OID */
1719  ptr = (Pointer) (range + 1);
1720 
1721  /* fetch lower bound, if any */
1722  if (RANGE_HAS_LBOUND(flags))
1723  {
1724  /* att_align_pointer cannot be necessary here */
1725  lbound = fetch_att(ptr, typbyval, typlen);
1726  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
1727  }
1728  else
1729  lbound = (Datum) 0;
1730 
1731  /* fetch upper bound, if any */
1732  if (RANGE_HAS_UBOUND(flags))
1733  {
1734  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
1735  ubound = fetch_att(ptr, typbyval, typlen);
1736  /* no need for att_addlength_pointer */
1737  }
1738  else
1739  ubound = (Datum) 0;
1740 
1741  /* emit results */
1742 
1743  *empty = (flags & RANGE_EMPTY) != 0;
1744 
1745  lower->val = lbound;
1746  lower->infinite = (flags & RANGE_LB_INF) != 0;
1747  lower->inclusive = (flags & RANGE_LB_INC) != 0;
1748  lower->lower = true;
1749 
1750  upper->val = ubound;
1751  upper->infinite = (flags & RANGE_UB_INF) != 0;
1752  upper->inclusive = (flags & RANGE_UB_INC) != 0;
1753  upper->lower = false;
1754 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
signed short int16
Definition: c.h:245
#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:304
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:235
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:172
bool lower
Definition: rangetypes.h:65
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:88
uintptr_t Datum
Definition: postgres.h:372
#define att_align_pointer(cur_offset, attalign, attlen, attptr)
Definition: tupmacs.h:122
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define Assert(condition)
Definition: c.h:681
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:71
Datum range_empty ( PG_FUNCTION_ARGS  )

Definition at line 474 of file rangetypes.c.

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

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

Definition at line 588 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_eq_internal(), range_get_typcache(), and RangeTypeGetOid.

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

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

557 {
558  RangeBound lower1,
559  lower2;
560  RangeBound upper1,
561  upper2;
562  bool empty1,
563  empty2;
564 
565  /* Different types should be prevented by ANYRANGE matching rules */
566  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
567  elog(ERROR, "range types do not match");
568 
569  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
570  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
571 
572  if (empty1 && empty2)
573  return true;
574  if (empty1 != empty2)
575  return false;
576 
577  if (range_cmp_bounds(typcache, &lower1, &lower2) != 0)
578  return false;
579 
580  if (range_cmp_bounds(typcache, &upper1, &upper2) != 0)
581  return false;
582 
583  return true;
584 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
Datum range_ge ( PG_FUNCTION_ARGS  )

Definition at line 1203 of file rangetypes.c.

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

1204 {
1205  int cmp = range_cmp(fcinfo);
1206 
1207  PG_RETURN_BOOL(cmp >= 0);
1208 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
Datum range_cmp(PG_FUNCTION_ARGS)
Definition: rangetypes.c:1141
static int cmp(const chr *x, const chr *y, size_t len)
Definition: regc_locale.c:742
char range_get_flags ( RangeType range)

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

1764 {
1765  /* fetch the flag byte from datum's last byte */
1766  return *((char *) range + VARSIZE(range) - 1);
1767 }
#define VARSIZE(PTR)
Definition: postgres.h:304
TypeCacheEntry* range_get_typcache ( FunctionCallInfo  fcinfo,
Oid  rngtypid 
)

Definition at line 1543 of file rangetypes.c.

References elog, ERROR, FunctionCallInfoData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), TypeCacheEntry::rngelemtype, 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().

1544 {
1545  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
1546 
1547  if (typcache == NULL ||
1548  typcache->type_id != rngtypid)
1549  {
1550  typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
1551  if (typcache->rngelemtype == NULL)
1552  elog(ERROR, "type %u is not a range type", rngtypid);
1553  fcinfo->flinfo->fn_extra = (void *) typcache;
1554  }
1555 
1556  return typcache;
1557 }
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:125
FmgrInfo * flinfo
Definition: fmgr.h:79
#define ERROR
Definition: elog.h:43
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:88
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:310
void * fn_extra
Definition: fmgr.h:64
#define elog
Definition: elog.h:219
Datum range_gt ( PG_FUNCTION_ARGS  )

Definition at line 1211 of file rangetypes.c.

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

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

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

81 {
82  char *input_str = PG_GETARG_CSTRING(0);
83  Oid rngtypoid = PG_GETARG_OID(1);
84  Oid typmod = PG_GETARG_INT32(2);
86  RangeIOData *cache;
87  char flags;
88  char *lbound_str;
89  char *ubound_str;
92 
93  check_stack_depth(); /* recurses when subtype is a range type */
94 
95  cache = get_range_io_data(fcinfo, rngtypoid, IOFunc_input);
96 
97  /* parse */
98  range_parse(input_str, &flags, &lbound_str, &ubound_str);
99 
100  /* call element type's input function */
101  if (RANGE_HAS_LBOUND(flags))
102  lower.val = InputFunctionCall(&cache->proc, lbound_str,
103  cache->typioparam, typmod);
104  if (RANGE_HAS_UBOUND(flags))
105  upper.val = InputFunctionCall(&cache->proc, ubound_str,
106  cache->typioparam, typmod);
107 
108  lower.infinite = (flags & RANGE_LB_INF) != 0;
109  lower.inclusive = (flags & RANGE_LB_INC) != 0;
110  lower.lower = true;
111  upper.infinite = (flags & RANGE_UB_INF) != 0;
112  upper.inclusive = (flags & RANGE_UB_INC) != 0;
113  upper.lower = false;
114 
115  /* serialize and canonicalize */
116  range = make_range(cache->typcache, &lower, &upper, flags & RANGE_EMPTY);
117 
118  PG_RETURN_RANGE_P(range);
119 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1792
#define PG_GETARG_INT32(n)
Definition: fmgr.h:234
#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:43
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:2043
TypeCacheEntry * typcache
Definition: rangetypes.c:50
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
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:240
void check_stack_depth(void)
Definition: postgres.c:3150
#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:1618
FmgrInfo proc
Definition: rangetypes.c:53
bool infinite
Definition: rangetypes.h:63
#define RANGE_UB_INF
Definition: rangetypes.h:40
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:242
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:301
Oid typioparam
Definition: rangetypes.c:52
Datum range_intersect ( PG_FUNCTION_ARGS  )

Definition at line 1098 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(), and RangeTypeGetOid.

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

Definition at line 1195 of file rangetypes.c.

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

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

Definition at line 429 of file rangetypes.c.

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

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

Definition at line 484 of file rangetypes.c.

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

485 {
486  RangeType *r1 = PG_GETARG_RANGE_P(0);
487  char flags = range_get_flags(r1);
488 
489  PG_RETURN_BOOL(flags & RANGE_LB_INC);
490 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#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:1763
Datum range_lower_inf ( PG_FUNCTION_ARGS  )

Definition at line 504 of file rangetypes.c.

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

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

Definition at line 1187 of file rangetypes.c.

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

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

Definition at line 1085 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_get_typcache(), range_union_internal(), and RangeTypeGetOid.

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

Definition at line 955 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(), and RangeTypeGetOid.

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

Definition at line 608 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_ne_internal(), and RangeTypeGetOid.

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

Definition at line 601 of file rangetypes.c.

References range_eq_internal().

Referenced by range_ne().

602 {
603  return (!range_eq_internal(typcache, r1, r2));
604 }
bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:556
Datum range_out ( PG_FUNCTION_ARGS  )

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

123 {
125  char *output_str;
126  RangeIOData *cache;
127  char flags;
128  char *lbound_str = NULL;
129  char *ubound_str = NULL;
132  bool empty;
133 
134  check_stack_depth(); /* recurses when subtype is a range type */
135 
136  cache = get_range_io_data(fcinfo, RangeTypeGetOid(range), IOFunc_output);
137 
138  /* deserialize */
139  range_deserialize(cache->typcache, range, &lower, &upper, &empty);
140  flags = range_get_flags(range);
141 
142  /* call element type's output function */
143  if (RANGE_HAS_LBOUND(flags))
144  lbound_str = OutputFunctionCall(&cache->proc, lower.val);
145  if (RANGE_HAS_UBOUND(flags))
146  ubound_str = OutputFunctionCall(&cache->proc, upper.val);
147 
148  /* construct result string */
149  output_str = range_deparse(flags, lbound_str, ubound_str);
150 
151  PG_RETURN_CSTRING(output_str);
152 }
#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:43
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:50
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
char * OutputFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1662
static char * range_deparse(char flags, const char *lbound_str, const char *ubound_str)
Definition: rangetypes.c:2221
void check_stack_depth(void)
Definition: postgres.c:3150
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:1696
FmgrInfo proc
Definition: rangetypes.c:53
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:322
#define PG_GETARG_RANGE_P(n)
Definition: rangetypes.h:74
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1763
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:301
Datum range_overlaps ( PG_FUNCTION_ARGS  )

Definition at line 857 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_overlaps_internal(), and RangeTypeGetOid.

Referenced by range_intersect().

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

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

825 {
826  RangeBound lower1,
827  lower2;
828  RangeBound upper1,
829  upper2;
830  bool empty1,
831  empty2;
832 
833  /* Different types should be prevented by ANYRANGE matching rules */
834  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
835  elog(ERROR, "range types do not match");
836 
837  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
838  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
839 
840  /* An empty range does not overlap any other range */
841  if (empty1 || empty2)
842  return false;
843 
844  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0 &&
845  range_cmp_bounds(typcache, &lower1, &upper2) <= 0)
846  return true;
847 
848  if (range_cmp_bounds(typcache, &lower2, &lower1) >= 0 &&
849  range_cmp_bounds(typcache, &lower2, &upper1) <= 0)
850  return true;
851 
852  return false;
853 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
Datum range_overleft ( PG_FUNCTION_ARGS  )

Definition at line 898 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_overleft_internal(), and RangeTypeGetOid.

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

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

871 {
872  RangeBound lower1,
873  lower2;
874  RangeBound upper1,
875  upper2;
876  bool empty1,
877  empty2;
878 
879  /* Different types should be prevented by ANYRANGE matching rules */
880  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
881  elog(ERROR, "range types do not match");
882 
883  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
884  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
885 
886  /* An empty range is neither before nor after any other range */
887  if (empty1 || empty2)
888  return false;
889 
890  if (range_cmp_bounds(typcache, &upper1, &upper2) <= 0)
891  return true;
892 
893  return false;
894 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
Datum range_overright ( PG_FUNCTION_ARGS  )

Definition at line 939 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_BOOL, range_get_typcache(), range_overright_internal(), and RangeTypeGetOid.

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

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

912 {
913  RangeBound lower1,
914  lower2;
915  RangeBound upper1,
916  upper2;
917  bool empty1,
918  empty2;
919 
920  /* Different types should be prevented by ANYRANGE matching rules */
921  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
922  elog(ERROR, "range types do not match");
923 
924  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
925  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
926 
927  /* An empty range is neither before nor after any other range */
928  if (empty1 || empty2)
929  return false;
930 
931  if (range_cmp_bounds(typcache, &lower1, &lower2) >= 0)
932  return true;
933 
934  return false;
935 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1832
#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:1696
#define elog
Definition: elog.h:219
static void range_parse ( const char *  input_str,
char *  flags,
char **  lbound_str,
char **  ubound_str 
)
static

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

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

Definition at line 2152 of file rangetypes.c.

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

Referenced by range_parse().

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

Definition at line 1971 of file rangetypes.c.

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

Referenced by range_constructor3().

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

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

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

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

246 {
249  RangeIOData *cache;
250  char flags;
253  bool empty;
254 
255  check_stack_depth(); /* recurses when subtype is a range type */
256 
257  cache = get_range_io_data(fcinfo, RangeTypeGetOid(range), IOFunc_send);
258 
259  /* deserialize */
260  range_deserialize(cache->typcache, range, &lower, &upper, &empty);
261  flags = range_get_flags(range);
262 
263  /* construct output */
264  pq_begintypsend(buf);
265 
266  pq_sendbyte(buf, flags);
267 
268  if (RANGE_HAS_LBOUND(flags))
269  {
270  Datum bound = PointerGetDatum(SendFunctionCall(&cache->proc,
271  lower.val));
272  uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
273  char *bound_data = VARDATA(bound);
274 
275  pq_sendint32(buf, bound_len);
276  pq_sendbytes(buf, bound_data, bound_len);
277  }
278 
279  if (RANGE_HAS_UBOUND(flags))
280  {
281  Datum bound = PointerGetDatum(SendFunctionCall(&cache->proc,
282  upper.val));
283  uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
284  char *bound_data = VARDATA(bound);
285 
286  pq_sendint32(buf, bound_len);
287  pq_sendbytes(buf, bound_data, bound_len);
288  }
289 
291 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define VARDATA(PTR)
Definition: postgres.h:303
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define VARSIZE(PTR)
Definition: postgres.h:304
static void pq_sendint32(StringInfo buf, int32 i)
Definition: pqformat.h:148
#define PointerGetDatum(X)
Definition: postgres.h:562
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:328
#define VARHDRSZ
Definition: c.h:439
StringInfo makeStringInfo(void)
Definition: stringinfo.c:28
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:50
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:330
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
static void pq_sendbyte(StringInfo buf, int8 byt)
Definition: pqformat.h:164
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:348
static char * buf
Definition: pg_test_fsync.c:67
void check_stack_depth(void)
Definition: postgres.c:3150
unsigned int uint32
Definition: c.h:258
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1723
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:1696
uintptr_t Datum
Definition: postgres.h:372
FmgrInfo proc
Definition: rangetypes.c:53
#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:1763
static RangeIOData * get_range_io_data(FunctionCallInfo fcinfo, Oid rngtypid, IOFuncSelector func)
Definition: rangetypes.c:301
RangeType* range_serialize ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

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

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

Definition at line 1777 of file rangetypes.c.

References RANGE_CONTAIN_EMPTY, and VARSIZE.

Referenced by range_super_union().

1778 {
1779  char *flagsp;
1780 
1781  /* flag byte is datum's last byte */
1782  flagsp = (char *) range + VARSIZE(range) - 1;
1783 
1784  *flagsp |= RANGE_CONTAIN_EMPTY;
1785 }
#define VARSIZE(PTR)
Definition: postgres.h:304
#define RANGE_CONTAIN_EMPTY
Definition: rangetypes.h:43
Datum range_union ( PG_FUNCTION_ARGS  )

Definition at line 1069 of file rangetypes.c.

References PG_GETARG_RANGE_P, PG_RETURN_RANGE_P, range_get_typcache(), range_union_internal(), and RangeTypeGetOid.

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

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

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

Definition at line 450 of file rangetypes.c.

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

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

Definition at line 494 of file rangetypes.c.

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

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

Definition at line 514 of file rangetypes.c.

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

515 {
516  RangeType *r1 = PG_GETARG_RANGE_P(0);
517  char flags = range_get_flags(r1);
518 
519  PG_RETURN_BOOL(flags & RANGE_UB_INF);
520 }
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:319
#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:1763
Datum tsrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1504 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1505 {
1508  float8 result;
1509 
1510  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1511  PG_RETURN_FLOAT8(result);
1512 }
#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:326
double float8
Definition: c.h:375
int64 Timestamp
Definition: timestamp.h:38
Datum tstzrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1515 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1516 {
1519  float8 result;
1520 
1521  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1522  PG_RETURN_FLOAT8(result);
1523 }
#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:326
double float8
Definition: c.h:375
int64 Timestamp
Definition: timestamp.h:38