问题
In the course of writing a program that accepts tsrange literals from the user, which are then plugged into various SQL queries, today I was testing some tsranges to see how they are interpreted by PostgreSQL 9.3.5.
This one, in particular, behaves strangely: '(-infinity,today)'::tsrange
The lower_inf function says the lower bound is not infinite (!)
test=> SELECT lower_inf('(-infinity,today)'::tsrange);
lower_inf
-----------
f
(1 row)
Yet PostgreSQL reports that this tsrange contains a timestamp like '1000-01-01 BC' . . .
test=> SELECT '(-infinity,today)'::tsrange @> '1000-01-01 BC'::timestamp;
?column?
----------
t
(1 row)
Can anyone shed light on this?
回答1:
The confusion stems from two different meanings of "infinity" here.
timestamp
types accept special values for infinity and -infinity.- Range types have a general concept for ranges without lower / upper bound. The functions to test for it are called lower_inf() and upper_inf(), but they are really testing for "no bound" in the range. Ranges with no upper / lower bound include the value
infinity
/-infinity
fortimestamp
respectively.
The manual:
Also, some element types have a notion of "infinity", but that is just another value so far as the range type mechanisms are concerned. For example, in timestamp ranges,
[today,]
means the same thing as[today,)
. But[today,infinity]
means something different from[today,infinity)
— the latter excludes the special timestamp valueinfinity
.
SQL Fiddle.
Maybe those functions should really be called something like lower_nobound()
and upper_nobound()
to avoid confusion ...
来源:https://stackoverflow.com/questions/27103608/postgresql-tsrange-is-it-correct-for-lower-inf-infinity-todaytsrange-to