From f1585362856d4da17113ba2e4ba46cf83cba0cf2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 14 Nov 2011 13:59:34 -0500 Subject: [PATCH] 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. --- src/backend/catalog/pg_range.c | 14 ++- src/backend/utils/adt/rangetypes.c | 142 +++++++++-------------- src/backend/utils/adt/rangetypes_gist.c | 85 +++++++------- src/include/catalog/pg_range.h | 23 ++-- src/include/utils/rangetypes.h | 117 +++++++++---------- src/test/regress/expected/rangetypes.out | 2 +- 6 files changed, 172 insertions(+), 211 deletions(-) diff --git a/src/backend/catalog/pg_range.c b/src/backend/catalog/pg_range.c index 07bfe4ab27..dbd06be45b 100644 --- a/src/backend/catalog/pg_range.c +++ b/src/backend/catalog/pg_range.c @@ -3,7 +3,8 @@ * 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 @@ -22,10 +23,10 @@ #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 @@ -45,7 +46,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, 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); @@ -55,11 +56,12 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, 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; @@ -105,7 +107,7 @@ RangeCreate(Oid rangeTypeOid, Oid rangeSubType, Oid rangeCollation, /* * RangeDelete - * Remove the pg_range entry. + * Remove the pg_range entry for the specified type. */ void RangeDelete(Oid rangeTypeOid) diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c index ff2691af45..f773c31813 100644 --- a/src/backend/utils/adt/rangetypes.c +++ b/src/backend/utils/adt/rangetypes.c @@ -1,9 +1,10 @@ /*------------------------------------------------------------------------- * * 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 @@ -31,6 +32,7 @@ #include "utils/timestamp.h" #include "utils/typcache.h" + #define TYPE_IS_PACKABLE(typlen, typstorage) \ (typlen == -1 && typstorage != 'p') @@ -53,6 +55,10 @@ #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, @@ -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, char typalign, int16 typlen, char typstorage); + /* *---------------------------------------------------------- * I/O FUNCTIONS @@ -78,16 +85,13 @@ range_in(PG_FUNCTION_ARGS) 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; @@ -132,18 +136,14 @@ Datum 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; @@ -193,13 +193,12 @@ range_recv(PG_FUNCTION_ARGS) 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); @@ -258,11 +257,6 @@ range_recv(PG_FUNCTION_ARGS) /* 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); } @@ -277,7 +271,6 @@ range_send(PG_FUNCTION_ARGS) bool empty; Oid subsend; bool typIsVarlena; - RangeTypeInfo rngtypinfo; pq_begintypsend(buf); @@ -301,8 +294,8 @@ range_send(PG_FUNCTION_ARGS) 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); @@ -312,8 +305,8 @@ range_send(PG_FUNCTION_ARGS) 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); @@ -432,6 +425,7 @@ range_constructor3(PG_FUNCTION_ARGS) 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; @@ -570,7 +564,6 @@ range_eq(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -612,9 +605,8 @@ Datum 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, @@ -653,9 +645,8 @@ Datum 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, @@ -695,7 +686,6 @@ range_before(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -727,7 +717,6 @@ range_after(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -759,9 +748,7 @@ range_adjacent(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeTypeInfo rngtypinfo; - RangeBound lower1, lower2; RangeBound upper1, @@ -817,7 +804,6 @@ range_overlaps(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -852,7 +838,6 @@ range_overleft(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -882,7 +867,6 @@ range_overright(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -914,14 +898,12 @@ range_minus(PG_FUNCTION_ARGS) { 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, @@ -946,7 +928,7 @@ range_minus(PG_FUNCTION_ARGS) 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); @@ -968,8 +950,8 @@ range_minus(PG_FUNCTION_ARGS) 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 @@ -977,7 +959,6 @@ range_union(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -999,7 +980,7 @@ range_union(PG_FUNCTION_ARGS) !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; @@ -1019,7 +1000,6 @@ range_intersect(PG_FUNCTION_ARGS) { RangeType *r1 = PG_GETARG_RANGE(0); RangeType *r2 = PG_GETARG_RANGE(1); - RangeBound lower1, lower2; RangeBound upper1, @@ -1055,14 +1035,12 @@ range_cmp(PG_FUNCTION_ARGS) { 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); @@ -1119,6 +1097,7 @@ range_gt(PG_FUNCTION_ARGS) } /* Hash support */ + Datum hash_range(PG_FUNCTION_ARGS) { @@ -1130,14 +1109,11 @@ 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) @@ -1214,7 +1190,6 @@ Datum int4range_canonical(PG_FUNCTION_ARGS) { RangeType *r = PG_GETARG_RANGE(0); - RangeBound lower; RangeBound upper; bool empty; @@ -1243,7 +1218,6 @@ Datum int8range_canonical(PG_FUNCTION_ARGS) { RangeType *r = PG_GETARG_RANGE(0); - RangeBound lower; RangeBound upper; bool empty; @@ -1272,7 +1246,6 @@ Datum daterange_canonical(PG_FUNCTION_ARGS) { RangeType *r = PG_GETARG_RANGE(0); - RangeBound lower; RangeBound upper; bool empty; @@ -1311,7 +1284,7 @@ int4range_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 @@ -1320,16 +1293,7 @@ int8range_subdiff(PG_FUNCTION_ARGS) 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 @@ -1342,12 +1306,21 @@ numrange_subdiff(PG_FUNCTION_ARGS) 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) { @@ -1356,7 +1329,7 @@ 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 @@ -1372,7 +1345,7 @@ tstzrange_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 @@ -1384,7 +1357,7 @@ tstzrange_subdiff(PG_FUNCTION_ARGS) *---------------------------------------------------------- * 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. *---------------------------------------------------------- */ @@ -1425,7 +1398,6 @@ range_serialize(FunctionCallInfo fcinfo, RangeBound *lower, RangeBound *upper, bool typbyval; char typstorage; char flags = 0; - RangeTypeInfo rngtypinfo; if (lower->rngtypid != upper->rngtypid) @@ -1509,7 +1481,6 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, Datum lbound; Datum ubound; Pointer flags_ptr; - RangeTypeInfo rngtypinfo; memset(lower, 0, sizeof(RangeBound)); @@ -1571,15 +1542,14 @@ range_deserialize(FunctionCallInfo fcinfo, RangeType *range, RangeBound *lower, } /* - * 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); @@ -1599,7 +1569,6 @@ int range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2) { int result; - RangeTypeInfo rngtypinfo; if (b1->infinite && b2->infinite) @@ -1615,6 +1584,7 @@ range_cmp_bounds(FunctionCallInfo fcinfo, RangeBound *b1, RangeBound *b2) return (b2->lower) ? 1 : -1; range_gettypinfo(fcinfo, b1->rngtypid, &rngtypinfo); + result = DatumGetInt32(FunctionCall2Coll(&rngtypinfo.cmpFn, rngtypinfo.collation, b1->val, b2->val)); @@ -1670,7 +1640,6 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, Form_pg_opclass pg_opclass; Form_pg_type pg_type; HeapTuple tup; - Oid subtypeOid; Oid collationOid; Oid canonicalOid; @@ -1716,10 +1685,9 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, 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)); @@ -1760,14 +1728,18 @@ range_gettypinfo(FunctionCallInfo fcinfo, Oid rngtypid, 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; @@ -1810,12 +1782,6 @@ range_parse_flags(char *flags_str) return flags; } -/* - *---------------------------------------------------------- - * STATIC FUNCTIONS - *---------------------------------------------------------- - */ - /* * Parse range input, modeled after record_in in rowtypes.c. * diff --git a/src/backend/utils/adt/rangetypes_gist.c b/src/backend/utils/adt/rangetypes_gist.c index b307c21ffb..e4737b1902 100644 --- a/src/backend/utils/adt/rangetypes_gist.c +++ b/src/backend/utils/adt/rangetypes_gist.c @@ -3,7 +3,8 @@ * 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 @@ -20,6 +21,8 @@ #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 @@ -33,16 +36,6 @@ #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. */ @@ -53,6 +46,16 @@ typedef struct 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) @@ -60,12 +63,10 @@ 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; @@ -77,14 +78,11 @@ range_gist_consistent(PG_FUNCTION_ARGS) 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; @@ -97,8 +95,8 @@ range_gist_consistent(PG_FUNCTION_ARGS) 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: @@ -107,11 +105,11 @@ range_gist_consistent(PG_FUNCTION_ARGS) } 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 @@ -157,22 +155,20 @@ range_gist_penalty(PG_FUNCTION_ARGS) 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); @@ -371,23 +367,21 @@ range_super_union(FunctionCallInfo fcinfo, RangeType * r1, RangeType * r2) 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; @@ -440,13 +434,16 @@ range_gist_consistent_int(FunctionCallInfo fcinfo, StrategyNumber strategy, 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), @@ -462,8 +459,7 @@ static bool range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy, RangeType * key, RangeType * query) { - Oid proc = InvalidOid; - + Oid proc; RangeBound lower1, lower2; RangeBound upper1, @@ -518,6 +514,10 @@ range_gist_consistent_leaf(FunctionCallInfo fcinfo, StrategyNumber strategy, return false; proc = F_RANGE_ADJACENT; break; + default: + elog(ERROR, "unrecognized range strategy: %d", strategy); + proc = InvalidOid; + break; } return DatumGetBool(OidFunctionCall2(proc, RangeTypeGetDatum(key), @@ -545,16 +545,13 @@ sort_item_cmp(const void *a, const void *b) 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); diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h index 19b437db8d..3826976e82 100644 --- a/src/include/catalog/pg_range.h +++ b/src/include/catalog/pg_range.h @@ -5,7 +5,8 @@ * 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 * @@ -59,16 +60,6 @@ typedef FormData_pg_range *Form_pg_range; #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 @@ -81,4 +72,14 @@ DATA(insert ( 3910 1184 0 10047 - tstzrange_subdiff)); 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 */ diff --git a/src/include/utils/rangetypes.h b/src/include/utils/rangetypes.h index a7595b15f6..e218a91d1a 100644 --- a/src/include/utils/rangetypes.h +++ b/src/include/utils/rangetypes.h @@ -3,47 +3,57 @@ * 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 @@ -62,16 +72,6 @@ extern Datum range_constructor0(PG_FUNCTION_ARGS); 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); @@ -84,7 +84,7 @@ extern Datum range_upper_inc(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); @@ -115,45 +115,40 @@ extern Datum range_gt(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 */ diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out index 495508c42e..3514dece30 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -345,7 +345,7 @@ select numrange(1.0, 2.0) + numrange(1.5, 3.0); (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? ---------- -- 2.40.0