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 1ugbYz-005JWn-Ex for pgsql-docs@arkaria.postgresql.org; Tue, 29 Jul 2025 04:03:42 +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 1ugbYy-00E8yB-Ic for pgsql-docs@arkaria.postgresql.org; Tue, 29 Jul 2025 04:03:40 +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 1ugbYy-00E8wS-9B for pgsql-docs@lists.postgresql.org; Tue, 29 Jul 2025 04:03:40 +0000 Received: from mail.postgrespro.ru ([93.174.132.70]) by makus.postgresql.org with smtp (Exim 4.96) (envelope-from ) id 1ugbYv-001JZX-1o for pgsql-docs@lists.postgresql.org; Tue, 29 Jul 2025 04:03:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1753761814; bh=lJ6ryoVGIw3mVs8sXrquJT5gVBJWTvnT4RkIFmWOhqk=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Message-ID:From; b=FyDcLvqdXLig6ojP4e2rVgbZgBJ6TRYWq60o/HXi8K8zFI5qTMgIjt6D18+srzOZ2 Pk8YPMHvnemdsKQRtXLLZsZTeSfCRdhits4uwrmUjEh9D6NYqndp/Nm4mDbTtSfHEN DgwfMf+U4v2NnmWqfx6/+MO66BAGAiI43xk8ZIMyHnSZJLm/k1eozRQSX0eZ7jIXjl +5PTdznkxVHTlJk7DoJvTIvnQ1almBuFadaH0f8veLTf6tqMC+Z88aCCxfwjDzqL4O OAXoB/JSvjlknj/k1q9/Yi1LliVXghpOSkRaaLB9g49iQLAKUEF61XnlCjrsCkkYUv 5gLhr5YdXEuoA== Received: from mail.postgrespro.ru (webmail-master-mstn.l.postgrespro.ru [192.168.2.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (Client did not present a certificate) (Authenticated sender: o.tselebrovskiy@postgrespro.ru) by mail.postgrespro.ru (Postfix/587) with ESMTPSA id 0021C5FF82; Tue, 29 Jul 2025 07:03:33 +0300 (MSK) MIME-Version: 1.0 Date: Tue, 29 Jul 2025 11:03:33 +0700 From: Oleg Tselebrovskiy To: Alexander Korotkov Cc: pgsql-docs@lists.postgresql.org Subject: Re: Initcap works differently with different locale providers In-Reply-To: References: <804cc10ef95d4d3b298e76b181fd9437@postgrespro.ru> <0658C8F0-5ED4-4962-A2A3-524B0D899982@gmail.com> Message-ID: <0a54a90a5154281486b1acb07e5650df@postgrespro.ru> X-Sender: o.tselebrovskiy@postgrespro.ru Organization: Postgres Pro Content-Type: text/plain; charset=UTF-8; format=flowed X-KSMG-AntiPhishing: NotDetected, bases: 2025/07/29 03:49:00 X-KSMG-AntiSpam-Interceptor-Info: not scanned X-KSMG-AntiSpam-Status: not scanned, disabled by settings X-KSMG-AntiVirus: Kaspersky Secure Mail Gateway, version 2.1.0.7854, bases: 2025/07/29 03:40:00 #27645574 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: not scanned, disabled by settings X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 1 Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Alexander Korotkov wrote at 2025-07-28 17:23: > On Mon, Jul 28, 2025 at 1:20=E2=80=AFPM Alexander Korotkov=20 > wrote: >>=20 >> On 25 Sep 2024, at 18:13, Oleg Tselebrovskiy=20 >> wrote: >>=20 >> Greetings, everyone! >>=20 >> One of our clients has found a difference in behaviour of initcap=20 >> function when >> using different locale providers, shown below >>=20 >> postgres=3D# create database test_db_1 locale_provider=3Dicu=20 >> locale=3D"ru_RU.UTF-8" template=3Dtemplate0; >> NOTICE: using standard form "ru-RU" for ICU locale "ru_RU.UTF-8" >> CREATE DATABASE >> postgres=3D# \c test_db_1; >> You are now connected to database "test_db_1" as user "postgres". >> test_db_1=3D# select initcap('=D0=A7=D0=B8=D0=AE =D0=90.=D0=AE.'); >> initcap >> ---------- >> =D0=A7=D0=B8=D1=8E =D0=90.=D1=8E. >> (1 row) >> test_db_1=3D# select initcap('joHn d.e.'); >> initcap >> ----------- >> John D.e. >> (1 row) >> postgres=3D# create database test_db_2 locale_provider=3Dlibc=20 >> locale=3D"ru_RU.UTF-8" template=3Dtemplate0; >> CREATE DATABASE >> postgres=3D# \c test_db_2 >> You are now connected to database "test_db_2" as user "postgres". >> test_db_2=3D# select initcap('=D0=A7=D0=B8=D0=AE =D0=90.=D0=AE.'); >> initcap >> ---------- >> =D0=A7=D0=B8=D1=8E =D0=90.=D0=AE. >> (1 row) >> test_db_2=3D# select initcap('joHn d.e.'); >> initcap >> ----------- >> John D.E. >> (1 row) >>=20 >> And an easier reproduction (should work for REL_12_STABLE and up) >>=20 >> postgres=3D# SELECT initcap('first.second' COLLATE "en-x-icu"); >> initcap >> -------------- >> First.second >> (1 row) >> postgres=3D# SELECT initcap('first.second' COLLATE "en_US"); >> initcap >> -------------- >> First.Second >> (1 row) >>=20 >> This behaviour is reproducible on REL_12_STABLE and up to master >>=20 >> I don't believe that this is an erroneous behaviour, just a differing=20 >> one, hence >> just a documentation change proposition >>=20 >> I suggest adding a clarification that this function works differently=20 >> with libc >> and ICU providers because there is a difference in what a "word" is=20 >> between them >>=20 >> In libc a word is a sequence of alphanumeric characters, separated by >> non-alphanumeric characters (as it is written in documentation right=20 >> now) >> In ICU words are divided according to Unicode=C2=AE Standard Annex #29= [1] >>=20 >> Similar issue was briefly discussed in [2] >>=20 >> The suggested documentation patch is attached (versions for=20 >> REL_13_STABLE+ and >> for REL_12_STABLE only) >>=20 >> [1]: https://www.unicode.org/reports/tr29/#Word_Boundaries >> [2]:=20 >> https://www.postgresql.org/message-id/CAEwbS1R8pwhRkwRo3XsPt24ErBNtFWu= ReAZhVPJwA3oqo148tA%40mail.gmail.com >>=20 >> Oleg Tselebrovskiy, Postgres=20 >> Professional >>=20 >>=20 >> I can confirm inicap works with libc and libicu as you stated. The=20 >> documentation patch looks good to me. I=E2=80=99ve written a commit m= essage. =20 >> The REL_12_STABLE branch is not relevant anymore as it=E2=80=99s out o= f=20 >> support. I=E2=80=99m going to push this if no objections. >=20 > I'm sorry for these many messages. My email client just gone crazy. > Must be fixed now. >=20 > ------ > Regards, > Alexander Korotkov > Supabase Commit message looks good to me, also no objections on ignoring=20 REL_12_STABLE :) Thank you! Regards, Oleg Tselebrovskiy