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 1rcXAz-000eAO-Sk for pgsql-bugs@arkaria.postgresql.org; Tue, 20 Feb 2024 20:57:18 +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 1rcX9x-001QTf-TP for pgsql-bugs@arkaria.postgresql.org; Tue, 20 Feb 2024 20:56:14 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rcX9x-001QTX-LC for pgsql-bugs@lists.postgresql.org; Tue, 20 Feb 2024 20:56:14 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1rcX9s-0003qt-Bl for pgsql-bugs@lists.postgresql.org; Tue, 20 Feb 2024 20:56:13 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 41KKu4Ra270583; Tue, 20 Feb 2024 15:56:04 -0500 From: Tom Lane To: jian he cc: Francisco Olarte , Michael Bondarenko , pgsql-bugs@lists.postgresql.org, dgrowleyml@gmail.com, Peter Eisentraut Subject: Re: BUG #18348: Inconsistency with EXTRACT([field] from INTERVAL); In-reply-to: <222870.1708458150@sss.pgh.pa.us> References: <18348-b097a3587dfde8a4@postgresql.org> <3709307.1708201825@sss.pgh.pa.us> <3749306.1708222748@sss.pgh.pa.us> <222870.1708458150@sss.pgh.pa.us> Comments: In-reply-to Tom Lane message dated "Tue, 20 Feb 2024 14:42:30 -0500" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <270496.1708462532.0@sss.pgh.pa.us> Content-Transfer-Encoding: 8bit Date: Tue, 20 Feb 2024 15:56:04 -0500 Message-ID: <270582.1708462564@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="UTF-8" Content-ID: <270496.1708462532.1@sss.pgh.pa.us> Content-Transfer-Encoding: 8bit I wrote: > jian he writes: >> On Sun, Feb 18, 2024 at 2:14 AM Tom Lane wrote: >>> (Parenthetically, one case that perhaps is surprising is >>> ERROR: unit "week" not supported for type interval >>> Why not just return the day field divided by 7?) >> seems pretty simple? > Hm, maybe, but does this behave desirably for zero or negative days? >> So in section 9.9.1. EXTRACT, date_part >> we may need to document extract(quarter from interval) case. >> intervals can be negative, which will make the issue more complicated. >> except the "quarter" field , EXTRACT other fields from intervals, the >> output seems sane. > Yeah, I see what you mean: the output for negative month counts is > very bizarre, whereas other fields seem to all produce the negative > of what they'd produce for the absolute value of the interval. > We could either try to fix that or decide that rejecting "quarter" > for intervals is the saner answer. After fooling with these cases for a little I'm inclined to think we should do it as attached (no test or docs changes yet). regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="interval-week-and-quarter-fixes.patch"; charset="us-ascii" Content-ID: <270496.1708462532.2@sss.pgh.pa.us> Content-Description: interval-week-and-quarter-fixes.patch Content-Transfer-Encoding: quoted-printable diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/tim= estamp.c index ed03c50a6d..7177c1a62f 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -5992,12 +5992,19 @@ interval_part_common(PG_FUNCTION_ARGS, bool retnum= eric) intresult =3D tm->tm_mday; break; = + case DTK_WEEK: + intresult =3D tm->tm_mday / 7; + break; + case DTK_MONTH: intresult =3D tm->tm_mon; break; = case DTK_QUARTER: - intresult =3D (tm->tm_mon / 3) + 1; + if (tm->tm_year >=3D 0) + intresult =3D (tm->tm_mon / 3) + 1; + else + intresult =3D -((-tm->tm_mon / 3) + 1); break; = case DTK_YEAR: ------- =_aaaaaaaaaa0--