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 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 2324 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:1728
#define RangeIsEmpty(r)
Definition: rangetypes.h:54
#define OidIsValid(objectId)
Definition: c.h:534
bool inclusive
Definition: rangetypes.h:64
bool lower
Definition: rangetypes.h:65
FmgrInfo rng_canonical_finfo
Definition: typcache.h:87
Oid fn_oid
Definition: fmgr.h:56
int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1842
#define Assert(condition)
Definition: c.h:671
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 1354 of file rangetypes.c.

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

1355 {
1356  RangeType *r = PG_GETARG_RANGE(0);
1357  TypeCacheEntry *typcache;
1358  RangeBound lower;
1359  RangeBound upper;
1360  bool empty;
1361 
1362  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1363 
1364  range_deserialize(typcache, r, &lower, &upper, &empty);
1365 
1366  if (empty)
1367  PG_RETURN_RANGE(r);
1368 
1369  if (!lower.infinite && !lower.inclusive)
1370  {
1371  lower.val = DirectFunctionCall2(date_pli, lower.val, Int32GetDatum(1));
1372  lower.inclusive = true;
1373  }
1374 
1375  if (!upper.infinite && upper.inclusive)
1376  {
1377  upper.val = DirectFunctionCall2(date_pli, upper.val, Int32GetDatum(1));
1378  upper.inclusive = false;
1379  }
1380 
1381  PG_RETURN_RANGE(range_serialize(typcache, &lower, &upper, false));
1382 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1503
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:63
#define Int32GetDatum(X)
Definition: postgres.h:487
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:557
Datum date_pli(PG_FUNCTION_ARGS)
Definition: date.c:523
Datum daterange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1431 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1432 {
1433  int32 v1 = PG_GETARG_INT32(0);
1434  int32 v2 = PG_GETARG_INT32(1);
1435 
1436  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1437 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
signed int int32
Definition: c.h:253
double float8
Definition: c.h:378
static Size datum_compute_size ( Size  sz,
Datum  datum,
bool  typbyval,
char  typalign,
int16  typlen,
char  typstorage 
)
static

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

2334 {
2335  if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2337  {
2338  /*
2339  * we're anticipating converting to a short varlena header, so adjust
2340  * length and don't count any alignment
2341  */
2343  }
2344  else
2345  {
2346  data_length = att_align_datum(data_length, typalign, typlen, val);
2347  data_length = att_addlength_datum(data_length, typlen, val);
2348  }
2349 
2350  return data_length;
2351 }
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2324
#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:557
#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 2358 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().

2360 {
2361  Size data_length;
2362 
2363  if (typbyval)
2364  {
2365  /* pass-by-value */
2366  ptr = (char *) att_align_nominal(ptr, typalign);
2367  store_att_byval(ptr, datum, typlen);
2368  data_length = typlen;
2369  }
2370  else if (typlen == -1)
2371  {
2372  /* varlena */
2373  Pointer val = DatumGetPointer(datum);
2374 
2375  if (VARATT_IS_EXTERNAL(val))
2376  {
2377  /*
2378  * Throw error, because we must never put a toast pointer inside a
2379  * range object. Caller should have detoasted it.
2380  */
2381  elog(ERROR, "cannot store a toast pointer inside a range");
2382  data_length = 0; /* keep compiler quiet */
2383  }
2384  else if (VARATT_IS_SHORT(val))
2385  {
2386  /* no alignment for short varlenas */
2387  data_length = VARSIZE_SHORT(val);
2388  memcpy(ptr, val, data_length);
2389  }
2390  else if (TYPE_IS_PACKABLE(typlen, typstorage) &&
2391  VARATT_CAN_MAKE_SHORT(val))
2392  {
2393  /* convert to short varlena -- no alignment */
2394  data_length = VARATT_CONVERTED_SHORT_SIZE(val);
2395  SET_VARSIZE_SHORT(ptr, data_length);
2396  memcpy(ptr + 1, VARDATA(val), data_length - 1);
2397  }
2398  else
2399  {
2400  /* full 4-byte header varlena */
2401  ptr = (char *) att_align_nominal(ptr, typalign);
2402  data_length = VARSIZE(val);
2403  memcpy(ptr, val, data_length);
2404  }
2405  }
2406  else if (typlen == -2)
2407  {
2408  /* cstring ... never needs alignment */
2409  Assert(typalign == 'c');
2410  data_length = strlen(DatumGetCString(datum)) + 1;
2411  memcpy(ptr, DatumGetPointer(datum), data_length);
2412  }
2413  else
2414  {
2415  /* fixed-length pass-by-reference */
2416  ptr = (char *) att_align_nominal(ptr, typalign);
2417  Assert(typlen > 0);
2418  data_length = typlen;
2419  memcpy(ptr, DatumGetPointer(datum), data_length);
2420  }
2421 
2422  ptr += data_length;
2423 
2424  return ptr;
2425 }
#define SET_VARSIZE_SHORT(PTR, len)
Definition: postgres.h:331
#define VARDATA(PTR)
Definition: postgres.h:305
#define att_align_nominal(cur_offset, attalign)
Definition: tupmacs.h:144
#define VARSIZE(PTR)
Definition: postgres.h:306
#define TYPE_IS_PACKABLE(typlen, typstorage)
Definition: rangetypes.c:2324
#define VARATT_IS_EXTERNAL(PTR)
Definition: postgres.h:316
char * Pointer
Definition: c.h:242
#define ERROR
Definition: elog.h:43
#define DatumGetCString(X)
Definition: postgres.h:574
#define VARATT_IS_SHORT(PTR)
Definition: postgres.h:327
#define VARATT_CAN_MAKE_SHORT(PTR)
Definition: postgres.h:271
#define VARSIZE_SHORT(PTR)
Definition: postgres.h:308
#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:671
size_t Size
Definition: c.h:353
#define DatumGetPointer(X)
Definition: postgres.h:557
#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, PG_RETURN_BOOL, range_contains_elem_internal(), range_get_typcache(), RangeTypeGetOid, and val.

541 {
543  RangeType *r = PG_GETARG_RANGE(1);
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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
uintptr_t Datum
Definition: postgres.h:374
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Definition: rangetypes.c:2277
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(), NULL, 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:252
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:121
MemoryContext fn_mcxt
Definition: fmgr.h:62
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:534
FmgrInfo * flinfo
Definition: fmgr.h:71
#define ERROR
Definition: elog.h:43
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
Definition: fmgr.c:169
#define ereport(elevel, rest)
Definition: elog.h:122
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:84
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:191
#define NULL
Definition: c.h:226
FmgrInfo proc
Definition: rangetypes.c:53
void * fn_extra
Definition: fmgr.h:61
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:749
#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:2043
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, 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(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:494
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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:117
#define PG_RETURN_INT32(x)
Definition: fmgr.h:298
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:534
#define ERROR
Definition: elog.h:43
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
void check_stack_depth(void)
Definition: postgres.c:3096
unsigned int uint32
Definition: c.h:265
FmgrInfo hash_proc_finfo
Definition: typcache.h:69
#define ereport(elevel, rest)
Definition: elog.h:122
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:84
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
Datum hash_uint32(uint32 k)
Definition: hashfunc.c:512
Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation, Datum arg1)
Definition: fmgr.c:1286
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:191
Oid fn_oid
Definition: fmgr.h:56
Oid rng_collation
Definition: typcache.h:85
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum int4range_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1292 of file rangetypes.c.

References DirectFunctionCall2, RangeBound::inclusive, RangeBound::infinite, Int32GetDatum, int4pl(), lower(), PG_GETARG_RANGE, PG_RETURN_RANGE, range_deserialize(), range_get_typcache(), range_serialize(), RangeTypeGetOid, upper(), and RangeBound::val.

1293 {
1294  RangeType *r = PG_GETARG_RANGE(0);
1295  TypeCacheEntry *typcache;
1296  RangeBound lower;
1297  RangeBound upper;
1298  bool empty;
1299 
1300  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1301 
1302  range_deserialize(typcache, r, &lower, &upper, &empty);
1303 
1304  if (empty)
1305  PG_RETURN_RANGE(r);
1306 
1307  if (!lower.infinite && !lower.inclusive)
1308  {
1309  lower.val = DirectFunctionCall2(int4pl, lower.val, Int32GetDatum(1));
1310  lower.inclusive = true;
1311  }
1312 
1313  if (!upper.infinite && upper.inclusive)
1314  {
1315  upper.val = DirectFunctionCall2(int4pl, upper.val, Int32GetDatum(1));
1316  upper.inclusive = false;
1317  }
1318 
1319  PG_RETURN_RANGE(range_serialize(typcache, &lower, &upper, false));
1320 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1503
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:63
#define Int32GetDatum(X)
Definition: postgres.h:487
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:557
Datum int4range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1397 of file rangetypes.c.

References PG_GETARG_INT32, and PG_RETURN_FLOAT8.

1398 {
1399  int32 v1 = PG_GETARG_INT32(0);
1400  int32 v2 = PG_GETARG_INT32(1);
1401 
1402  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1403 }
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
signed int int32
Definition: c.h:253
double float8
Definition: c.h:378
Datum int8range_canonical ( PG_FUNCTION_ARGS  )

Definition at line 1323 of file rangetypes.c.

References DirectFunctionCall2, RangeBound::inclusive, RangeBound::infinite, Int64GetDatum(), int8pl(), lower(), PG_GETARG_RANGE, PG_RETURN_RANGE, range_deserialize(), range_get_typcache(), range_serialize(), RangeTypeGetOid, upper(), and RangeBound::val.

1324 {
1325  RangeType *r = PG_GETARG_RANGE(0);
1326  TypeCacheEntry *typcache;
1327  RangeBound lower;
1328  RangeBound upper;
1329  bool empty;
1330 
1331  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r));
1332 
1333  range_deserialize(typcache, r, &lower, &upper, &empty);
1334 
1335  if (empty)
1336  PG_RETURN_RANGE(r);
1337 
1338  if (!lower.infinite && !lower.inclusive)
1339  {
1340  lower.val = DirectFunctionCall2(int8pl, lower.val, Int64GetDatum(1));
1341  lower.inclusive = true;
1342  }
1343 
1344  if (!upper.infinite && upper.inclusive)
1345  {
1346  upper.val = DirectFunctionCall2(int8pl, upper.val, Int64GetDatum(1));
1347  upper.inclusive = false;
1348  }
1349 
1350  PG_RETURN_RANGE(range_serialize(typcache, &lower, &upper, false));
1351 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
RangeType * range_serialize(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1503
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
bool infinite
Definition: rangetypes.h:63
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:557
Datum int8range_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1406 of file rangetypes.c.

References PG_GETARG_INT64, and PG_RETURN_FLOAT8.

1407 {
1408  int64 v1 = PG_GETARG_INT64(0);
1409  int64 v2 = PG_GETARG_INT64(1);
1410 
1411  PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
1412 }
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
double float8
Definition: c.h:378
#define PG_GETARG_INT64(n)
Definition: fmgr.h:238
RangeType* make_empty_range ( TypeCacheEntry typcache)

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

1878 {
1879  RangeBound lower;
1880  RangeBound upper;
1881 
1882  lower.val = (Datum) 0;
1883  lower.infinite = false;
1884  lower.inclusive = false;
1885  lower.lower = true;
1886 
1887  upper.val = (Datum) 0;
1888  upper.infinite = false;
1889  upper.inclusive = false;
1890  upper.lower = false;
1891 
1892  return make_range(typcache, &lower, &upper, true);
1893 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1728
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:374
bool infinite
Definition: rangetypes.h:63
RangeType* make_range ( TypeCacheEntry typcache,
RangeBound lower,
RangeBound upper,
bool  empty 
)

Definition at line 1728 of file rangetypes.c.

References DatumGetRangeType, FmgrInfo::fn_oid, FunctionCall1, OidIsValid, range(), range_serialize(), RangeIsEmpty, RangeTypeGetDatum, 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().

1730 {
1731  RangeType *range;
1732 
1733  range = range_serialize(typcache, lower, upper, empty);
1734 
1735  /* no need to call canonical on empty ranges ... */
1736  if (OidIsValid(typcache->rng_canonical_finfo.fn_oid) &&
1737  !RangeIsEmpty(range))
1739  RangeTypeGetDatum(range)));
1740 
1741  return range;
1742 }
#define RangeIsEmpty(r)
Definition: rangetypes.h:54
#define RangeTypeGetDatum(X)
Definition: rangetypes.h:73
#define DatumGetRangeType(X)
Definition: rangetypes.h:71
#define OidIsValid(objectId)
Definition: c.h:534
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:1503
FmgrInfo rng_canonical_finfo
Definition: typcache.h:87
Oid fn_oid
Definition: fmgr.h:56
#define FunctionCall1(flinfo, arg1)
Definition: fmgr.h:573
Datum numrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1415 of file rangetypes.c.

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

1416 {
1417  Datum v1 = PG_GETARG_DATUM(0);
1418  Datum v2 = PG_GETARG_DATUM(1);
1419  Datum numresult;
1420  float8 floatresult;
1421 
1422  numresult = DirectFunctionCall2(numeric_sub, v1, v2);
1423 
1425  numresult));
1426 
1427  PG_RETURN_FLOAT8(floatresult);
1428 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:310
#define DirectFunctionCall1(func, arg1)
Definition: fmgr.h:555
double float8
Definition: c.h:378
Datum numeric_float8(PG_FUNCTION_ARGS)
Definition: numeric.c:3092
#define DatumGetFloat8(X)
Definition: postgres.h:736
uintptr_t Datum
Definition: postgres.h:374
Datum numeric_sub(PG_FUNCTION_ARGS)
Definition: numeric.c:2286
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:557
Datum range_adjacent ( PG_FUNCTION_ARGS  )

Definition at line 811 of file rangetypes.c.

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

812 {
813  RangeType *r1 = PG_GETARG_RANGE(0);
814  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
bool range_adjacent_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:781
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:1632
#define elog
Definition: elog.h:219
Datum range_after ( PG_FUNCTION_ARGS  )

Definition at line 710 of file rangetypes.c.

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

711 {
712  RangeType *r1 = PG_GETARG_RANGE(0);
713  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_after_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:685
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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:1768
#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:1632
#define elog
Definition: elog.h:219
Datum range_before ( PG_FUNCTION_ARGS  )

Definition at line 672 of file rangetypes.c.

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

673 {
674  RangeType *r1 = PG_GETARG_RANGE(0);
675  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_before_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:647
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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:1768
#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:1632
#define elog
Definition: elog.h:219
static char * range_bound_escape ( const char *  value)
static

Definition at line 2187 of file rangetypes.c.

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

Referenced by range_deparse().

2188 {
2189  bool nq;
2190  const char *ptr;
2192 
2193  initStringInfo(&buf);
2194 
2195  /* Detect whether we need double quotes for this value */
2196  nq = (value[0] == '\0'); /* force quotes for empty string */
2197  for (ptr = value; *ptr; ptr++)
2198  {
2199  char ch = *ptr;
2200 
2201  if (ch == '"' || ch == '\\' ||
2202  ch == '(' || ch == ')' ||
2203  ch == '[' || ch == ']' ||
2204  ch == ',' ||
2205  isspace((unsigned char) ch))
2206  {
2207  nq = true;
2208  break;
2209  }
2210  }
2211 
2212  /* And emit the string */
2213  if (nq)
2214  appendStringInfoChar(&buf, '"');
2215  for (ptr = value; *ptr; ptr++)
2216  {
2217  char ch = *ptr;
2218 
2219  if (ch == '"' || ch == '\\')
2220  appendStringInfoChar(&buf, ch);
2221  appendStringInfoChar(&buf, ch);
2222  }
2223  if (nq)
2224  appendStringInfoChar(&buf, '"');
2225 
2226  return buf.data;
2227 }
static struct @76 value
static char * buf
Definition: pg_test_fsync.c:65
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
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, 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(0);
1144  RangeType *r2 = PG_GETARG_RANGE(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:1768
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_RETURN_INT32(x)
Definition: fmgr.h:298
#define ERROR
Definition: elog.h:43
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
void check_stack_depth(void)
Definition: postgres.c:3096
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:216
#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 1842 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().

1844 {
1845  /*
1846  * First, handle cases involving infinity, which don't require invoking
1847  * the comparison proc.
1848  */
1849  if (b1->infinite && b2->infinite)
1850  {
1851  /*
1852  * Both are infinity, so they are equal unless one is lower and the
1853  * other not.
1854  */
1855  if (b1->lower == b2->lower)
1856  return 0;
1857  else
1858  return b1->lower ? -1 : 1;
1859  }
1860  else if (b1->infinite)
1861  return b1->lower ? -1 : 1;
1862  else if (b2->infinite)
1863  return b2->lower ? 1 : -1;
1864 
1865  /*
1866  * Both boundaries are finite, so compare the held values.
1867  */
1869  typcache->rng_collation,
1870  b1->val, b2->val));
1871 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:86
#define DatumGetInt32(X)
Definition: postgres.h:480
Datum val
Definition: rangetypes.h:62
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1306
bool lower
Definition: rangetypes.h:65
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:85
int range_cmp_bounds ( TypeCacheEntry typcache,
RangeBound b1,
RangeBound b2 
)

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

1769 {
1770  int32 result;
1771 
1772  /*
1773  * First, handle cases involving infinity, which don't require invoking
1774  * the comparison proc.
1775  */
1776  if (b1->infinite && b2->infinite)
1777  {
1778  /*
1779  * Both are infinity, so they are equal unless one is lower and the
1780  * other not.
1781  */
1782  if (b1->lower == b2->lower)
1783  return 0;
1784  else
1785  return b1->lower ? -1 : 1;
1786  }
1787  else if (b1->infinite)
1788  return b1->lower ? -1 : 1;
1789  else if (b2->infinite)
1790  return b2->lower ? 1 : -1;
1791 
1792  /*
1793  * Both boundaries are finite, so compare the held values.
1794  */
1796  typcache->rng_collation,
1797  b1->val, b2->val));
1798 
1799  /*
1800  * If the comparison is anything other than equal, we're done. If they
1801  * compare equal though, we still have to consider whether the boundaries
1802  * are inclusive or exclusive.
1803  */
1804  if (result == 0)
1805  {
1806  if (!b1->inclusive && !b2->inclusive)
1807  {
1808  /* both are exclusive */
1809  if (b1->lower == b2->lower)
1810  return 0;
1811  else
1812  return b1->lower ? 1 : -1;
1813  }
1814  else if (!b1->inclusive)
1815  return b1->lower ? 1 : -1;
1816  else if (!b2->inclusive)
1817  return b2->lower ? -1 : 1;
1818  else
1819  {
1820  /*
1821  * Both are inclusive and the values held are equal, so they are
1822  * equal regardless of whether they are upper or lower boundaries,
1823  * or a mix.
1824  */
1825  return 0;
1826  }
1827  }
1828 
1829  return result;
1830 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:86
#define DatumGetInt32(X)
Definition: postgres.h:480
Datum val
Definition: rangetypes.h:62
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition: fmgr.c:1306
signed int int32
Definition: c.h:253
bool inclusive
Definition: rangetypes.h:64
bool lower
Definition: rangetypes.h:65
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:85
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, 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(range);
385 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1728
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
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
uintptr_t Datum
Definition: postgres.h:374
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:2198
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
#define PG_ARGISNULL(n)
Definition: fmgr.h:166
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_P, PG_RETURN_RANGE, 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(range);
422 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1728
static char range_parse_flags(const char *flags_str)
Definition: rangetypes.c:1907
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
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
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
uintptr_t Datum
Definition: postgres.h:374
Oid get_fn_expr_rettype(FmgrInfo *flinfo)
Definition: fmgr.c:2198
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
#define PG_ARGISNULL(n)
Definition: fmgr.h:166
bool infinite
Definition: rangetypes.h:63
char * text_to_cstring(const text *t)
Definition: varlena.c:184
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Datum range_contained_by ( PG_FUNCTION_ARGS  )

Definition at line 634 of file rangetypes.c.

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

635 {
636  RangeType *r1 = PG_GETARG_RANGE(0);
637  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_contained_by_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2268
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
bool range_contained_by_internal ( TypeCacheEntry typcache,
RangeType r1,
RangeType r2 
)

Definition at line 2268 of file rangetypes.c.

References range_contains_internal().

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

2269 {
2270  return range_contains_internal(typcache, r2, r1);
2271 }
bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2236
Datum range_contains ( PG_FUNCTION_ARGS  )

Definition at line 621 of file rangetypes.c.

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

622 {
623  RangeType *r1 = PG_GETARG_RANGE(0);
624  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
bool range_contains_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:2236
Datum range_contains_elem ( PG_FUNCTION_ARGS  )

Definition at line 527 of file rangetypes.c.

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

528 {
529  RangeType *r = PG_GETARG_RANGE(0);
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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:224
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
uintptr_t Datum
Definition: postgres.h:374
bool range_contains_elem_internal(TypeCacheEntry *typcache, RangeType *r, Datum val)
Definition: rangetypes.c:2277
long val
Definition: informix.c:689
bool range_contains_elem_internal ( TypeCacheEntry typcache,
RangeType r,
Datum  val 
)

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

2278 {
2279  RangeBound lower;
2280  RangeBound upper;
2281  bool empty;
2282  int32 cmp;
2283 
2284  range_deserialize(typcache, r, &lower, &upper, &empty);
2285 
2286  if (empty)
2287  return false;
2288 
2289  if (!lower.infinite)
2290  {
2292  typcache->rng_collation,
2293  lower.val, val));
2294  if (cmp > 0)
2295  return false;
2296  if (cmp == 0 && !lower.inclusive)
2297  return false;
2298  }
2299 
2300  if (!upper.infinite)
2301  {
2303  typcache->rng_collation,
2304  upper.val, val));
2305  if (cmp < 0)
2306  return false;
2307  if (cmp == 0 && !upper.inclusive)
2308  return false;
2309  }
2310 
2311  return true;
2312 }
FmgrInfo rng_cmp_proc_finfo
Definition: typcache.h:86
#define DatumGetInt32(X)
Definition: postgres.h:480
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:1306
signed int int32
Definition: c.h:253
bool inclusive
Definition: rangetypes.h:64
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
bool infinite
Definition: rangetypes.h:63
Oid rng_collation
Definition: typcache.h:85
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 2236 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().

2237 {
2238  RangeBound lower1;
2239  RangeBound upper1;
2240  bool empty1;
2241  RangeBound lower2;
2242  RangeBound upper2;
2243  bool empty2;
2244 
2245  /* Different types should be prevented by ANYRANGE matching rules */
2246  if (RangeTypeGetOid(r1) != RangeTypeGetOid(r2))
2247  elog(ERROR, "range types do not match");
2248 
2249  range_deserialize(typcache, r1, &lower1, &upper1, &empty1);
2250  range_deserialize(typcache, r2, &lower2, &upper2, &empty2);
2251 
2252  /* If either range is empty, the answer is easy */
2253  if (empty2)
2254  return true;
2255  else if (empty1)
2256  return false;
2257 
2258  /* Else we must have lower1 <= lower2 and upper1 >= upper2 */
2259  if (range_cmp_bounds(typcache, &lower1, &lower2) > 0)
2260  return false;
2261  if (range_cmp_bounds(typcache, &upper1, &upper2) < 0)
2262  return false;
2263 
2264  return true;
2265 }
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1768
#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:1632
#define elog
Definition: elog.h:219
static char * range_deparse ( char  flags,
const char *  lbound_str,
const char *  ubound_str 
)
static

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

2158 {
2160 
2161  if (flags & RANGE_EMPTY)
2162  return pstrdup(RANGE_EMPTY_LITERAL);
2163 
2164  initStringInfo(&buf);
2165 
2166  appendStringInfoChar(&buf, (flags & RANGE_LB_INC) ? '[' : '(');
2167 
2168  if (RANGE_HAS_LBOUND(flags))
2169  appendStringInfoString(&buf, range_bound_escape(lbound_str));
2170 
2171  appendStringInfoChar(&buf, ',');
2172 
2173  if (RANGE_HAS_UBOUND(flags))
2174  appendStringInfoString(&buf, range_bound_escape(ubound_str));
2175 
2176  appendStringInfoChar(&buf, (flags & RANGE_UB_INC) ? ']' : ')');
2177 
2178  return buf.data;
2179 }
#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:1165
#define RANGE_EMPTY_LITERAL
Definition: rangetypes.c:45
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:189
static char * buf
Definition: pg_test_fsync.c:65
#define RANGE_UB_INC
Definition: rangetypes.h:38
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define RANGE_LB_INC
Definition: rangetypes.h:37
static char * range_bound_escape(const char *value)
Definition: rangetypes.c:2187
void range_deserialize ( TypeCacheEntry typcache,
RangeType range,
RangeBound lower,
RangeBound upper,
bool empty 
)

Definition at line 1632 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(), 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(), spg_range_quad_picksplit(), TQExamineRange(), and TQRemapRange().

1634 {
1635  char flags;
1636  int16 typlen;
1637  bool typbyval;
1638  char typalign;
1639  Pointer ptr;
1640  Datum lbound;
1641  Datum ubound;
1642 
1643  /* assert caller passed the right typcache entry */
1644  Assert(RangeTypeGetOid(range) == typcache->type_id);
1645 
1646  /* fetch the flag byte from datum's last byte */
1647  flags = *((char *) range + VARSIZE(range) - 1);
1648 
1649  /* fetch information about range's element type */
1650  typlen = typcache->rngelemtype->typlen;
1651  typbyval = typcache->rngelemtype->typbyval;
1652  typalign = typcache->rngelemtype->typalign;
1653 
1654  /* initialize data pointer just after the range OID */
1655  ptr = (Pointer) (range + 1);
1656 
1657  /* fetch lower bound, if any */
1658  if (RANGE_HAS_LBOUND(flags))
1659  {
1660  /* att_align_pointer cannot be necessary here */
1661  lbound = fetch_att(ptr, typbyval, typlen);
1662  ptr = (Pointer) att_addlength_pointer(ptr, typlen, ptr);
1663  }
1664  else
1665  lbound = (Datum) 0;
1666 
1667  /* fetch upper bound, if any */
1668  if (RANGE_HAS_UBOUND(flags))
1669  {
1670  ptr = (Pointer) att_align_pointer(ptr, typalign, typlen, ptr);
1671  ubound = fetch_att(ptr, typbyval, typlen);
1672  /* no need for att_addlength_pointer */
1673  }
1674  else
1675  ubound = (Datum) 0;
1676 
1677  /* emit results */
1678 
1679  *empty = (flags & RANGE_EMPTY) != 0;
1680 
1681  lower->val = lbound;
1682  lower->infinite = (flags & RANGE_LB_INF) != 0;
1683  lower->inclusive = (flags & RANGE_LB_INC) != 0;
1684  lower->lower = true;
1685 
1686  upper->val = ubound;
1687  upper->infinite = (flags & RANGE_UB_INF) != 0;
1688  upper->inclusive = (flags & RANGE_UB_INC) != 0;
1689  upper->lower = false;
1690 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
signed short int16
Definition: c.h:252
#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:306
Datum val
Definition: rangetypes.h:62
int16 typlen
Definition: typcache.h:35
#define RANGE_LB_INF
Definition: rangetypes.h:39
bool typbyval
Definition: typcache.h:36
char * Pointer
Definition: c.h:242
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:84
uintptr_t Datum
Definition: postgres.h:374
#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:671
bool infinite
Definition: rangetypes.h:63
#define RANGE_UB_INF
Definition: rangetypes.h:40
char typalign
Definition: typcache.h:37
#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, PG_RETURN_BOOL, RANGE_EMPTY, and range_get_flags().

475 {
476  RangeType *r1 = PG_GETARG_RANGE(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_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
Datum range_eq ( PG_FUNCTION_ARGS  )

Definition at line 588 of file rangetypes.c.

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

589 {
590  RangeType *r1 = PG_GETARG_RANGE(0);
591  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_eq_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:556
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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:1768
#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:1632
#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:303
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 1699 of file rangetypes.c.

References VARSIZE.

Referenced by get_gist_range_class(), hash_range(), 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().

1700 {
1701  /* fetch the flag byte from datum's last byte */
1702  return *((char *) range + VARSIZE(range) - 1);
1703 }
#define VARSIZE(PTR)
Definition: postgres.h:306
TypeCacheEntry* range_get_typcache ( FunctionCallInfo  fcinfo,
Oid  rngtypid 
)

Definition at line 1479 of file rangetypes.c.

References elog, ERROR, FunctionCallInfoData::flinfo, FmgrInfo::fn_extra, lookup_type_cache(), NULL, TypeCacheEntry::rngelemtype, TypeCacheEntry::type_id, and TYPECACHE_RANGE_INFO.

Referenced by daterange_canonical(), elem_contained_by_range(), hash_range(), 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().

1480 {
1481  TypeCacheEntry *typcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
1482 
1483  if (typcache == NULL ||
1484  typcache->type_id != rngtypid)
1485  {
1486  typcache = lookup_type_cache(rngtypid, TYPECACHE_RANGE_INFO);
1487  if (typcache->rngelemtype == NULL)
1488  elog(ERROR, "type %u is not a range type", rngtypid);
1489  fcinfo->flinfo->fn_extra = (void *) typcache;
1490  }
1491 
1492  return typcache;
1493 }
#define TYPECACHE_RANGE_INFO
Definition: typcache.h:121
FmgrInfo * flinfo
Definition: fmgr.h:71
#define ERROR
Definition: elog.h:43
struct TypeCacheEntry * rngelemtype
Definition: typcache.h:84
TypeCacheEntry * lookup_type_cache(Oid type_id, int flags)
Definition: typcache.c:191
#define NULL
Definition: c.h:226
void * fn_extra
Definition: fmgr.h:61
#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:303
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, 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(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:1728
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
#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:1979
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:231
void check_stack_depth(void)
Definition: postgres.c:3096
#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 RANGE_LB_INC
Definition: rangetypes.h:37
Datum InputFunctionCall(FmgrInfo *flinfo, char *str, Oid typioparam, int32 typmod)
Definition: fmgr.c:1882
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
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:233
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, PG_RETURN_RANGE, range_cmp_bounds(), range_deserialize(), range_get_typcache(), range_overlaps(), and RangeTypeGetOid.

1099 {
1100  RangeType *r1 = PG_GETARG_RANGE(0);
1101  RangeType *r2 = PG_GETARG_RANGE(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)))
1122  PG_RETURN_RANGE(make_empty_range(typcache));
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(make_range(typcache, result_lower, result_upper, false));
1135 }
RangeType * make_range(TypeCacheEntry *typcache, RangeBound *lower, RangeBound *upper, bool empty)
Definition: rangetypes.c:1728
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1768
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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:1877
#define ERROR
Definition: elog.h:43
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define DatumGetBool(X)
Definition: postgres.h:401
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
#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:303
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, PG_RETURN_DATUM, PG_RETURN_NULL, range_deserialize(), range_get_typcache(), RangeTypeGetOid, upper(), and RangeBound::val.

430 {
431  RangeType *r1 = PG_GETARG_RANGE(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:1479
#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
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
bool infinite
Definition: rangetypes.h:63
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum range_lower_inc ( PG_FUNCTION_ARGS  )

Definition at line 484 of file rangetypes.c.

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

485 {
486  RangeType *r1 = PG_GETARG_RANGE(0);
487  char flags = range_get_flags(r1);
488 
489  PG_RETURN_BOOL(flags & RANGE_LB_INC);
490 }
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
#define RANGE_LB_INC
Definition: rangetypes.h:37
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
Datum range_lower_inf ( PG_FUNCTION_ARGS  )

Definition at line 504 of file rangetypes.c.

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

505 {
506  RangeType *r1 = PG_GETARG_RANGE(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_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
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:303
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, PG_RETURN_RANGE, range_get_typcache(), range_union_internal(), and RangeTypeGetOid.

1086 {
1087  RangeType *r1 = PG_GETARG_RANGE(0);
1088  RangeType *r2 = PG_GETARG_RANGE(1);
1089  TypeCacheEntry *typcache;
1090 
1091  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1092 
1093  PG_RETURN_RANGE(range_union_internal(typcache, r1, r2, false));
1094 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
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, PG_RETURN_NULL, PG_RETURN_RANGE, range_cmp_bounds(), range_deserialize(), range_get_typcache(), and RangeTypeGetOid.

956 {
957  RangeType *r1 = PG_GETARG_RANGE(0);
958  RangeType *r2 = PG_GETARG_RANGE(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(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(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(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(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:1728
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1768
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
int errcode(int sqlerrcode)
Definition: elog.c:575
RangeType * make_empty_range(TypeCacheEntry *typcache)
Definition: rangetypes.c:1877
bool inclusive
Definition: rangetypes.h:64
#define ERROR
Definition: elog.h:43
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define ereport(elevel, rest)
Definition: elog.h:122
bool lower
Definition: rangetypes.h:65
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum range_ne ( PG_FUNCTION_ARGS  )

Definition at line 608 of file rangetypes.c.

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

609 {
610  RangeType *r1 = PG_GETARG_RANGE(0);
611  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
bool range_ne_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:601
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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(), NULL, OutputFunctionCall(), PG_GETARG_RANGE, 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:1926
static char * range_deparse(char flags, const char *lbound_str, const char *ubound_str)
Definition: rangetypes.c:2157
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
void check_stack_depth(void)
Definition: postgres.c:3096
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:1632
#define NULL
Definition: c.h:226
FmgrInfo proc
Definition: rangetypes.c:53
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:306
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
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, PG_RETURN_BOOL, range_get_typcache(), range_overlaps_internal(), and RangeTypeGetOid.

Referenced by range_intersect().

858 {
859  RangeType *r1 = PG_GETARG_RANGE(0);
860  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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:1768
#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:1632
#define elog
Definition: elog.h:219
Datum range_overleft ( PG_FUNCTION_ARGS  )

Definition at line 898 of file rangetypes.c.

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

899 {
900  RangeType *r1 = PG_GETARG_RANGE(0);
901  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_overleft_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:870
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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:1768
#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:1632
#define elog
Definition: elog.h:219
Datum range_overright ( PG_FUNCTION_ARGS  )

Definition at line 939 of file rangetypes.c.

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

940 {
941  RangeType *r1 = PG_GETARG_RANGE(0);
942  RangeType *r2 = PG_GETARG_RANGE(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:1479
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
bool range_overright_internal(TypeCacheEntry *typcache, RangeType *r1, RangeType *r2)
Definition: rangetypes.c:911
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
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:1768
#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:1632
#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 1979 of file rangetypes.c.

References ereport, errcode(), errdetail(), errmsg(), ERROR, NULL, 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().

1981 {
1982  const char *ptr = string;
1983  bool infinite;
1984 
1985  *flags = 0;
1986 
1987  /* consume whitespace */
1988  while (*ptr != '\0' && isspace((unsigned char) *ptr))
1989  ptr++;
1990 
1991  /* check for empty range */
1993  strlen(RANGE_EMPTY_LITERAL)) == 0)
1994  {
1995  *flags = RANGE_EMPTY;
1996  *lbound_str = NULL;
1997  *ubound_str = NULL;
1998 
1999  ptr += strlen(RANGE_EMPTY_LITERAL);
2000 
2001  /* the rest should be whitespace */
2002  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2003  ptr++;
2004 
2005  /* should have consumed everything */
2006  if (*ptr != '\0')
2007  ereport(ERROR,
2008  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2009  errmsg("malformed range literal: \"%s\"",
2010  string),
2011  errdetail("Junk after \"empty\" key word.")));
2012 
2013  return;
2014  }
2015 
2016  if (*ptr == '[')
2017  {
2018  *flags |= RANGE_LB_INC;
2019  ptr++;
2020  }
2021  else if (*ptr == '(')
2022  ptr++;
2023  else
2024  ereport(ERROR,
2025  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2026  errmsg("malformed range literal: \"%s\"",
2027  string),
2028  errdetail("Missing left parenthesis or bracket.")));
2029 
2030  ptr = range_parse_bound(string, ptr, lbound_str, &infinite);
2031  if (infinite)
2032  *flags |= RANGE_LB_INF;
2033 
2034  if (*ptr == ',')
2035  ptr++;
2036  else
2037  ereport(ERROR,
2038  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2039  errmsg("malformed range literal: \"%s\"",
2040  string),
2041  errdetail("Missing comma after lower bound.")));
2042 
2043  ptr = range_parse_bound(string, ptr, ubound_str, &infinite);
2044  if (infinite)
2045  *flags |= RANGE_UB_INF;
2046 
2047  if (*ptr == ']')
2048  {
2049  *flags |= RANGE_UB_INC;
2050  ptr++;
2051  }
2052  else if (*ptr == ')')
2053  ptr++;
2054  else /* must be a comma */
2055  ereport(ERROR,
2056  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2057  errmsg("malformed range literal: \"%s\"",
2058  string),
2059  errdetail("Too many commas.")));
2060 
2061  /* consume whitespace */
2062  while (*ptr != '\0' && isspace((unsigned char) *ptr))
2063  ptr++;
2064 
2065  if (*ptr != '\0')
2066  ereport(ERROR,
2067  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2068  errmsg("malformed range literal: \"%s\"",
2069  string),
2070  errdetail("Junk after right parenthesis or bracket.")));
2071 }
#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:2088
#define RANGE_LB_INC
Definition: rangetypes.h:37
#define NULL
Definition: c.h:226
#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 2088 of file rangetypes.c.

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

Referenced by range_parse().

2090 {
2092 
2093  /* Check for null: completely empty input means null */
2094  if (*ptr == ',' || *ptr == ')' || *ptr == ']')
2095  {
2096  *bound_str = NULL;
2097  *infinite = true;
2098  }
2099  else
2100  {
2101  /* Extract string for this bound */
2102  bool inquote = false;
2103 
2104  initStringInfo(&buf);
2105  while (inquote || !(*ptr == ',' || *ptr == ')' || *ptr == ']'))
2106  {
2107  char ch = *ptr++;
2108 
2109  if (ch == '\0')
2110  ereport(ERROR,
2111  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2112  errmsg("malformed range literal: \"%s\"",
2113  string),
2114  errdetail("Unexpected end of input.")));
2115  if (ch == '\\')
2116  {
2117  if (*ptr == '\0')
2118  ereport(ERROR,
2119  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
2120  errmsg("malformed range literal: \"%s\"",
2121  string),
2122  errdetail("Unexpected end of input.")));
2123  appendStringInfoChar(&buf, *ptr++);
2124  }
2125  else if (ch == '"')
2126  {
2127  if (!inquote)
2128  inquote = true;
2129  else if (*ptr == '"')
2130  {
2131  /* doubled quote within quote sequence */
2132  appendStringInfoChar(&buf, *ptr++);
2133  }
2134  else
2135  inquote = false;
2136  }
2137  else
2138  appendStringInfoChar(&buf, ch);
2139  }
2140 
2141  *bound_str = buf.data;
2142  *infinite = false;
2143  }
2144 
2145  return ptr;
2146 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
static char * buf
Definition: pg_test_fsync.c:65
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:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define NULL
Definition: c.h:226
int errmsg(const char *fmt,...)
Definition: elog.c:797
static char range_parse_flags ( const char *  flags_str)
static

Definition at line 1907 of file rangetypes.c.

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

Referenced by range_constructor3().

1908 {
1909  char flags = 0;
1910 
1911  if (flags_str[0] == '\0' ||
1912  flags_str[1] == '\0' ||
1913  flags_str[2] != '\0')
1914  ereport(ERROR,
1915  (errcode(ERRCODE_SYNTAX_ERROR),
1916  errmsg("invalid range bound flags"),
1917  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
1918 
1919  switch (flags_str[0])
1920  {
1921  case '[':
1922  flags |= RANGE_LB_INC;
1923  break;
1924  case '(':
1925  break;
1926  default:
1927  ereport(ERROR,
1928  (errcode(ERRCODE_SYNTAX_ERROR),
1929  errmsg("invalid range bound flags"),
1930  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
1931  }
1932 
1933  switch (flags_str[1])
1934  {
1935  case ']':
1936  flags |= RANGE_UB_INC;
1937  break;
1938  case ')':
1939  break;
1940  default:
1941  ereport(ERROR,
1942  (errcode(ERRCODE_SYNTAX_ERROR),
1943  errmsg("invalid range bound flags"),
1944  errhint("Valid values are \"[]\", \"[)\", \"(]\", and \"()\".")));
1945  }
1946 
1947  return flags;
1948 }
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, 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(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:1728
#define PG_GETARG_INT32(n)
Definition: fmgr.h:225
#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:46
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:50
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:232
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:550
signed int int32
Definition: c.h:253
void pfree(void *pointer)
Definition: mcxt.c:992
bool inclusive
Definition: rangetypes.h:64
Datum ReceiveFunctionCall(FmgrInfo *flinfo, StringInfo buf, Oid typioparam, int32 typmod)
Definition: fmgr.c:1940
static char * buf
Definition: pg_test_fsync.c:65
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
void check_stack_depth(void)
Definition: postgres.c:3096
#define RANGE_UB_INC
Definition: rangetypes.h:38
unsigned int uint32
Definition: c.h:265
static struct cvec * range(struct vars *v, chr a, chr b, int cases)
Definition: regc_locale.c:416
bool lower
Definition: rangetypes.h:65
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
uintptr_t Datum
Definition: postgres.h:374
#define RANGE_LB_INC
Definition: rangetypes.h:37
int pq_getmsgbyte(StringInfo msg)
Definition: pqformat.c:432
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
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:448
void pq_getmsgend(StringInfo msg)
Definition: pqformat.c:677
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:240
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, PG_RETURN_BYTEA_P, PointerGetDatum, pq_begintypsend(), pq_endtypsend(), pq_sendbyte(), pq_sendbytes(), pq_sendint(), 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_sendint(buf, bound_len, 4);
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_sendint(buf, bound_len, 4);
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:305
void pq_sendbyte(StringInfo buf, int byt)
Definition: pqformat.c:105
#define RangeTypeGetOid(r)
Definition: rangetypes.h:33
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:43
#define VARSIZE(PTR)
Definition: postgres.h:306
#define PointerGetDatum(X)
Definition: postgres.h:564
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:359
#define VARHDRSZ
Definition: c.h:441
StringInfo makeStringInfo(void)
Definition: stringinfo.c:29
Datum val
Definition: rangetypes.h:62
TypeCacheEntry * typcache
Definition: rangetypes.c:50
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:313
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:74
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:379
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
static char * buf
Definition: pg_test_fsync.c:65
void check_stack_depth(void)
Definition: postgres.c:3096
unsigned int uint32
Definition: c.h:265
bytea * SendFunctionCall(FmgrInfo *flinfo, Datum val)
Definition: fmgr.c:1987
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:1632
uintptr_t Datum
Definition: postgres.h:374
FmgrInfo proc
Definition: rangetypes.c:53
void pq_sendbytes(StringInfo buf, const char *data, int datalen)
Definition: pqformat.c:115
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
void pq_sendint(StringInfo buf, int i, int b)
Definition: pqformat.c:236
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 1503 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(), spg_range_quad_picksplit(), and TQRemapRange().

1505 {
1506  RangeType *range;
1507  int cmp;
1508  Size msize;
1509  Pointer ptr;
1510  int16 typlen;
1511  bool typbyval;
1512  char typalign;
1513  char typstorage;
1514  char flags = 0;
1515 
1516  /*
1517  * Verify range is not invalid on its face, and construct flags value,
1518  * preventing any non-canonical combinations such as infinite+inclusive.
1519  */
1520  Assert(lower->lower);
1521  Assert(!upper->lower);
1522 
1523  if (empty)
1524  flags |= RANGE_EMPTY;
1525  else
1526  {
1527  cmp = range_cmp_bound_values(typcache, lower, upper);
1528 
1529  /* error check: if lower bound value is above upper, it's wrong */
1530  if (cmp > 0)
1531  ereport(ERROR,
1532  (errcode(ERRCODE_DATA_EXCEPTION),
1533  errmsg("range lower bound must be less than or equal to range upper bound")));
1534 
1535  /* if bounds are equal, and not both inclusive, range is empty */
1536  if (cmp == 0 && !(lower->inclusive && upper->inclusive))
1537  flags |= RANGE_EMPTY;
1538  else
1539  {
1540  /* infinite boundaries are never inclusive */
1541  if (lower->infinite)
1542  flags |= RANGE_LB_INF;
1543  else if (lower->inclusive)
1544  flags |= RANGE_LB_INC;
1545  if (upper->infinite)
1546  flags |= RANGE_UB_INF;
1547  else if (upper->inclusive)
1548  flags |= RANGE_UB_INC;
1549  }
1550  }
1551 
1552  /* Fetch information about range's element type */
1553  typlen = typcache->rngelemtype->typlen;
1554  typbyval = typcache->rngelemtype->typbyval;
1555  typalign = typcache->rngelemtype->typalign;
1556  typstorage = typcache->rngelemtype->typstorage;
1557 
1558  /* Count space for varlena header and range type's OID */
1559  msize = sizeof(RangeType);
1560  Assert(msize == MAXALIGN(msize));
1561 
1562  /* Count space for bounds */
1563  if (RANGE_HAS_LBOUND(flags))
1564  {
1565  /*
1566  * Make sure item to be inserted is not toasted. It is essential that
1567  * we not insert an out-of-line toast value pointer into a range
1568  * object, for the same reasons that arrays and records can't contain
1569  * them. It would work to store a compressed-in-line value, but we
1570  * prefer to decompress and then let compression be applied to the
1571  * whole range object if necessary. But, unlike arrays, we do allow
1572  * short-header varlena objects to stay as-is.
1573  */
1574  if (typlen == -1)
1575  lower->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(lower->val));
1576 
1577  msize = datum_compute_size(msize, lower->val, typbyval, typalign,
1578  typlen, typstorage);
1579  }
1580 
1581  if (RANGE_HAS_UBOUND(flags))
1582  {
1583  /* Make sure item to be inserted is not toasted */
1584  if (typlen == -1)
1585  upper->val = PointerGetDatum(PG_DETOAST_DATUM_PACKED(upper->val));
1586 
1587  msize = datum_compute_size(msize, upper->val, typbyval, typalign,
1588  typlen, typstorage);
1589  }
1590 
1591  /* Add space for flag byte */
1592  msize += sizeof(char);
1593 
1594  /* Note: zero-fill is required here, just as in heap tuples */
1595  range = (RangeType *) palloc0(msize);
1596  SET_VARSIZE(range, msize);
1597 
1598  /* Now fill in the datum */
1599  range->rangetypid = typcache->type_id;
1600 
1601  ptr = (char *) (range + 1);
1602 
1603  if (RANGE_HAS_LBOUND(flags))
1604  {
1605  Assert(lower->lower);
1606  ptr = datum_write(ptr, lower->val, typbyval, typalign, typlen,
1607  typstorage);
1608  }
1609 
1610  if (RANGE_HAS_UBOUND(flags))
1611  {
1612  Assert(!upper->lower);
1613  ptr = datum_write(ptr, upper->val, typbyval, typalign, typlen,
1614  typstorage);
1615  }
1616 
1617  *((char *) ptr) = flags;
1618 
1619  return range;
1620 }
#define RANGE_HAS_UBOUND(flags)
Definition: rangetypes.h:50
signed short int16
Definition: c.h:252
#define RANGE_HAS_LBOUND(flags)
Definition: rangetypes.h:46
#define RANGE_EMPTY
Definition: rangetypes.h:36
#define PointerGetDatum(X)
Definition: postgres.h:564
Datum val
Definition: rangetypes.h:62
int errcode(int sqlerrcode)
Definition: elog.c:575
int16 typlen
Definition: typcache.h:35
#define RANGE_LB_INF
Definition: rangetypes.h:39
bool typbyval
Definition: typcache.h:36
Oid rangetypid
Definition: rangetypes.h:28
char * Pointer
Definition: c.h:242
bool inclusive
Definition: rangetypes.h:64
#define ERROR
Definition: elog.h:43
#define PG_DETOAST_DATUM_PACKED(datum)
Definition: fmgr.h:204
static Size datum_compute_size(Size sz, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2332
char typstorage
Definition: typcache.h:38
#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:84
void * palloc0(Size size)
Definition: mcxt.c:920
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, char typalign, int16 typlen, char typstorage)
Definition: rangetypes.c:2358
#define RANGE_LB_INC
Definition: rangetypes.h:37
int range_cmp_bound_values(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1842
#define Assert(condition)
Definition: c.h:671
size_t Size
Definition: c.h:353
bool infinite
Definition: rangetypes.h:63
#define MAXALIGN(LEN)
Definition: c.h:584
#define RANGE_UB_INF
Definition: rangetypes.h:40
char typalign
Definition: typcache.h:37
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:330
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 1713 of file rangetypes.c.

References RANGE_CONTAIN_EMPTY, and VARSIZE.

Referenced by range_super_union().

1714 {
1715  char *flagsp;
1716 
1717  /* flag byte is datum's last byte */
1718  flagsp = (char *) range + VARSIZE(range) - 1;
1719 
1720  *flagsp |= RANGE_CONTAIN_EMPTY;
1721 }
#define VARSIZE(PTR)
Definition: postgres.h:306
#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, PG_RETURN_RANGE, range_get_typcache(), range_union_internal(), and RangeTypeGetOid.

1070 {
1071  RangeType *r1 = PG_GETARG_RANGE(0);
1072  RangeType *r2 = PG_GETARG_RANGE(1);
1073  TypeCacheEntry *typcache;
1074 
1075  typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1));
1076 
1077  PG_RETURN_RANGE(range_union_internal(typcache, r1, r2, true));
1078 }
TypeCacheEntry * range_get_typcache(FunctionCallInfo fcinfo, Oid rngtypid)
Definition: rangetypes.c:1479
#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_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_RANGE(x)
Definition: rangetypes.h:76
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:1728
int range_cmp_bounds(TypeCacheEntry *typcache, RangeBound *b1, RangeBound *b2)
Definition: rangetypes.c:1768
#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:401
#define ereport(elevel, rest)
Definition: elog.h:122
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
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, PG_RETURN_DATUM, PG_RETURN_NULL, range_deserialize(), range_get_typcache(), RangeTypeGetOid, upper(), and RangeBound::val.

451 {
452  RangeType *r1 = PG_GETARG_RANGE(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:1479
#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
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
void range_deserialize(TypeCacheEntry *typcache, RangeType *range, RangeBound *lower, RangeBound *upper, bool *empty)
Definition: rangetypes.c:1632
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
bool infinite
Definition: rangetypes.h:63
#define PG_RETURN_NULL()
Definition: fmgr.h:289
Datum range_upper_inc ( PG_FUNCTION_ARGS  )

Definition at line 494 of file rangetypes.c.

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

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

Definition at line 514 of file rangetypes.c.

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

515 {
516  RangeType *r1 = PG_GETARG_RANGE(0);
517  char flags = range_get_flags(r1);
518 
519  PG_RETURN_BOOL(flags & RANGE_UB_INF);
520 }
#define PG_GETARG_RANGE(n)
Definition: rangetypes.h:74
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:303
#define RANGE_UB_INF
Definition: rangetypes.h:40
char range_get_flags(RangeType *range)
Definition: rangetypes.c:1699
Datum tsrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1440 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1441 {
1444  float8 result;
1445 
1446  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1447  PG_RETURN_FLOAT8(result);
1448 }
#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:310
double float8
Definition: c.h:378
int64 Timestamp
Definition: timestamp.h:38
Datum tstzrange_subdiff ( PG_FUNCTION_ARGS  )

Definition at line 1451 of file rangetypes.c.

References PG_GETARG_TIMESTAMP, PG_RETURN_FLOAT8, and USECS_PER_SEC.

1452 {
1455  float8 result;
1456 
1457  result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
1458  PG_RETURN_FLOAT8(result);
1459 }
#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:310
double float8
Definition: c.h:378
int64 Timestamp
Definition: timestamp.h:38