pg.ddx.io  pgsql-docs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Bruce Momjian <bruce@momjian.us>
To: Laurenz Albe <laurenz.albe@cybertec.at>
Cc: Fujii Masao <masao.fujii@oss.nttdata.com>
Cc: jani.rahkola@iki.fi
Cc: pgsql-docs@lists.postgresql.org
Subject: Re: Documentation of return values of range functions lower and upper
Date: Wed, 1 Nov 2023 16:28:42 -0400
Message-ID: <ZUK0-gzxmfHdDila@momjian.us> (raw)
In-Reply-To: <02f3fa3a592fa6c1f8ec1a9f539ae376f744eb42.camel@cybertec.at>
References: <160508672127.25505.8356390205508789564@wrigleys.postgresql.org>
	<53ec9f116bea9252d7fa9341e024530553656c42.camel@cybertec.at>
	<16601466752e40543051369fac722c0a200bb4e6.camel@cybertec.at>
	<27d690d8-0987-5f2b-a2da-fc2ec7c19e3c@oss.nttdata.com>
	<02f3fa3a592fa6c1f8ec1a9f539ae376f744eb42.camel@cybertec.at>

On Wed, Nov 18, 2020 at 05:28:44PM +0100, Laurenz Albe wrote:
> On Wed, 2020-11-18 at 22:49 +0900, Fujii Masao wrote:
> > On 2020/11/12 17:14, Laurenz Albe wrote:
> > 
> > > On Wed, 2020-11-11 at 18:19 +0100, Laurenz Albe wrote:
> > > > > Table 9.54 in page
> > > > > https://www.postgresql.org/docs/current/functions-range.html states that the
> > > > > functions lower and upper return NULL if the requested bound is infinite. If
> > > > > the element type of the range contains the special values infinity and
> > > > > -infinity, this is not correct, as those values are returned if explicitly
> > > > > used as either bound.
> > > > +1
> > > > Perhaps it would be better to say
> > > >     NULL if the range is empty or has no lower/upper bound
> > 
> > I agree this description looks a bit confusing. But according to the section
> > "Infinite (Unbounded) Ranges" (*1), we already call "lower/upper bound
> > omitted" just infinite. So I don't think the current description is incorrect.
> > 
> > (*1)
> > https://www.postgresql.org/docs/devel/rangetypes.html#RANGETYPES-INFINITE
> 
> That is correct, but I'd argue that it would be better to clarify the paragraph too,
> in particular:
> 
>   The functions lower_inf and upper_inf test for infinite lower and upper bounds of a range, respectively.
> 
> should better read
> 
>   The functions lower_inf and upper_inf test for omitted lower and upper bounds of a range, respectively.
> 
> The rest of the paragraph is pretty unambiguous.
> 
> 
> Independent of this, I think that my patch for "upper" and "lower" would make the
> documentation clearer.

Yes, I agree this documentation needs help.  Look at this output I
verified in PG 11 and master:

	SELECT upper('[now,]'::tstzrange);
	 upper
	--------
	 (null)
	
	SELECT upper('[now,infinity]'::tstzrange);
	  upper
	----------
	 infinity
	
	SELECT upper('[-infinity,-infinity]'::tstzrange);
	   upper
	-----------
	 -infinity
	
	SELECT upper_inf('[now,]'::tstzrange);
	 upper_inf
	-----------
	 t
	
	SELECT upper_inf('[now,infinity]'::tstzrange);
	 upper_inf
	-----------
	 f
	
	SELECT upper_inf('[-infinity,-infinity]'::tstzrange);
	 upper_inf
	-----------
	 f

For upper/lower(), it is clear that the documentation is better saying
"unspecified" rather than infinite.  The fact that upper/lower_inf()
returns false for +/-Infinity is quite odd, but should at least be
documented.

Patch attached.  It is odd that +Infinity (vs. Infinity) wasn't
supported for datetime input until PG 16, but I think we have to say
+/-infinity vs (blank)/-Infinity.

Patch attached.

