]> granicus.if.org Git - postgresql/commitdiff
Fix daterange canonicalization for +/- infinity.
authorJeff Davis <jdavis@postgresql.org>
Thu, 18 Jul 2019 23:55:59 +0000 (16:55 -0700)
committerJeff Davis <jdavis@postgresql.org>
Thu, 18 Jul 2019 23:55:59 +0000 (16:55 -0700)
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

src/backend/utils/adt/rangetypes.c
src/test/regress/expected/rangetypes.out
src/test/regress/sql/rangetypes.sql

index 88f857b509f806f11c9e91dbb161b15c9a1969eb..288052347b39d0007bafc9497c1f2818db680c7d 100644 (file)
@@ -1366,13 +1366,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;
index ae03246050f786ab727dcbda551ed2f386419adc..6756a2151b9806d7654c03b047ea45e2a379b08c 100644 (file)
@@ -652,6 +652,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);
index 9148d1c893e50b3a0780734474c2cc7b6736d0aa..62cb474a42324d120851025f61acb2e939ff9c01 100644 (file)
@@ -165,6 +165,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);