Commit f1585362 authored by Tom Lane's avatar Tom Lane

Fix copyright notices, other minor editing in new range-types code.

No functional changes in this commit (except I could not resist the
temptation to re-word a couple of error messages).  This is just manual
cleanup after pgindent to make the code look reasonably like other PG
code, in preparation for more detailed code review to come.
parent 1a2586c1
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
* pg_range.c * pg_range.c
* routines to support manipulation of the pg_range relation * 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 * IDENTIFICATION
...@@ -22,10 +23,10 @@ ...@@ -22,10 +23,10 @@
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
#include "catalog/pg_range.h" #include "catalog/pg_range.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/tqual.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/tqual.h"
/* /*
* RangeCreate * RangeCreate
...@@ -45,7 +46,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ...@@ -45,7 +46,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
pg_range = heap_open(RangeRelationId, RowExclusiveLock); 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_rngtypid - 1] = ObjectIdGetDatum(rangeTypeOid);
values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType); values[Anum_pg_range_rngsubtype - 1] = ObjectIdGetDatum(rangeSubType);
...@@ -55,11 +56,12 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ...@@ -55,11 +56,12 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff); values[Anum_pg_range_rngsubdiff - 1] = ObjectIdGetDatum(rangeSubDiff);
tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls); tup = heap_form_tuple(RelationGetDescr(pg_range), values, nulls);
simple_heap_insert(pg_range, tup); simple_heap_insert(pg_range, tup);
CatalogUpdateIndexes(pg_range, tup); CatalogUpdateIndexes(pg_range, tup);
heap_freetuple(tup); heap_freetuple(tup);
/* record dependencies */ /* record type's dependencies on range-related items */
myself.classId = TypeRelationId; myself.classId = TypeRelationId;
myself.objectId = rangeTypeOid; myself.objectId = rangeTypeOid;
...@@ -105,7 +107,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, ...@@ -105,7 +107,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation,
/* /*
* RangeDelete * RangeDelete
* Remove the pg_range entry. * Remove the pg_range entry for the specified type.
*/ */
void void
RangeDelete(Oid rangeTypeOid) RangeDelete(Oid rangeTypeOid)
......
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* *
* rangetypes.c * 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 * IDENTIFICATION
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#include "utils/timestamp.h" #include "utils/timestamp.h"
#include "utils/typcache.h" #include "utils/typcache.h"
#define TYPE_IS_PACKABLE(typlen, typstorage) \ #define TYPE_IS_PACKABLE(typlen, typstorage) \
(typlen == -1 && typstorage != 'p') (typlen == -1 && typstorage != 'p')
...@@ -53,6 +55,10 @@ ...@@ -53,6 +55,10 @@
#define RANGE_EMPTY_LITERAL "empty" #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, static void range_parse(char *input_str, char *flags, char **lbound_str,
char **ubound_str); char **ubound_str);
static char *range_parse_bound(char *string, char *ptr, char **bound_str, static char *range_parse_bound(char *string, char *ptr, char **bound_str,
...@@ -66,6 +72,7 @@ static Size datum_compute_size(Size sz, Datum datum, bool typbyval, ...@@ -66,6 +72,7 @@ static Size datum_compute_size(Size sz, Datum datum, bool typbyval,
static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval, static Pointer datum_write(Pointer ptr, Datum datum, bool typbyval,
char typalign, int16 typlen, char typstorage); char typalign, int16 typlen, char typstorage);
/* /*
*---------------------------------------------------------- *----------------------------------------------------------
* I/O FUNCTIONS * I/O FUNCTIONS
...@@ -78,16 +85,13 @@ range_in(PG_FUNCTION_ARGS) ...@@ -78,16 +85,13 @@ range_in(PG_FUNCTION_ARGS)
char *input_str = PG_GETARG_CSTRING(0); char *input_str = PG_GETARG_CSTRING(0);
Oid rngtypoid = PG_GETARG_OID(1); Oid rngtypoid = PG_GETARG_OID(1);
Oid typmod = PG_GETARG_INT32(2); Oid typmod = PG_GETARG_INT32(2);
char flags;
Datum range; Datum range;
char flags;
char *lbound_str; char *lbound_str;
char *ubound_str; char *ubound_str;
regproc subInput; regproc subInput;
FmgrInfo subInputFn; FmgrInfo subInputFn;
Oid ioParam; Oid ioParam;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
...@@ -132,18 +136,14 @@ Datum ...@@ -132,18 +136,14 @@ Datum
range_out(PG_FUNCTION_ARGS) range_out(PG_FUNCTION_ARGS)
{ {
RangeType *range = PG_GETARG_RANGE(0); RangeType *range = PG_GETARG_RANGE(0);
char *output_str;
regproc subOutput; regproc subOutput;
FmgrInfo subOutputFn; FmgrInfo subOutputFn;
bool isVarlena; bool isVarlena;
char flags = 0; char flags = 0;
char *lbound_str = NULL; char *lbound_str = NULL;
char *ubound_str = NULL; char *ubound_str = NULL;
char *output_str;
bool empty; bool empty;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
...@@ -193,13 +193,12 @@ range_recv(PG_FUNCTION_ARGS) ...@@ -193,13 +193,12 @@ range_recv(PG_FUNCTION_ARGS)
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
Oid rngtypid = PG_GETARG_OID(1); Oid rngtypid = PG_GETARG_OID(1);
int32 typmod = PG_GETARG_INT32(2); int32 typmod = PG_GETARG_INT32(2);
Datum range;
Oid subrecv; Oid subrecv;
Oid ioparam; Oid ioparam;
Datum range;
char flags; char flags;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
flags = (unsigned char) pq_getmsgbyte(buf); flags = (unsigned char) pq_getmsgbyte(buf);
...@@ -258,11 +257,6 @@ range_recv(PG_FUNCTION_ARGS) ...@@ -258,11 +257,6 @@ range_recv(PG_FUNCTION_ARGS)
/* serialize and canonicalize */ /* serialize and canonicalize */
range = make_range(fcinfo, &lower, &upper, flags & RANGE_EMPTY); 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); PG_RETURN_RANGE(range);
} }
...@@ -277,7 +271,6 @@ range_send(PG_FUNCTION_ARGS) ...@@ -277,7 +271,6 @@ range_send(PG_FUNCTION_ARGS)
bool empty; bool empty;
Oid subsend; Oid subsend;
bool typIsVarlena; bool typIsVarlena;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
pq_begintypsend(buf); pq_begintypsend(buf);
...@@ -301,8 +294,8 @@ range_send(PG_FUNCTION_ARGS) ...@@ -301,8 +294,8 @@ range_send(PG_FUNCTION_ARGS)
if (RANGE_HAS_LBOUND(flags)) if (RANGE_HAS_LBOUND(flags))
{ {
Datum bound = PointerGetDatum( Datum bound = PointerGetDatum(OidSendFunctionCall(subsend,
OidSendFunctionCall(subsend, lower.val)); lower.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ; uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound); char *bound_data = VARDATA(bound);
...@@ -312,8 +305,8 @@ range_send(PG_FUNCTION_ARGS) ...@@ -312,8 +305,8 @@ range_send(PG_FUNCTION_ARGS)
if (RANGE_HAS_UBOUND(flags)) if (RANGE_HAS_UBOUND(flags))
{ {
Datum bound = PointerGetDatum( Datum bound = PointerGetDatum(OidSendFunctionCall(subsend,
OidSendFunctionCall(subsend, upper.val)); upper.val));
uint32 bound_len = VARSIZE(bound) - VARHDRSZ; uint32 bound_len = VARSIZE(bound) - VARHDRSZ;
char *bound_data = VARDATA(bound); char *bound_data = VARDATA(bound);
...@@ -432,6 +425,7 @@ range_constructor3(PG_FUNCTION_ARGS) ...@@ -432,6 +425,7 @@ range_constructor3(PG_FUNCTION_ARGS)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (errcode(ERRCODE_DATA_EXCEPTION),
errmsg("flags argument must not be NULL"))); errmsg("flags argument must not be NULL")));
flags = range_parse_flags(text_to_cstring(PG_GETARG_TEXT_P(2))); flags = range_parse_flags(text_to_cstring(PG_GETARG_TEXT_P(2)));
lower.rngtypid = rngtypid; lower.rngtypid = rngtypid;
...@@ -570,7 +564,6 @@ range_eq(PG_FUNCTION_ARGS) ...@@ -570,7 +564,6 @@ range_eq(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -612,9 +605,8 @@ Datum ...@@ -612,9 +605,8 @@ Datum
range_contains_elem(PG_FUNCTION_ARGS) range_contains_elem(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2;
Datum val = PG_GETARG_DATUM(1); Datum val = PG_GETARG_DATUM(1);
RangeType *r2;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -653,9 +645,8 @@ Datum ...@@ -653,9 +645,8 @@ Datum
elem_contained_by_range(PG_FUNCTION_ARGS) elem_contained_by_range(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(1); RangeType *r1 = PG_GETARG_RANGE(1);
RangeType *r2;
Datum val = PG_GETARG_DATUM(0); Datum val = PG_GETARG_DATUM(0);
RangeType *r2;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -695,7 +686,6 @@ range_before(PG_FUNCTION_ARGS) ...@@ -695,7 +686,6 @@ range_before(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -727,7 +717,6 @@ range_after(PG_FUNCTION_ARGS) ...@@ -727,7 +717,6 @@ range_after(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -759,9 +748,7 @@ range_adjacent(PG_FUNCTION_ARGS) ...@@ -759,9 +748,7 @@ range_adjacent(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -817,7 +804,6 @@ range_overlaps(PG_FUNCTION_ARGS) ...@@ -817,7 +804,6 @@ range_overlaps(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -852,7 +838,6 @@ range_overleft(PG_FUNCTION_ARGS) ...@@ -852,7 +838,6 @@ range_overleft(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -882,7 +867,6 @@ range_overright(PG_FUNCTION_ARGS) ...@@ -882,7 +867,6 @@ range_overright(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -914,14 +898,12 @@ range_minus(PG_FUNCTION_ARGS) ...@@ -914,14 +898,12 @@ range_minus(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
upper2; upper2;
bool empty1, bool empty1,
empty2; empty2;
int cmp_l1l2, int cmp_l1l2,
cmp_l1u2, cmp_l1u2,
cmp_u1l2, cmp_u1l2,
...@@ -946,7 +928,7 @@ range_minus(PG_FUNCTION_ARGS) ...@@ -946,7 +928,7 @@ range_minus(PG_FUNCTION_ARGS)
if (cmp_l1l2 < 0 && cmp_u1u2 > 0) if (cmp_l1l2 < 0 && cmp_u1u2 > 0)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (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) if (cmp_l1u2 > 0 || cmp_u1l2 < 0)
PG_RETURN_RANGE(r1); PG_RETURN_RANGE(r1);
...@@ -968,8 +950,8 @@ range_minus(PG_FUNCTION_ARGS) ...@@ -968,8 +950,8 @@ range_minus(PG_FUNCTION_ARGS)
PG_RETURN_RANGE(make_range(fcinfo, &upper2, &upper1, false)); PG_RETURN_RANGE(make_range(fcinfo, &upper2, &upper1, false));
} }
elog(ERROR, "unexpected error in range_minus"); elog(ERROR, "unexpected case in range_minus");
PG_RETURN_VOID(); PG_RETURN_NULL();
} }
Datum Datum
...@@ -977,7 +959,6 @@ range_union(PG_FUNCTION_ARGS) ...@@ -977,7 +959,6 @@ range_union(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -999,7 +980,7 @@ range_union(PG_FUNCTION_ARGS) ...@@ -999,7 +980,7 @@ range_union(PG_FUNCTION_ARGS)
!DatumGetBool(range_adjacent(fcinfo))) !DatumGetBool(range_adjacent(fcinfo)))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATA_EXCEPTION), (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) if (range_cmp_bounds(fcinfo, &lower1, &lower2) < 0)
result_lower = &lower1; result_lower = &lower1;
...@@ -1019,7 +1000,6 @@ range_intersect(PG_FUNCTION_ARGS) ...@@ -1019,7 +1000,6 @@ range_intersect(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -1055,14 +1035,12 @@ range_cmp(PG_FUNCTION_ARGS) ...@@ -1055,14 +1035,12 @@ range_cmp(PG_FUNCTION_ARGS)
{ {
RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r1 = PG_GETARG_RANGE(0);
RangeType *r2 = PG_GETARG_RANGE(1); RangeType *r2 = PG_GETARG_RANGE(1);
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
upper2; upper2;
bool empty1, bool empty1,
empty2; empty2;
int cmp; int cmp;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
...@@ -1119,6 +1097,7 @@ range_gt(PG_FUNCTION_ARGS) ...@@ -1119,6 +1097,7 @@ range_gt(PG_FUNCTION_ARGS)
} }
/* Hash support */ /* Hash support */
Datum Datum
hash_range(PG_FUNCTION_ARGS) hash_range(PG_FUNCTION_ARGS)
{ {
...@@ -1130,14 +1109,11 @@ hash_range(PG_FUNCTION_ARGS) ...@@ -1130,14 +1109,11 @@ hash_range(PG_FUNCTION_ARGS)
uint32 lower_hash = 0; uint32 lower_hash = 0;
uint32 upper_hash = 0; uint32 upper_hash = 0;
uint32 result = 0; uint32 result = 0;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
TypeCacheEntry *typentry; TypeCacheEntry *typentry;
Oid subtype; Oid subtype;
FunctionCallInfoData locfcinfo; FunctionCallInfoData locfcinfo;
range_deserialize(fcinfo, r, &lower, &upper, &empty); range_deserialize(fcinfo, r, &lower, &upper, &empty);
if (lower.rngtypid != upper.rngtypid) if (lower.rngtypid != upper.rngtypid)
...@@ -1214,7 +1190,6 @@ Datum ...@@ -1214,7 +1190,6 @@ Datum
int4range_canonical(PG_FUNCTION_ARGS) int4range_canonical(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
...@@ -1243,7 +1218,6 @@ Datum ...@@ -1243,7 +1218,6 @@ Datum
int8range_canonical(PG_FUNCTION_ARGS) int8range_canonical(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
...@@ -1272,7 +1246,6 @@ Datum ...@@ -1272,7 +1246,6 @@ Datum
daterange_canonical(PG_FUNCTION_ARGS) daterange_canonical(PG_FUNCTION_ARGS)
{ {
RangeType *r = PG_GETARG_RANGE(0); RangeType *r = PG_GETARG_RANGE(0);
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
...@@ -1311,7 +1284,7 @@ int4range_subdiff(PG_FUNCTION_ARGS) ...@@ -1311,7 +1284,7 @@ int4range_subdiff(PG_FUNCTION_ARGS)
int32 v1 = PG_GETARG_INT32(0); int32 v1 = PG_GETARG_INT32(0);
int32 v2 = PG_GETARG_INT32(1); int32 v2 = PG_GETARG_INT32(1);
PG_RETURN_FLOAT8((float8) (v1 - v2)); PG_RETURN_FLOAT8((float8) v1 - (float8) v2);
} }
Datum Datum
...@@ -1320,16 +1293,7 @@ int8range_subdiff(PG_FUNCTION_ARGS) ...@@ -1320,16 +1293,7 @@ int8range_subdiff(PG_FUNCTION_ARGS)
int64 v1 = PG_GETARG_INT64(0); int64 v1 = PG_GETARG_INT64(0);
int64 v2 = PG_GETARG_INT64(1); int64 v2 = PG_GETARG_INT64(1);
PG_RETURN_FLOAT8((float8) (v1 - v2)); PG_RETURN_FLOAT8((float8) v1 - (float8) 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));
} }
Datum Datum
...@@ -1342,12 +1306,21 @@ numrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1342,12 +1306,21 @@ numrange_subdiff(PG_FUNCTION_ARGS)
numresult = DirectFunctionCall2(numeric_sub, v1, v2); numresult = DirectFunctionCall2(numeric_sub, v1, v2);
floatresult = DatumGetFloat8( floatresult = DatumGetFloat8(DirectFunctionCall1(numeric_float8,
DirectFunctionCall1(numeric_float8, numresult)); numresult));
PG_RETURN_FLOAT8(floatresult); 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 Datum
tsrange_subdiff(PG_FUNCTION_ARGS) tsrange_subdiff(PG_FUNCTION_ARGS)
{ {
...@@ -1356,7 +1329,7 @@ tsrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1356,7 +1329,7 @@ tsrange_subdiff(PG_FUNCTION_ARGS)
float8 result; float8 result;
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
result = ((float8) (v1 - v2)) / USECS_PER_SEC; result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
#else #else
result = v1 - v2; result = v1 - v2;
#endif #endif
...@@ -1372,7 +1345,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1372,7 +1345,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS)
float8 result; float8 result;
#ifdef HAVE_INT64_TIMESTAMP #ifdef HAVE_INT64_TIMESTAMP
result = ((float8) (v1 - v2)) / USECS_PER_SEC; result = ((float8) v1 - (float8) v2) / USECS_PER_SEC;
#else #else
result = v1 - v2; result = v1 - v2;
#endif #endif
...@@ -1384,7 +1357,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS) ...@@ -1384,7 +1357,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS)
*---------------------------------------------------------- *----------------------------------------------------------
* SUPPORT FUNCTIONS * 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. * defining new generic range functions in C.
*---------------------------------------------------------- *----------------------------------------------------------
*/ */
...@@ -1425,7 +1398,6 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, ...@@ -1425,7 +1398,6 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
bool typbyval; bool typbyval;
char typstorage; char typstorage;
char flags = 0; char flags = 0;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
if (lower->rngtypid != upper->rngtypid) if (lower->rngtypid != upper->rngtypid)
...@@ -1509,7 +1481,6 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, ...@@ -1509,7 +1481,6 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower,
Datum lbound; Datum lbound;
Datum ubound; Datum ubound;
Pointer flags_ptr; Pointer flags_ptr;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
memset(lower, 0, sizeof(RangeBound)); memset(lower, 0, sizeof(RangeBound));
...@@ -1571,15 +1542,14 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, ...@@ -1571,15 +1542,14 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower,
} }
/* /*
* This both serializes and caonicalizes (if applicable) the * This both serializes and canonicalizes (if applicable) the range.
* range. This should be used by most callers. * This should be used by most callers.
*/ */
Datum Datum
make_range(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, make_range(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper,
bool empty) bool empty)
{ {
Datum range; Datum range;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
range_gettypinfo(fcinfo, lower->rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, lower->rngtypid, &rngtypinfo);
...@@ -1599,7 +1569,6 @@ int ...@@ -1599,7 +1569,6 @@ int
range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2) range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2)
{ {
int result; int result;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
if (b1->infinite && b2->infinite) if (b1->infinite && b2->infinite)
...@@ -1615,6 +1584,7 @@ range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2) ...@@ -1615,6 +1584,7 @@ range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2)
return (b2->lower) ? 1 : -1; return (b2->lower) ? 1 : -1;
range_gettypinfo(fcinfo, b1->rngtypid, &rngtypinfo); range_gettypinfo(fcinfo, b1->rngtypid, &rngtypinfo);
result = DatumGetInt32(FunctionCall2Coll(&rngtypinfo.cmpFn, result = DatumGetInt32(FunctionCall2Coll(&rngtypinfo.cmpFn,
rngtypinfo.collation, rngtypinfo.collation,
b1->val, b2->val)); b1->val, b2->val));
...@@ -1670,7 +1640,6 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1670,7 +1640,6 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
Form_pg_opclass pg_opclass; Form_pg_opclass pg_opclass;
Form_pg_type pg_type; Form_pg_type pg_type;
HeapTuple tup; HeapTuple tup;
Oid subtypeOid; Oid subtypeOid;
Oid collationOid; Oid collationOid;
Oid canonicalOid; Oid canonicalOid;
...@@ -1716,10 +1685,9 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1716,10 +1685,9 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
cmpFnOid = get_opfamily_proc(opfamilyOid, opcintype, opcintype, cmpFnOid = get_opfamily_proc(opfamilyOid, opcintype, opcintype,
BTORDER_PROC); BTORDER_PROC);
if (!RegProcedureIsValid(cmpFnOid))
if (!OidIsValid(cmpFnOid)) elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
elog(ERROR, "unable to find compare function for operator class %d", BTORDER_PROC, opcintype, opcintype, opfamilyOid);
opclassOid);
/* get information from pg_type */ /* get information from pg_type */
tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(subtypeOid)); tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(subtypeOid));
...@@ -1760,14 +1728,18 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, ...@@ -1760,14 +1728,18 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
memcpy(rngtypinfo, cached, sizeof(RangeTypeInfo)); memcpy(rngtypinfo, cached, sizeof(RangeTypeInfo));
} }
/*
*----------------------------------------------------------
* STATIC FUNCTIONS
*----------------------------------------------------------
*/
/* /*
* Given a string representing the flags for the range type, return the flags * Given a string representing the flags for the range type, return the flags
* represented as a char. * represented as a char.
*
* Exported so that it can be called by DefineRange to check the default flags.
*/ */
char static char
range_parse_flags(char *flags_str) range_parse_flags(const char *flags_str)
{ {
char flags = 0; char flags = 0;
...@@ -1810,12 +1782,6 @@ range_parse_flags(char *flags_str) ...@@ -1810,12 +1782,6 @@ range_parse_flags(char *flags_str)
return flags; return flags;
} }
/*
*----------------------------------------------------------
* STATIC FUNCTIONS
*----------------------------------------------------------
*/
/* /*
* Parse range input, modeled after record_in in rowtypes.c. * Parse range input, modeled after record_in in rowtypes.c.
* *
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
* rangetypes_gist.c * rangetypes_gist.c
* GiST support for range types. * 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 * IDENTIFICATION
...@@ -20,6 +21,8 @@ ...@@ -20,6 +21,8 @@
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/rangetypes.h" #include "utils/rangetypes.h"
/* Operator strategy numbers used in the GiST range opclass */
#define RANGESTRAT_EQ 1 #define RANGESTRAT_EQ 1
#define RANGESTRAT_NE 2 #define RANGESTRAT_NE 2
#define RANGESTRAT_OVERLAPS 3 #define RANGESTRAT_OVERLAPS 3
...@@ -33,16 +36,6 @@ ...@@ -33,16 +36,6 @@
#define RANGESTRAT_OVERRIGHT 11 #define RANGESTRAT_OVERRIGHT 11
#define RANGESTRAT_ADJACENT 12 #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. * Auxiliary structure for picksplit method.
*/ */
...@@ -53,6 +46,16 @@ typedef struct ...@@ -53,6 +46,16 @@ typedef struct
FunctionCallInfo fcinfo; FunctionCallInfo fcinfo;
} PickSplitSortItem; } 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 Datum
range_gist_consistent(PG_FUNCTION_ARGS) range_gist_consistent(PG_FUNCTION_ARGS)
...@@ -60,12 +63,10 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -60,12 +63,10 @@ range_gist_consistent(PG_FUNCTION_ARGS)
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Datum dquery = PG_GETARG_DATUM(1); Datum dquery = PG_GETARG_DATUM(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
/* Oid subtype = PG_GETARG_OID(3); */ /* Oid subtype = PG_GETARG_OID(3); */
bool *recheck = (bool *) PG_GETARG_POINTER(4); bool *recheck = (bool *) PG_GETARG_POINTER(4);
RangeType *key = DatumGetRangeType(entry->key); RangeType *key = DatumGetRangeType(entry->key);
RangeType *query; RangeType *query;
RangeBound lower; RangeBound lower;
RangeBound upper; RangeBound upper;
bool empty; bool empty;
...@@ -77,9 +78,6 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -77,9 +78,6 @@ range_gist_consistent(PG_FUNCTION_ARGS)
switch (strategy) switch (strategy)
{ {
RangeBound lower;
RangeBound upper;
/* /*
* For contains and contained by operators, the other operand is a * For contains and contained by operators, the other operand is a
* "point" of the subtype. Construct a singleton range containing * "point" of the subtype. Construct a singleton range containing
...@@ -97,8 +95,8 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -97,8 +95,8 @@ range_gist_consistent(PG_FUNCTION_ARGS)
upper.val = dquery; upper.val = dquery;
upper.lower = false; upper.lower = false;
upper.infinite = false; upper.infinite = false;
query = DatumGetRangeType( query = DatumGetRangeType(make_range(fcinfo,
make_range(fcinfo, &lower, &upper, false)); &lower, &upper, false));
break; break;
default: default:
...@@ -107,11 +105,11 @@ range_gist_consistent(PG_FUNCTION_ARGS) ...@@ -107,11 +105,11 @@ range_gist_consistent(PG_FUNCTION_ARGS)
} }
if (GIST_LEAF(entry)) if (GIST_LEAF(entry))
PG_RETURN_BOOL(range_gist_consistent_leaf( PG_RETURN_BOOL(range_gist_consistent_leaf(fcinfo, strategy,
fcinfo, strategy, key, query)); key, query));
else else
PG_RETURN_BOOL(range_gist_consistent_int( PG_RETURN_BOOL(range_gist_consistent_int(fcinfo, strategy,
fcinfo, strategy, key, query)); key, query));
} }
Datum Datum
...@@ -157,22 +155,20 @@ range_gist_penalty(PG_FUNCTION_ARGS) ...@@ -157,22 +155,20 @@ range_gist_penalty(PG_FUNCTION_ARGS)
float *penalty = (float *) PG_GETARG_POINTER(2); float *penalty = (float *) PG_GETARG_POINTER(2);
RangeType *orig = DatumGetRangeType(origentry->key); RangeType *orig = DatumGetRangeType(origentry->key);
RangeType *new = DatumGetRangeType(newentry->key); RangeType *new = DatumGetRangeType(newentry->key);
RangeType *s_union = range_super_union(fcinfo, orig, new); RangeType *s_union;
FmgrInfo *subtype_diff; FmgrInfo *subtype_diff;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
upper2; upper2;
bool empty1, bool empty1,
empty2; empty2;
float lower_diff, float lower_diff,
upper_diff; upper_diff;
RangeTypeInfo rngtypinfo; RangeTypeInfo rngtypinfo;
s_union = range_super_union(fcinfo, orig, new);
range_deserialize(fcinfo, orig, &lower1, &upper1, &empty1); range_deserialize(fcinfo, orig, &lower1, &upper1, &empty1);
range_deserialize(fcinfo, s_union, &lower2, &upper2, &empty2); range_deserialize(fcinfo, s_union, &lower2, &upper2, &empty2);
...@@ -371,23 +367,21 @@ range_super_union(FunctionCallInfo fcinfo, RangeType * r1, RangeType * r2) ...@@ -371,23 +367,21 @@ range_super_union(FunctionCallInfo fcinfo, RangeType * r1, RangeType * r2)
if (result_lower == &lower2 && result_upper == &upper2) if (result_lower == &lower2 && result_upper == &upper2)
return r2; return r2;
return DatumGetRangeType( return DatumGetRangeType(make_range(fcinfo, result_lower, result_upper,
make_range(fcinfo, result_lower, result_upper, false)); false));
} }
static bool static bool
range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
RangeType * key, RangeType * query) RangeType * key, RangeType * query)
{ {
Oid proc = InvalidOid; Oid proc;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
upper2; upper2;
bool empty1, bool empty1,
empty2; empty2;
bool retval; bool retval;
bool negate = false; bool negate = false;
...@@ -440,13 +434,16 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -440,13 +434,16 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy,
case RANGESTRAT_ADJACENT: case RANGESTRAT_ADJACENT:
if (empty1 || empty2) if (empty1 || empty2)
return false; return false;
if (DatumGetBool( if (DatumGetBool(OidFunctionCall2(F_RANGE_ADJACENT,
OidFunctionCall2(F_RANGE_ADJACENT,
RangeTypeGetDatum(key), RangeTypeGetDatum(key),
RangeTypeGetDatum(query)))) RangeTypeGetDatum(query))))
return true; return true;
proc = F_RANGE_OVERLAPS; proc = F_RANGE_OVERLAPS;
break; break;
default:
elog(ERROR, "unrecognized range strategy: %d", strategy);
proc = InvalidOid;
break;
} }
retval = DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key), retval = DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key),
...@@ -462,8 +459,7 @@ static bool ...@@ -462,8 +459,7 @@ static bool
range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy, range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy,
RangeType * key, RangeType * query) RangeType * key, RangeType * query)
{ {
Oid proc = InvalidOid; Oid proc;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
...@@ -518,6 +514,10 @@ range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy, ...@@ -518,6 +514,10 @@ range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy,
return false; return false;
proc = F_RANGE_ADJACENT; proc = F_RANGE_ADJACENT;
break; break;
default:
elog(ERROR, "unrecognized range strategy: %d", strategy);
proc = InvalidOid;
break;
} }
return DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key), return DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key),
...@@ -545,16 +545,13 @@ sort_item_cmp(const void *a, const void *b) ...@@ -545,16 +545,13 @@ sort_item_cmp(const void *a, const void *b)
PickSplitSortItem *i2 = (PickSplitSortItem *) b; PickSplitSortItem *i2 = (PickSplitSortItem *) b;
RangeType *r1 = i1->data; RangeType *r1 = i1->data;
RangeType *r2 = i2->data; RangeType *r2 = i2->data;
RangeBound lower1, RangeBound lower1,
lower2; lower2;
RangeBound upper1, RangeBound upper1,
upper2; upper2;
bool empty1, bool empty1,
empty2; empty2;
FunctionCallInfo fcinfo = i1->fcinfo; FunctionCallInfo fcinfo = i1->fcinfo;
int cmp; int cmp;
range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1); range_deserialize(fcinfo, r1, &lower1, &upper1, &empty1);
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
* along with the relation's initial contents. * 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 * src/include/catalog/pg_range.h
* *
...@@ -59,16 +60,6 @@ typedef FormData_pg_range *Form_pg_range; ...@@ -59,16 +60,6 @@ typedef FormData_pg_range *Form_pg_range;
#define Anum_pg_range_rngcanonical 5 #define Anum_pg_range_rngcanonical 5
#define Anum_pg_range_rngsubdiff 6 #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 * initial contents of pg_range
...@@ -81,4 +72,14 @@ DATA(insert ( 3910 1184 0 10047 - tstzrange_subdiff)); ...@@ -81,4 +72,14 @@ DATA(insert ( 3910 1184 0 10047 - tstzrange_subdiff));
DATA(insert ( 3912 1082 0 10019 daterange_canonical daterange_subdiff)); DATA(insert ( 3912 1082 0 10019 daterange_canonical daterange_subdiff));
DATA(insert ( 3926 20 0 10029 int8range_canonical int8range_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 */ #endif /* PG_RANGE_H */
...@@ -3,36 +3,46 @@ ...@@ -3,36 +3,46 @@
* rangetypes.h * rangetypes.h
* Declarations for Postgres range types. * 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 #ifndef RANGETYPES_H
#define RANGETYPES_H #define RANGETYPES_H
#include "fmgr.h" #include "fmgr.h"
/* All ranges are represented as varlena objects */
typedef struct varlena RangeType; typedef struct varlena RangeType;
/* Internal representation of either bound of a range (not what's on disk) */
typedef struct typedef struct
{ {
Datum val; Datum val; /* the bound value, if any */
Oid rngtypid; Oid rngtypid; /* OID of the range type itself */
bool infinite; bool infinite; /* bound is +/- infinity */
bool lower; bool lower; /* this is the lower (vs upper) bound */
bool inclusive; bool inclusive; /* bound is inclusive (vs exclusive) */
} RangeBound; } RangeBound;
/* Standard runtime-cached data for a range type */
typedef struct typedef struct
{ {
FmgrInfo canonicalFn; FmgrInfo canonicalFn; /* canonicalization function, if any */
FmgrInfo cmpFn; FmgrInfo cmpFn; /* element type's btree comparison function */
FmgrInfo subdiffFn; FmgrInfo subdiffFn; /* element type difference function, if any */
Oid rngtypid; Oid rngtypid; /* OID of the range type itself */
Oid subtype; Oid subtype; /* OID of the element type */
Oid collation; Oid collation; /* collation for comparisons, if any */
int16 subtyplen; int16 subtyplen; /* typlen of element type */
char subtypalign; char subtypalign; /* typalign of element type */
char subtypstorage; char subtypstorage; /* typstorage of element type */
bool subtypbyval; bool subtypbyval; /* typbyval of element type */
} RangeTypeInfo; } RangeTypeInfo;
/* /*
...@@ -62,16 +72,6 @@ extern Datum range_constructor0(PG_FUNCTION_ARGS); ...@@ -62,16 +72,6 @@ extern Datum range_constructor0(PG_FUNCTION_ARGS);
extern Datum range_constructor1(PG_FUNCTION_ARGS); extern Datum range_constructor1(PG_FUNCTION_ARGS);
extern Datum range_constructor2(PG_FUNCTION_ARGS); extern Datum range_constructor2(PG_FUNCTION_ARGS);
extern Datum range_constructor3(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 */ /* range -> subtype */
extern Datum range_lower(PG_FUNCTION_ARGS); extern Datum range_lower(PG_FUNCTION_ARGS);
...@@ -84,7 +84,7 @@ extern Datum range_upper_inc(PG_FUNCTION_ARGS); ...@@ -84,7 +84,7 @@ extern Datum range_upper_inc(PG_FUNCTION_ARGS);
extern Datum range_lower_inf(PG_FUNCTION_ARGS); extern Datum range_lower_inf(PG_FUNCTION_ARGS);
extern Datum range_upper_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 range_contains_elem(PG_FUNCTION_ARGS);
extern Datum elem_contained_by_range(PG_FUNCTION_ARGS); extern Datum elem_contained_by_range(PG_FUNCTION_ARGS);
...@@ -115,45 +115,40 @@ extern Datum range_gt(PG_FUNCTION_ARGS); ...@@ -115,45 +115,40 @@ extern Datum range_gt(PG_FUNCTION_ARGS);
/* Hash support */ /* Hash support */
extern Datum hash_range(PG_FUNCTION_ARGS); 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 */ /* Canonical functions */
Datum int4range_canonical(PG_FUNCTION_ARGS); extern Datum int4range_canonical(PG_FUNCTION_ARGS);
Datum int8range_canonical(PG_FUNCTION_ARGS); extern Datum int8range_canonical(PG_FUNCTION_ARGS);
Datum daterange_canonical(PG_FUNCTION_ARGS); extern Datum daterange_canonical(PG_FUNCTION_ARGS);
/* Subtype Difference functions */ /* Subtype Difference functions */
Datum int4range_subdiff(PG_FUNCTION_ARGS); extern Datum int4range_subdiff(PG_FUNCTION_ARGS);
Datum int8range_subdiff(PG_FUNCTION_ARGS); extern Datum int8range_subdiff(PG_FUNCTION_ARGS);
Datum numrange_subdiff(PG_FUNCTION_ARGS); extern Datum numrange_subdiff(PG_FUNCTION_ARGS);
Datum daterange_subdiff(PG_FUNCTION_ARGS); extern Datum daterange_subdiff(PG_FUNCTION_ARGS);
Datum tsrange_subdiff(PG_FUNCTION_ARGS); extern Datum tsrange_subdiff(PG_FUNCTION_ARGS);
Datum tstzrange_subdiff(PG_FUNCTION_ARGS); extern Datum tstzrange_subdiff(PG_FUNCTION_ARGS);
/* for defining more generic functions */ /* assorted support functions */
extern Datum make_range(FunctionCallInfo fcinfo, RangeBound *lower, extern Datum range_serialize(FunctionCallInfo fcinfo, RangeBound *lower,
RangeBound *upper, bool empty); RangeBound *upper, bool empty);
extern void range_deserialize(FunctionCallInfo fcinfo, RangeType *range, extern void range_deserialize(FunctionCallInfo fcinfo, RangeType *range,
RangeBound *lower, RangeBound *upper, RangeBound *lower, RangeBound *upper,
bool *empty); bool *empty);
extern Datum make_range(FunctionCallInfo fcinfo, RangeBound *lower,
RangeBound *upper, bool empty);
extern int range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, extern int range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1,
RangeBound *b2); RangeBound *b2);
extern RangeType *make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid); extern RangeType *make_empty_range(FunctionCallInfo fcinfo, Oid rngtypid);
extern void range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, extern void range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid,
RangeTypeInfo *rngtypinfo); RangeTypeInfo *rngtypinfo);
/* for defining a range "canonicalize" function */ /* GiST support (in rangetypes_gist.c) */
extern Datum range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, extern Datum range_gist_consistent(PG_FUNCTION_ARGS);
RangeBound *upper, bool empty); extern Datum range_gist_compress(PG_FUNCTION_ARGS);
extern Datum range_gist_decompress(PG_FUNCTION_ARGS);
/* for use in DefineRange */ extern Datum range_gist_union(PG_FUNCTION_ARGS);
extern char range_parse_flags(char *flags_str); 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 */ #endif /* RANGETYPES_H */
...@@ -345,7 +345,7 @@ select numrange(1.0, 2.0) + numrange(1.5, 3.0); ...@@ -345,7 +345,7 @@ select numrange(1.0, 2.0) + numrange(1.5, 3.0);
(1 row) (1 row)
select numrange(1.0, 2.0) + numrange(2.5, 3.0); 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); select numrange(1.0, 2.0) * numrange(2.0, 3.0);
?column? ?column?
---------- ----------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment