为何显式用infinity作范围上界时upper_inf返回false?
PostgreSQL范围类型中
upper_inf函数的行为疑问 PostgreSQL范围类型文档指出,特殊时间戳infinity的作用应与省略边界值相同:
具有“无穷”概念的元素类型可将其用作显式边界值。例如,对于时间戳范围,
[today,infinity)排除特殊时间戳值infinity,而[today,infinity]包含它,[today,)和[today,]同样包含它。lower_inf和upper_inf函数分别用于检测范围的无穷下界和上界。
但实际使用upper_inf测试范围(或多范围)时,显式指定infinity的情况下结果始终为false:
SELECT * FROM ( SELECT 1 AS test, upper_inf('{(,)}'::tstzmultirange) UNION SELECT 2, upper_inf('{(,infinity)}'::tstzmultirange) UNION SELECT 3, upper_inf('{(,]}'::tstzmultirange) UNION SELECT 4, upper_inf('{(,infinity]}'::tstzmultirange) UNION SELECT 5, upper_inf('(,)'::tstzrange) UNION SELECT 6, upper_inf('(,infinity)'::tstzrange) UNION SELECT 7, upper_inf('(,]'::tstzrange) UNION SELECT 8, upper_inf('(,infinity]'::tstzrange) ) AS cases ORDER BY test;
执行结果:
1 true 2 false 3 true 4 false 5 true 6 false 7 true 8 false
原因解释
核心区别在于**“无穷边界”和“显式用infinity值做边界”是两个完全不同的概念**:
- 当省略上边界(比如
(,)或(,])时,PostgreSQL会把这个范围标记为「上界无穷」,此时upper_inf返回true,代表范围没有实际上限,自然包含所有时间戳(包括infinity)。 - 当显式指定
infinity作为边界值时,这个范围的上边界是一个具体的特殊值,而非「无边界」。upper_inf的作用是检测范围本身是否属于“无边界”类型,不是判断范围是否包含infinity值。
文档里说的「[today,)和[today,]包含infinity」,指的是范围的取值覆盖该特殊值;而upper_inf判断的是范围的属性(有没有上界),二者语义完全不同。如果要判断范围是否包含infinity,应该用@>操作符,比如:
SELECT '(,infinity]'::tstzrange @> 'infinity'::timestamptz; -- 返回true SELECT '(,)'::tstzrange @> 'infinity'::timestamptz; -- 返回true
内容的提问来源于stack exchange,提问作者Jan Klan
相关产品推荐
相关产品推荐

