From: Jeff Davis Date: Fri, 19 Jul 2019 00:01:44 +0000 (-0700) Subject: Fix daterange canonicalization for +/- infinity. X-Git-Tag: REL9_4_24~18 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=2be355498eafaddc1c274f05884e1ed79b671655;p=postgresql.git Fix daterange canonicalization for +/- infinity. The values 'infinity' and '-infinity' are a part of the DATE type itself, so a bound of the date 'infinity' is not the same as an unbounded/infinite range. However, it is still wrong to try to canonicalize such values, because adding or subtracting one has no effect. Fix by treating 'infinity' and '-infinity' the same as unbounded ranges for the purposes of canonicalization (but not other purposes). Backpatch to all versions because it is inconsistent with the documented behavior. Note that this could be an incompatibility for applications relying on the behavior contrary to the documentation. Author: Laurenz Albe Reviewed-by: Thomas Munro Discussion: https://postgr.es/m/77f24ea19ab802bc9bc60ddbb8977ee2d646aec1.camel%40cybertec.at Backpatch-through: 9.4 --- diff --git a/src/backend/utils/adt/rangetypes.c b/src/backend/utils/adt/rangetypes.c index 39d3cff3172..b4d50ec639f 100644 --- a/src/backend/utils/adt/rangetypes.c +++ b/src/backend/utils/adt/rangetypes.c @@ -1338,13 +1338,13 @@ daterange_canonical(PG_FUNCTION_ARGS) if (empty) PG_RETURN_RANGE(r); - if (!lower.infinite && !lower.inclusive) + if (!lower.infinite && !DATE_NOT_FINITE(lower.val) && !lower.inclusive) { lower.val = DirectFunctionCall2(date_pli, lower.val, Int32GetDatum(1)); lower.inclusive = true; } - if (!upper.infinite && upper.inclusive) + if (!upper.infinite && !DATE_NOT_FINITE(upper.val) && upper.inclusive) { upper.val = DirectFunctionCall2(date_pli, upper.val, Int32GetDatum(1)); upper.inclusive = false; diff --git a/src/test/regress/expected/rangetypes.out b/src/test/regress/expected/rangetypes.out index b942ab1378b..293de8fbf7b 100644 --- a/src/test/regress/expected/rangetypes.out +++ b/src/test/regress/expected/rangetypes.out @@ -634,6 +634,30 @@ select daterange('2000-01-10'::date, '2000-01-11'::date, '(]'); [01-11-2000,01-12-2000) (1 row) +select daterange('-infinity'::date, '2000-01-01'::date, '()'); + daterange +------------------------ + (-infinity,01-01-2000) +(1 row) + +select daterange('-infinity'::date, '2000-01-01'::date, '[)'); + daterange +------------------------ + [-infinity,01-01-2000) +(1 row) + +select daterange('2000-01-01'::date, 'infinity'::date, '[)'); + daterange +----------------------- + [01-01-2000,infinity) +(1 row) + +select daterange('2000-01-01'::date, 'infinity'::date, '[]'); + daterange +----------------------- + [01-01-2000,infinity] +(1 row) + -- test GiST index that's been built incrementally create table test_range_gist(ir int4range); create index test_range_gist_idx on test_range_gist using gist (ir); diff --git a/src/test/regress/sql/rangetypes.sql b/src/test/regress/sql/rangetypes.sql index 94587f02fee..72a09eaed95 100644 --- a/src/test/regress/sql/rangetypes.sql +++ b/src/test/regress/sql/rangetypes.sql @@ -161,6 +161,10 @@ select daterange('2000-01-10'::date, '2000-01-20'::date, '(]'); select daterange('2000-01-10'::date, '2000-01-20'::date, '()'); select daterange('2000-01-10'::date, '2000-01-11'::date, '()'); select daterange('2000-01-10'::date, '2000-01-11'::date, '(]'); +select daterange('-infinity'::date, '2000-01-01'::date, '()'); +select daterange('-infinity'::date, '2000-01-01'::date, '[)'); +select daterange('2000-01-01'::date, 'infinity'::date, '[)'); +select daterange('2000-01-01'::date, 'infinity'::date, '[]'); -- test GiST index that's been built incrementally create table test_range_gist(ir int4range);