* pg_range.c
* routines to support manipulation of the pg_range relation
*
- * Copyright (c) 2006-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
#include "catalog/pg_proc.h"
#include "catalog/pg_range.h"
#include "catalog/pg_type.h"
-#include "utils/builtins.h"
#include "utils/fmgroids.h"
-#include "utils/tqual.h"
#include "utils/rel.h"
+#include "utils/tqual.h"
+
/*
* RangeCreate
pg_range = heap_open(RangeRelationId, RowExclusiveLock);
- memset(nulls, 0, Natts_pg_range * sizeof(bool));
+ memset(nulls, 0, sizeof(nulls));
values[Anum_pg_range_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff);
tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls);
+
simple_heap_insert(pg_range, tup);
CatalogUpdateIndexes(pg_range, tup);
heap_freetuple(tup);
- /* record dependencies */
+ /* record type's dependencies on range-related items */
myself.classId = TypeRelationId;
myself.objectId = rangeTypeOid;
/*
* RangeDelete
- * Remove the pg_range entry.
+ * Remove the pg_range entry for the specified type.
*/
void
RangeDelete(Oid rangeTypeOid)
/*-------------------------------------------------------------------------
*
* rangetypes.c
- * I/O functions, operators, and support functions for range types
+ * I/O functions, operators, and support functions for range types.
*
- * Copyright (c) 2006-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
#include "utils/timestamp.h"
#include "utils/typcache.h"
+
#define TYPE_IS_PACKABLE(typlen, typstorage) \
(typlen == -1 && typstorage != 'p')
#define RANGE_EMPTY_LITERAL "empty"
+#define RANGE_DEFAULT_FLAGS "[)"
+
+
+static char range_parse_flags(const char *flags_str);
static void range_parse(char *input_str, char *flags, char **lbound_str,
char **ubound_str);
static char *range_parse_bound(char *string, char *ptr, char **bound_str,
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval,
char typalign, int16 typlen, char typstorage);
+
/*
*----------------------------------------------------------
* I/O FUNCTIONS
char *input_str = PG_GETARG_CSTRING(0);
Oid rngtypoid = PG_GETARG_OID(1);
Oid typmod = PG_GETARG_INT32(2);
-
- char flags;
Datum range;
+ char flags;
char *lbound_str;
char *ubound_str;
-
regproc subInput;
FmgrInfo subInputFn;
Oid ioParam;
-
RangeTypeInfo rngtypinfo;
RangeBound lower;
RangeBound upper;
range_out(PG_FUNCTION_ARGS)
{
RangeType *range = PG_GETARG_RANGE(0);
-
+ char *output_str;
regproc subOutput;
FmgrInfo subOutputFn;
bool isVarlena;
-
char flags = 0;
char *lbound_str = NULL;
char *ubound_str = NULL;
- char *output_str;
-
bool empty;
-
RangeTypeInfo rngtypinfo;
RangeBound lower;
RangeBound upper;
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
Oid rngtypid = PG_GETARG_OID(1);
int32 typmod = PG_GETARG_INT32(2);
+ Datum range;
Oid subrecv;
Oid ioparam;
- Datum range;
char flags;
RangeBound lower;
RangeBound upper;
-
RangeTypeInfo rngtypinfo;
flags = (unsigned char) pq_getmsgbyte(buf);
/* serialize and canonicalize */
range = make_range(fcinfo, &lower, &upper, flags & RANGE_EMPTY);
- /*
- * XXX if the subtype is pass-by-val, we should pfree the upper and lower
- * bounds here.
- */
-
PG_RETURN_RANGE(range);
}
bool empty;
Oid subsend;
bool typIsVarlena;
-
RangeTypeInfo rngtypinfo;
pq_begintypsend(buf);
if (RANGE_HAS_LBOUND(flags))
{
- Datum bound = PointerGetDatum(
- OidSendFunctionCall(subsend, lower.val));
+ Datum bound = PointerGetDatum(OidSendFunctionCall(subsend,
+ lower.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound);
if (RANGE_HAS_UBOUND(flags))
{
- Datum bound = PointerGetDatum(
- OidSendFunctionCall(subsend, upper.val));
+ Datum bound = PointerGetDatum(OidSendFunctionCall(subsend,
+ upper.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound);
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
errmsg("flags argument must not be NULL")));
+
flags = range_parse_flags(text_to_cstring(PG_GETARG_TEXT_P(2)));
lower.rngtypid = rngtypid;
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
range_contains_elem(PG_FUNCTION_ARGS)
{
RangeType *r1 = PG_GETARG_RANGE(0);
- RangeType *r2;
Datum val = PG_GETARG_DATUM(1);
-
+ RangeType *r2;
RangeBound lower1,
lower2;
RangeBound upper1,
elem_contained_by_range(PG_FUNCTION_ARGS)
{
RangeType *r1 = PG_GETARG_RANGE(1);
- RangeType *r2;
Datum val = PG_GETARG_DATUM(0);
-
+ RangeType *r2;
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeTypeInfo rngtypinfo;
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
upper2;
bool empty1,
empty2;
-
int cmp_l1l2,
cmp_l1u2,
cmp_u1l2,
if (cmp_l1l2 < 0 && cmp_u1u2 > 0)
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
- errmsg("result range is not contiguous")));
+ errmsg("result of range difference would not be contiguous")));
if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
PG_RETURN_RANGE(r1);
PG_RETURN_RANGE(make_range(fcinfo, &upper2, &upper1, false));
}
- elog(ERROR, "unexpected error in range_minus");
- PG_RETURN_VOID();
+ elog(ERROR, "unexpected case in range_minus");
+ PG_RETURN_NULL();
}
Datum
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
!DatumGetBool(range_adjacent(fcinfo)))
ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION),
- errmsg("result range is not contiguous")));
+ errmsg("result of range union would not be contiguous")));
if (range_cmp_bounds(fcinfo, &lower1, &lower2) < 0)
result_lower = &lower1;
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
{
RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1);
-
RangeBound lower1,
lower2;
RangeBound upper1,
upper2;
bool empty1,
empty2;
-
int cmp;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
}
/* Hash support */
+
Datum
hash_range(PG_FUNCTION_ARGS)
{
uint32 lower_hash = 0;
uint32 upper_hash = 0;
uint32 result = 0;
-
RangeTypeInfo rngtypinfo;
-
TypeCacheEntry *typentry;
Oid subtype;
FunctionCallInfoData locfcinfo;
-
range_deserialize(fcinfo, r, &lower, &upper, &empty);
if (lower.rngtypid != upper.rngtypid)
int4range_canonical(PG_FUNCTION_ARGS)
{
RangeType *r = PG_GETARG_RANGE(0);
-
RangeBound lower;
RangeBound upper;
bool empty;
int8range_canonical(PG_FUNCTION_ARGS)
{
RangeType *r = PG_GETARG_RANGE(0);
-
RangeBound lower;
RangeBound upper;
bool empty;
daterange_canonical(PG_FUNCTION_ARGS)
{
RangeType *r = PG_GETARG_RANGE(0);
-
RangeBound lower;
RangeBound upper;
bool empty;
int32 v1 = PG_GETARG_INT32(0);
int32 v2 = PG_GETARG_INT32(1);
- PG_RETURN_FLOAT8((float8) (v1 - v2));
+ PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
}
Datum
int64 v1 = PG_GETARG_INT64(0);
int64 v2 = PG_GETARG_INT64(1);
- PG_RETURN_FLOAT8((float8) (v1 - v2));
-}
-
-Datum
-daterange_subdiff(PG_FUNCTION_ARGS)
-{
- int32 v1 = PG_GETARG_INT32(0);
- int32 v2 = PG_GETARG_INT32(1);
-
- PG_RETURN_FLOAT8((float8) (v1 - v2));
+ PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
}
Datum
numresult = DirectFunctionCall2(numeric_sub, v1, v2);
- floatresult = DatumGetFloat8(
- DirectFunctionCall1(numeric_float8, numresult));
+ floatresult = DatumGetFloat8(DirectFunctionCall1(numeric_float8,
+ numresult));
PG_RETURN_FLOAT8(floatresult);
}
+Datum
+daterange_subdiff(PG_FUNCTION_ARGS)
+{
+ int32 v1 = PG_GETARG_INT32(0);
+ int32 v2 = PG_GETARG_INT32(1);
+
+ PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
+}
+
Datum
tsrange_subdiff(PG_FUNCTION_ARGS)
{
float8 result;
#ifdef HAVE_INT64_TIMESTAMP
- result = ((float8) (v1 - v2)) / USECS_PER_SEC;
+ result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
#else
result = v1 - v2;
#endif
float8 result;
#ifdef HAVE_INT64_TIMESTAMP
- result = ((float8) (v1 - v2)) / USECS_PER_SEC;
+ result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
#else
result = v1 - v2;
#endif
*----------------------------------------------------------
* SUPPORT FUNCTIONS
*
- * These functions aren't in pg_proc, but are useful if
+ * These functions aren't in pg_proc, but are useful for
* defining new generic range functions in C.
*----------------------------------------------------------
*/
bool typbyval;
char typstorage;
char flags = 0;
-
RangeTypeInfo rngtypinfo;
if (lower->rngtypid != upper->rngtypid)
Datum lbound;
Datum ubound;
Pointer flags_ptr;
-
RangeTypeInfo rngtypinfo;
memset(lower, 0, sizeof(RangeBound));
}
/*
- * This both serializes and caonicalizes (if applicable) the
- * range. This should be used by most callers.
+ * This both serializes and canonicalizes (if applicable) the range.
+ * This should be used by most callers.
*/
Datum
make_range(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
bool empty)
{
Datum range;
-
RangeTypeInfo rngtypinfo;
range_gettypinfo(fcinfo, lower->rngtypid, &rngtypinfo);
range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2)
{
int result;
-
RangeTypeInfo rngtypinfo;
if (b1->infinite && b2->infinite)
return (b2->lower) ? 1 : -1;
range_gettypinfo(fcinfo, b1->rngtypid, &rngtypinfo);
+
result = DatumGetInt32(FunctionCall2Coll(&rngtypinfo.cmpFn,
rngtypinfo.collation,
b1->val, b2->val));
Form_pg_opclass pg_opclass;
Form_pg_type pg_type;
HeapTuple tup;
-
Oid subtypeOid;
Oid collationOid;
Oid canonicalOid;
cmpFnOid = get_opfamily_proc(opfamilyOid, opcintype, opcintype,
BTORDER_PROC);
-
- if (!OidIsValid(cmpFnOid))
- elog(ERROR, "unable to find compare function for operator class %d",
- opclassOid);
+ if (!RegProcedureIsValid(cmpFnOid))
+ elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
+ BTORDER_PROC, opcintype, opcintype, opfamilyOid);
/* get information from pg_type */
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(subtypeOid));
memcpy(rngtypinfo, cached, sizeof(RangeTypeInfo));
}
+/*
+ *----------------------------------------------------------
+ * STATIC FUNCTIONS
+ *----------------------------------------------------------
+ */
+
/*
* Given a string representing the flags for the range type, return the flags
* represented as a char.
- *
- * Exported so that it can be called by DefineRange to check the default flags.
*/
-char
-range_parse_flags(char *flags_str)
+static char
+range_parse_flags(const char *flags_str)
{
char flags = 0;
return flags;
}
-/*
- *----------------------------------------------------------
- * STATIC FUNCTIONS
- *----------------------------------------------------------
- */
-
/*
* Parse range input, modeled after record_in in rowtypes.c.
*
* rangetypes_gist.c
* GiST support for range types.
*
- * Copyright (c) 2006-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
#include "utils/lsyscache.h"
#include "utils/rangetypes.h"
+
+/* Operator strategy numbers used in the GiST range opclass */
#define RANGESTRAT_EQ 1
#define RANGESTRAT_NE 2
#define RANGESTRAT_OVERLAPS 3
#define RANGESTRAT_OVERRIGHT 11
#define RANGESTRAT_ADJACENT 12
-static RangeType *range_super_union(FunctionCallInfo fcinfo, RangeType * r1,
- RangeType * r2);
-static bool range_gist_consistent_int(FunctionCallInfo fcinfo,
- StrategyNumber strategy, RangeType * key,
- RangeType * query);
-static bool range_gist_consistent_leaf(FunctionCallInfo fcinfo,
- StrategyNumber strategy, RangeType * key,
- RangeType * query);
-static int sort_item_cmp(const void *a, const void *b);
-
/*
* Auxiliary structure for picksplit method.
*/
FunctionCallInfo fcinfo;
} PickSplitSortItem;
+static RangeType *range_super_union(FunctionCallInfo fcinfo, RangeType * r1,
+ RangeType * r2);
+static bool range_gist_consistent_int(FunctionCallInfo fcinfo,
+ StrategyNumber strategy, RangeType * key,
+ RangeType * query);
+static bool range_gist_consistent_leaf(FunctionCallInfo fcinfo,
+ StrategyNumber strategy, RangeType * key,
+ RangeType * query);
+static int sort_item_cmp(const void *a, const void *b);
+
Datum
range_gist_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Datum dquery = PG_GETARG_DATUM(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
-
/* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4);
RangeType *key = DatumGetRangeType(entry->key);
RangeType *query;
-
RangeBound lower;
RangeBound upper;
bool empty;
switch (strategy)
{
- RangeBound lower;
- RangeBound upper;
-
- /*
- * For contains and contained by operators, the other operand is a
- * "point" of the subtype. Construct a singleton range containing
- * just that value.
- */
+ /*
+ * For contains and contained by operators, the other operand is a
+ * "point" of the subtype. Construct a singleton range containing
+ * just that value.
+ */
case RANGESTRAT_CONTAINS_ELEM:
case RANGESTRAT_ELEM_CONTAINED_BY:
lower.rngtypid = rngtypid;
upper.val = dquery;
upper.lower = false;
upper.infinite = false;
- query = DatumGetRangeType(
- make_range(fcinfo, &lower, &upper, false));
+ query = DatumGetRangeType(make_range(fcinfo,
+ &lower, &upper, false));
break;
default:
}
if (GIST_LEAF(entry))
- PG_RETURN_BOOL(range_gist_consistent_leaf(
- fcinfo, strategy, key, query));
+ PG_RETURN_BOOL(range_gist_consistent_leaf(fcinfo, strategy,
+ key, query));
else
- PG_RETURN_BOOL(range_gist_consistent_int(
- fcinfo, strategy, key, query));
+ PG_RETURN_BOOL(range_gist_consistent_int(fcinfo, strategy,
+ key, query));
}
Datum
float *penalty = (float *) PG_GETARG_POINTER(2);
RangeType *orig = DatumGetRangeType(origentry->key);
RangeType *new = DatumGetRangeType(newentry->key);
- RangeType *s_union = range_super_union(fcinfo, orig, new);
-
+ RangeType *s_union;
FmgrInfo *subtype_diff;
-
RangeBound lower1,
lower2;
RangeBound upper1,
upper2;
bool empty1,
empty2;
-
float lower_diff,
upper_diff;
-
RangeTypeInfo rngtypinfo;
+ s_union = range_super_union(fcinfo, orig, new);
+
range_deserialize(fcinfo, orig, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, s_union, &lower2, &upper2, &empty2);
if (result_lower == &lower2 && result_upper == &upper2)
return r2;
- return DatumGetRangeType(
- make_range(fcinfo, result_lower, result_upper, false));
+ return DatumGetRangeType(make_range(fcinfo, result_lower, result_upper,
+ false));
}
static bool
range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
RangeType * key, RangeType * query)
{
- Oid proc = InvalidOid;
-
+ Oid proc;
RangeBound lower1,
lower2;
RangeBound upper1,
upper2;
bool empty1,
empty2;
-
bool retval;
bool negate = false;
case RANGESTRAT_ADJACENT:
if (empty1 || empty2)
return false;
- if (DatumGetBool(
- OidFunctionCall2(F_RANGE_ADJACENT,
+ if (DatumGetBool(OidFunctionCall2(F_RANGE_ADJACENT,
RangeTypeGetDatum(key),
RangeTypeGetDatum(query))))
return true;
proc = F_RANGE_OVERLAPS;
break;
+ default:
+ elog(ERROR, "unrecognized range strategy: %d", strategy);
+ proc = InvalidOid;
+ break;
}
retval = DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key),
range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy,
RangeType * key, RangeType * query)
{
- Oid proc = InvalidOid;
-
+ Oid proc;
RangeBound lower1,
lower2;
RangeBound upper1,
return false;
proc = F_RANGE_ADJACENT;
break;
+ default:
+ elog(ERROR, "unrecognized range strategy: %d", strategy);
+ proc = InvalidOid;
+ break;
}
return DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key),
PickSplitSortItem *i2 = (PickSplitSortItem *) b;
RangeType *r1 = i1->data;
RangeType *r2 = i2->data;
-
RangeBound lower1,
lower2;
RangeBound upper1,
upper2;
bool empty1,
empty2;
-
FunctionCallInfo fcinfo = i1->fcinfo;
-
int cmp;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
* along with the relation's initial contents.
*
*
- * Copyright (c) 2006-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/catalog/pg_range.h
*
#define Anum_pg_range_rngcanonical 5
#define Anum_pg_range_rngsubdiff 6
-#define RANGE_DEFAULT_FLAGS "[)"
-
-/*
- * prototypes for functions in pg_range.c
- */
-
-extern void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
- Oid rangeSubOpclass, RegProcedure rangeCanonical,
- RegProcedure rangeSubDiff);
-extern void RangeDelete(Oid rangeTypeOid);
/* ----------------
* initial contents of pg_range
DATA(insert ( 3912 1082 0 10019 daterange_canonical daterange_subdiff));
DATA(insert ( 3926 20 0 10029 int8range_canonical int8range_subdiff));
+
+/*
+ * prototypes for functions in pg_range.c
+ */
+
+extern void RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
+ Oid rangeSubOpclass, RegProcedure rangeCanonical,
+ RegProcedure rangeSubDiff);
+extern void RangeDelete(Oid rangeTypeOid);
+
#endif /* PG_RANGE_H */
* rangetypes.h
* Declarations for Postgres range types.
*
+ *
+ * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/utils/rangetypes.h
+ *
+ *-------------------------------------------------------------------------
*/
-
#ifndef RANGETYPES_H
#define RANGETYPES_H
#include "fmgr.h"
+
+/* All ranges are represented as varlena objects */
typedef struct varlena RangeType;
+/* Internal representation of either bound of a range (not what's on disk) */
typedef struct
{
- Datum val;
- Oid rngtypid;
- bool infinite;
- bool lower;
- bool inclusive;
+ Datum val; /* the bound value, if any */
+ Oid rngtypid; /* OID of the range type itself */
+ bool infinite; /* bound is +/- infinity */
+ bool lower; /* this is the lower (vs upper) bound */
+ bool inclusive; /* bound is inclusive (vs exclusive) */
} RangeBound;
+/* Standard runtime-cached data for a range type */
typedef struct
{
- FmgrInfo canonicalFn;
- FmgrInfo cmpFn;
- FmgrInfo subdiffFn;
- Oid rngtypid;
- Oid subtype;
- Oid collation;
- int16 subtyplen;
- char subtypalign;
- char subtypstorage;
- bool subtypbyval;
+ FmgrInfo canonicalFn; /* canonicalization function, if any */
+ FmgrInfo cmpFn; /* element type's btree comparison function */
+ FmgrInfo subdiffFn; /* element type difference function, if any */
+ Oid rngtypid; /* OID of the range type itself */
+ Oid subtype; /* OID of the element type */
+ Oid collation; /* collation for comparisons, if any */
+ int16 subtyplen; /* typlen of element type */
+ char subtypalign; /* typalign of element type */
+ char subtypstorage; /* typstorage of element type */
+ bool subtypbyval; /* typbyval of element type */
} RangeTypeInfo;
/*
* fmgr macros for range type objects
*/
-#define DatumGetRangeType(X) ((RangeType *) PG_DETOAST_DATUM(X))
-#define DatumGetRangeTypeCopy(X) ((RangeType *) PG_DETOAST_DATUM_COPY(X))
-#define RangeTypeGetDatum(X) PointerGetDatum(X)
-#define PG_GETARG_RANGE(n) DatumGetRangeType(PG_GETARG_DATUM(n))
-#define PG_GETARG_RANGE_COPY(n) DatumGetRangeTypeCopy(PG_GETARG_DATUM(n))
-#define PG_RETURN_RANGE(x) return RangeTypeGetDatum(x)
+#define DatumGetRangeType(X) ((RangeType *) PG_DETOAST_DATUM(X))
+#define DatumGetRangeTypeCopy(X) ((RangeType *) PG_DETOAST_DATUM_COPY(X))
+#define RangeTypeGetDatum(X) PointerGetDatum(X)
+#define PG_GETARG_RANGE(n) DatumGetRangeType(PG_GETARG_DATUM(n))
+#define PG_GETARG_RANGE_COPY(n) DatumGetRangeTypeCopy(PG_GETARG_DATUM(n))
+#define PG_RETURN_RANGE(x) return RangeTypeGetDatum(x)
/*
* prototypes for functions defined in rangetypes.c
extern Datum range_constructor1(PG_FUNCTION_ARGS);
extern Datum range_constructor2(PG_FUNCTION_ARGS);
extern Datum range_constructor3(PG_FUNCTION_ARGS);
-extern Datum range_make1(PG_FUNCTION_ARGS);
-extern Datum range_linf_(PG_FUNCTION_ARGS);
-extern Datum range_uinf_(PG_FUNCTION_ARGS);
-extern Datum range_linfi(PG_FUNCTION_ARGS);
-extern Datum range_uinfi(PG_FUNCTION_ARGS);
-extern Datum range(PG_FUNCTION_ARGS);
-extern Datum range__(PG_FUNCTION_ARGS);
-extern Datum range_i(PG_FUNCTION_ARGS);
-extern Datum rangei_(PG_FUNCTION_ARGS);
-extern Datum rangeii(PG_FUNCTION_ARGS);
/* range -> subtype */
extern Datum range_lower(PG_FUNCTION_ARGS);
extern Datum range_lower_inf(PG_FUNCTION_ARGS);
extern Datum range_upper_inf(PG_FUNCTION_ARGS);
-/* range, point -> bool */
+/* range, element -> bool */
extern Datum range_contains_elem(PG_FUNCTION_ARGS);
extern Datum elem_contained_by_range(PG_FUNCTION_ARGS);
/* Hash support */
extern Datum hash_range(PG_FUNCTION_ARGS);
-/* GiST support (rangetypes_gist.c) */
-extern Datum range_gist_consistent(PG_FUNCTION_ARGS);
-extern Datum range_gist_compress(PG_FUNCTION_ARGS);
-extern Datum range_gist_decompress(PG_FUNCTION_ARGS);
-extern Datum range_gist_union(PG_FUNCTION_ARGS);
-extern Datum range_gist_penalty(PG_FUNCTION_ARGS);
-extern Datum range_gist_picksplit(PG_FUNCTION_ARGS);
-extern Datum range_gist_same(PG_FUNCTION_ARGS);
-
/* Canonical functions */
-Datum int4range_canonical(PG_FUNCTION_ARGS);
-Datum int8range_canonical(PG_FUNCTION_ARGS);
-Datum daterange_canonical(PG_FUNCTION_ARGS);
+extern Datum int4range_canonical(PG_FUNCTION_ARGS);
+extern Datum int8range_canonical(PG_FUNCTION_ARGS);
+extern Datum daterange_canonical(PG_FUNCTION_ARGS);
/* Subtype Difference functions */
-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);
-
-/* for defining more generic functions */
-extern Datum make_range(FunctionCallInfo fcinfo, RangeBound *lower,
- RangeBound *upper, bool empty);
+extern Datum int4range_subdiff(PG_FUNCTION_ARGS);
+extern Datum int8range_subdiff(PG_FUNCTION_ARGS);
+extern Datum numrange_subdiff(PG_FUNCTION_ARGS);
+extern Datum daterange_subdiff(PG_FUNCTION_ARGS);
+extern Datum tsrange_subdiff(PG_FUNCTION_ARGS);
+extern Datum tstzrange_subdiff(PG_FUNCTION_ARGS);
+
+/* assorted support functions */
+extern Datum range_serialize(FunctionCallInfo fcinfo, RangeBound *lower,
+ RangeBound *upper, bool empty);
extern void range_deserialize(FunctionCallInfo fcinfo, RangeType *range,
RangeBound *lower, RangeBound *upper,
bool *empty);
+extern Datum make_range(FunctionCallInfo fcinfo, RangeBound *lower,
+ RangeBound *upper, bool empty);
extern int range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1,
RangeBound *b2);
extern RangeType *make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid);
extern void range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
RangeTypeInfo *rngtypinfo);
-/* for defining a range "canonicalize" function */
-extern Datum range_serialize(FunctionCallInfo fcinfo, RangeBound *lower,
- RangeBound *upper, bool empty);
-
-/* for use in DefineRange */
-extern char range_parse_flags(char *flags_str);
+/* GiST support (in rangetypes_gist.c) */
+extern Datum range_gist_consistent(PG_FUNCTION_ARGS);
+extern Datum range_gist_compress(PG_FUNCTION_ARGS);
+extern Datum range_gist_decompress(PG_FUNCTION_ARGS);
+extern Datum range_gist_union(PG_FUNCTION_ARGS);
+extern Datum range_gist_penalty(PG_FUNCTION_ARGS);
+extern Datum range_gist_picksplit(PG_FUNCTION_ARGS);
+extern Datum range_gist_same(PG_FUNCTION_ARGS);
#endif /* RANGETYPES_H */
(1 row)
select numrange(1.0, 2.0) + numrange(2.5, 3.0);
-ERROR: result range is not contiguous
+ERROR: result of range union would not be contiguous
select numrange(1.0, 2.0) * numrange(2.0, 3.0);
?column?
----------