为什么`infinity`不包含在范围内?

时间:2019-04-29 14:20:12

标签: postgresql range

我的范围上限是无穷大。

为什么这个范围不包含无穷大?

我希望这返回true:

=> select '[2019-01-02, infinity]'::daterange @> 'infinity'::date;
 ?column? 
----------
 f
(1 row)

因为:

=> select 'infinity'::date = 'infinity'::date;
 ?column? 
----------
 t
(1 row)

3 个答案:

答案 0 :(得分:1)

select '[2019-01-02, infinity]'::daterange;
+-------------------------------------------+
| daterange                                 |
|-------------------------------------------|
| DateRange('2019-01-02', 'infinity', '[)') |
+-------------------------------------------+

[)表示排除右边框。

  

但是请注意,这些无限值永远不会是范围元素类型的值,并且永远不会成为范围的一部分。

https://www.postgresql.org/docs/current/rangetypes.html

修改

还请注意:

select '[2019-01-01, 2019-01-31]'::daterange;         
+---------------------------------------------+
| daterange                                   |
|---------------------------------------------|
| DateRange('2019-01-01', '2019-02-01', '[)') |
+---------------------------------------------+

包含范围会在一天后转换为专属范围。应该如何做到无穷大?

答案 1 :(得分:1)

The documentation说:

  

此外,某些元素类型具有“无穷大”的概念,但是就范围类型机制而言,这只是另一个值。例如,在时间戳范围内,[today,][today,)的含义相同。但是[today,infinity]的含义与[today,infinity)有所不同,后者不包含特殊的时间戳记值infinity

这似乎与您的观察结果完全矛盾,因为

SELECT 'infinity'::date;
   date   
----------
 infinity
(1 row)

对此行为的解释是PostgreSQL将“离散”类型(dateinteger类型)的范围转换为它们的“规范”表示形式:

SELECT '[2010-01-01,2010-02-28]'::daterange;
        daterange        
-------------------------
 [2010-01-01,2010-03-01)
(1 row)

这就是您的示例中发生的情况:PostgreSQL在infinity上加1(不会更改值),并将包含的上限转换为专有的上限。

现在可以说这不是正确的行为,因为现在infinity不再是间隔的一部分。我已发送patch来解决此问题;希望它将得到应用。

答案 2 :(得分:1)

感谢ilmari

对于那些正在寻找select '[2019-01-02, infinity]'::daterange @> 'infinity'::date;的有效解决方案的人,即:不要以infinity为界,请使用无界范围:

> select '[2019-01-02,)'::daterange @> 'infinity'::date;
 ?column? 
----------
 t
(1 row)

> select '[2019-01-02,]'::daterange @> 'infinity'::date;
 ?column? 
----------
 t
(1 row)