Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iwGMI-0005ph-K5 for pgsql-hackers@arkaria.postgresql.org; Tue, 28 Jan 2020 02:12:06 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iwGMG-0007Aq-VD for pgsql-hackers@arkaria.postgresql.org; Tue, 28 Jan 2020 02:12:04 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iwGMG-0007Aj-J5 for pgsql-hackers@lists.postgresql.org; Tue, 28 Jan 2020 02:12:04 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1iwGMD-0003VL-GR for pgsql-hackers@lists.postgresql.org; Tue, 28 Jan 2020 02:12:03 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id 00S2BvjT007213; Mon, 27 Jan 2020 21:11:57 -0500 From: Tom Lane To: Peter Eisentraut cc: =?UTF-8?Q?Juan_Jos=c3=a9_Santamar=c3=ada_Flecha?= , Alvaro Herrera , Arthur Zakirov , Tomas Vondra , PostgreSQL Hackers Subject: Re: Allow to_date() and to_timestamp() to accept localized names In-reply-to: References: <20200124161814.GA8989@alvherre.pgsql> <32487.1579882979@sss.pgh.pa.us> <2f83150e-a2c0-6318-3125-d9b86e421aa2@2ndquadrant.com> <964.1579884408@sss.pgh.pa.us> Comments: In-reply-to Peter Eisentraut message dated "Sat, 25 Jan 2020 10:31:42 +0100" MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-ID: <7211.1580177517.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Mon, 27 Jan 2020 21:11:57 -0500 Message-ID: <7212.1580177517@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Peter Eisentraut writes: > For the record, the correct form of that would appear to be > select to_date('=CE=99=CE=B1=CE=BD=CE=BF=CF=85=CE=AC=CF=81=CE=B9=CE=BF=CF= =82', 'TMMonth'); > with the accent. I had tried different variations of that and they all = > failed. OK, so for anyone who is as confused as I was, the main point here seems to be this: the upper case form of Greek sigma is '=CE=A3', and the lower case form is '=CF=83' ... except as the final letter of a word, where it is supposed to be written like '=CF=82'. If I set lc_collate, lc_ctype, and lc_time to 'el_GR.utf8', then (on a somewhat hoary glibc platform) I get u8=3D# select to_char('2020-01-01'::timestamptz, 'TMMONTH'); = to_char = ---------------------- =CE=99=CE=91=CE=9D=CE=9F=CE=A5=CE=86=CE=A1=CE=99=CE=9F=CE=A3 (1 row) u8=3D# select to_char('2020-01-01'::timestamptz, 'TMMonth'); to_char = ---------------------- =CE=99=CE=B1=CE=BD=CE=BF=CF=85=CE=AC=CF=81=CE=B9=CE=BF=CF=82 (1 row) u8=3D# select to_char('2020-01-01'::timestamptz, 'TMmonth'); to_char = ---------------------- =CE=B9=CE=B1=CE=BD=CE=BF=CF=85=CE=AC=CF=81=CE=B9=CE=BF=CF=82 (1 row) which is correct AFAICS ... but u8=3D# select lower(to_char('2020-01-01'::timestamptz, 'TMMONTH')); lower = ---------------------- =CE=B9=CE=B1=CE=BD=CE=BF=CF=85=CE=AC=CF=81=CE=B9=CE=BF=CF=83 (1 row) So what we actually have here, ISTM, is a bug in lower() not to_char(). The bug is unsurprising because str_tolower() simply applies towlower_l() to each character independently, so there's no way for it to account for the word-final rule. I'm not aware that glibc provides any API whereby that could be done correctly. On the other hand, we get it right when using an ICU collation for lower(): u8=3D# select lower(to_char('2020-01-01'::timestamptz, 'TMMONTH') collate = "el-gr-x-icu"); lower = ---------------------- =CE=B9=CE=B1=CE=BD=CE=BF=CF=85=CE=AC=CF=81=CE=B9=CE=BF=CF=82 (1 row) because that code path passes the whole string to ICU at once, and of course getting this right is ICU's entire job. I haven't double-checked, but I imagine that the reason that to_char gets the month name case-folding right is that what comes out of strftime(..."%B"...) is "=CE=99=CE=B1=CE=BD=CE=BF=CF=85=CE=AC=CF=81=CE=B9=CE= =BF=CF=82" which we are able to upcase correctly, while the downcasing code paths don't affect '=CF=82'. I thought for a little bit about trying to dodge this issue in the patch by folding to upper case, not lower, before comparing month/day names. I fear that that would just shift the problem cases to some other language(s). However, it makes Greek better, and I think it makes German better (does '=C3=9F' appear in any month/day names there?), so maybe we should just roll with that. In the end, it doesn't seem right to reject this patch just because lower() is broken on some platforms. The other question your example raises is whether we should be trying to de-accent before comparison, ie was it right for '=CE=99=CE=B1=CE=BD=CE= =BF=CF=85=CE=AC=CF=81=CE=B9=CE=BF=CF=82' to be treated differently from '=CE=99=CE=B1=CE=BD=CE=BF=CF=85=CE=B1=CF=81=CE= =B9=CE=BF=CF=82'. I don't know enough Greek to say, but it kind of feels like that should be outside to_date's purview. regards, tom lane