-- 
  Bruce Momjian  <bruce@momjian.us>        https://momjian.us
  EDB                                      https://enterprisedb.com

  Only you can decide what is important to you.

Attachments:

  [text/x-diff] range.diff (3.0K, ../ZUK0-gzxmfHdDila@momjian.us/2-range.diff)
  download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index c76ec52c55..fd390b03ac 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -19905,7 +19905,7 @@ SELECT NULLIF(value, '(none)') ...
        </para>
        <para>
         Extracts the lower bound of the range (<literal>NULL</literal> if the
-        range is empty or the lower bound is infinite).
+        range is empty or unspecified).
        </para>
        <para>
         <literal>lower(numrange(1.1,2.2))</literal>
@@ -19923,7 +19923,7 @@ SELECT NULLIF(value, '(none)') ...
        </para>
        <para>
         Extracts the upper bound of the range (<literal>NULL</literal> if the
-        range is empty or the upper bound is infinite).
+        range is empty or unspecified).
        </para>
        <para>
         <literal>upper(numrange(1.1,2.2))</literal>
@@ -19991,7 +19991,8 @@ SELECT NULLIF(value, '(none)') ...
         <returnvalue>boolean</returnvalue>
        </para>
        <para>
-        Is the range's lower bound infinite?
+        Is the range's lower bound unspecified?  A +/-Infinity lower
+        bound returns false.
        </para>
        <para>
         <literal>lower_inf('(,)'::daterange)</literal>
@@ -20008,7 +20009,8 @@ SELECT NULLIF(value, '(none)') ...
         <returnvalue>boolean</returnvalue>
        </para>
        <para>
-        Is the range's upper bound infinite?
+        Is the range's upper bound unspecified?  A +/-Infinity upper
+        bound returns false.
        </para>
        <para>
         <literal>upper_inf('(,)'::daterange)</literal>
@@ -20063,7 +20065,7 @@ SELECT NULLIF(value, '(none)') ...
        </para>
        <para>
         Extracts the lower bound of the multirange (<literal>NULL</literal> if the
-        multirange is empty or the lower bound is infinite).
+        multirange is empty or unspecified).
        </para>
        <para>
         <literal>lower('{[1.1,2.2)}'::nummultirange)</literal>
@@ -20081,7 +20083,7 @@ SELECT NULLIF(value, '(none)') ...
        </para>
        <para>
         Extracts the upper bound of the multirange (<literal>NULL</literal> if the
-        multirange is empty or the upper bound is infinite).
+        multirange is empty or unspecified).
        </para>
        <para>
         <literal>upper('{[1.1,2.2)}'::nummultirange)</literal>
@@ -20149,7 +20151,8 @@ SELECT NULLIF(value, '(none)') ...
         <returnvalue>boolean</returnvalue>
        </para>
        <para>
-        Is the multirange's lower bound infinite?
+        Is the multirange's lower bound unspecified?  A +/-Infinity lower
+        bound returns false.
        </para>
        <para>
         <literal>lower_inf('{(,)}'::datemultirange)</literal>
@@ -20166,7 +20169,8 @@ SELECT NULLIF(value, '(none)') ...
         <returnvalue>boolean</returnvalue>
        </para>
        <para>
-        Is the multirange's upper bound infinite?
+        Is the multirange's upper bound unspecified?  A +/-Infinity upper
+        bound returns false.
        </para>
        <para>
         <literal>upper_inf('{(,)}'::datemultirange)</literal>

view thread (14+ messages)  latest in thread

Message-ID: <ZUK0-gzxmfHdDila@momjian.us>
Permalink:  ../ZUK0-gzxmfHdDila@momjian.us/
Also on:    postgresql.org/message-id/ZUK0-gzxmfHdDila@momjian.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-docs@postgresql.org
  Cc: bruce@momjian.us, laurenz.albe@cybertec.at, masao.fujii@oss.nttdata.com, jani.rahkola@iki.fi, pgsql-docs@lists.postgresql.org
  Subject: Re: Documentation of return values of range functions lower and upper
  In-Reply-To: <ZUK0-gzxmfHdDila@momjian.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox