]> granicus.if.org Git - postgresql/commitdiff
Fix daterange canonicalization for +/- infinity.
authorJeff Davis <jdavis@postgresql.org>
Fri, 19 Jul 2019 00:01:44 +0000 (17:01 -0700)
committerJeff Davis <jdavis@postgresql.org>
Fri, 19 Jul 2019 00:01:44 +0000 (17:01 -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 39d3cff3172945d355f4b790058bc39353b24151..b4d50ec639f1a0ec3f51d793e798adb4f51fa421 100644 (file)
@@ -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;
index b942ab1378bc23997e4c793ffda503b9fc658114..293de8fbf7bde33e2370e51c2b84a5ac1db3c6fe 100644 (file)
@@ -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);
index 94587f02fee9778e54bf3532f71f801a5b2e3ac2..72a09eaed95e7ddb83966eccc4b4239860e0ca94 100644 (file)
@@ -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);