Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qyHqc-007Nwp-H0 for pgsql-docs@arkaria.postgresql.org; Wed, 01 Nov 2023 20:29:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1qyHpb-008knE-N0 for pgsql-docs@arkaria.postgresql.org; Wed, 01 Nov 2023 20:28:51 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qyHpb-008kn5-BG for pgsql-docs@lists.postgresql.org; Wed, 01 Nov 2023 20:28:51 +0000 Received: from momjian.us ([72.94.173.45]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1qyHpY-003UvW-Bm for pgsql-docs@lists.postgresql.org; Wed, 01 Nov 2023 20:28:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=momjian.us; s=2023062407; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description; bh=YVLvLjw3utHFr5oL/vqwjjlJbCxNQ4Xn1yU5h+rNNiA=; b=edhxX m8sHCjmkqR5p4RAGVfN1FD3Pq7plhV0X4e/ai6Ege3tZWe+aTJOLkEU42dH5LmG92+xp7O4T2fpuf ulIGb4ISZhiD8YU2hfcAzHZ3yj6AnJ11adDG29pykya6nVAaWbsVsL5Rkg7Er9jLR9JXXb6dVh2Ao bcUsrUlOJo2rdkxmpBOO3Ux76yinGl8SkrvM9YWvYj22n3CpVonYeJQwsVfcH1io7gxybOHnuSdY7 qXLz0hcUp+R4zjVX2M3c4llcXmsCli4hRn9NTgMY9cMJeYajJqEs4yOkSgotr1RwyJvTz7dOKDDi2 OkOayPFtSTBXJsAmxjtIpPga4EcIg==; Received: from bruce by momjian.us with local (Exim 4.96) (envelope-from ) id 1qyHpS-009hT1-37; Wed, 01 Nov 2023 16:28:42 -0400 Date: Wed, 1 Nov 2023 16:28:42 -0400 From: Bruce Momjian To: Laurenz Albe Cc: Fujii Masao , jani.rahkola@iki.fi, pgsql-docs@lists.postgresql.org Subject: Re: Documentation of return values of range functions lower and upper Message-ID: 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> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="k5IA1Arm4fThtaCF" Content-Disposition: inline In-Reply-To: <02f3fa3a592fa6c1f8ec1a9f539ae376f744eb42.camel@cybertec.at> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --k5IA1Arm4fThtaCF Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 https://momjian.us EDB https://enterprisedb.com Only you can decide what is important to you. --k5IA1Arm4fThtaCF Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="range.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)') ... Extracts the lower bound of the range (NULL if the - range is empty or the lower bound is infinite). + range is empty or unspecified). lower(numrange(1.1,2.2)) @@ -19923,7 +19923,7 @@ SELECT NULLIF(value, '(none)') ... Extracts the upper bound of the range (NULL if the - range is empty or the upper bound is infinite). + range is empty or unspecified). upper(numrange(1.1,2.2)) @@ -19991,7 +19991,8 @@ SELECT NULLIF(value, '(none)') ... boolean - Is the range's lower bound infinite? + Is the range's lower bound unspecified? A +/-Infinity lower + bound returns false. lower_inf('(,)'::daterange) @@ -20008,7 +20009,8 @@ SELECT NULLIF(value, '(none)') ... boolean - Is the range's upper bound infinite? + Is the range's upper bound unspecified? A +/-Infinity upper + bound returns false. upper_inf('(,)'::daterange) @@ -20063,7 +20065,7 @@ SELECT NULLIF(value, '(none)') ... Extracts the lower bound of the multirange (NULL if the - multirange is empty or the lower bound is infinite). + multirange is empty or unspecified). lower('{[1.1,2.2)}'::nummultirange) @@ -20081,7 +20083,7 @@ SELECT NULLIF(value, '(none)') ... Extracts the upper bound of the multirange (NULL if the - multirange is empty or the upper bound is infinite). + multirange is empty or unspecified). upper('{[1.1,2.2)}'::nummultirange) @@ -20149,7 +20151,8 @@ SELECT NULLIF(value, '(none)') ... boolean - Is the multirange's lower bound infinite? + Is the multirange's lower bound unspecified? A +/-Infinity lower + bound returns false. lower_inf('{(,)}'::datemultirange) @@ -20166,7 +20169,8 @@ SELECT NULLIF(value, '(none)') ... boolean - Is the multirange's upper bound infinite? + Is the multirange's upper bound unspecified? A +/-Infinity upper + bound returns false. upper_inf('{(,)}'::datemultirange) --k5IA1Arm4fThtaCF--