Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix daterange canonicalization for +/- infinity.
authorJeff Davis <jdavis@postgresql.org>
Thu, 18 Jul 2019 21:01:17 +0000 (14:01 -0700)
committerJeff Davis <jdavis@postgresql.org>
Thu, 18 Jul 2019 21:01:17 +0000 (14: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 5a5d0a0b8fc11c1396a450c2c861d1b7c1c0a0ae..5b28e74a593a6ab109821f0b6276709eaf11582a 100644 (file)
@@ -1430,13 +1430,13 @@ daterange_canonical(PG_FUNCTION_ARGS)
    if (empty)
        PG_RETURN_RANGE_P(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 accf1e0d9e25f1cfd84e0b89d1c211c0db1cb0f6..60d875e898ed65f810208f55fb4675eda2c390ac 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 55638a85ee1308a6b48d8bcba9881cb2100eab4a..9fdb1953df54dc545894c17f7716ec4eeb3a041b 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);