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 1uinmu-00G0OS-SY for pgsql-docs@arkaria.postgresql.org; Mon, 04 Aug 2025 05:31:10 +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 1uinmt-00G3wn-RP for pgsql-docs@arkaria.postgresql.org; Mon, 04 Aug 2025 05:31:07 +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 1uinmt-00G3we-Ae for pgsql-docs@lists.postgresql.org; Mon, 04 Aug 2025 05:31:07 +0000 Received: from mail.postgrespro.ru ([93.174.132.70]) by makus.postgresql.org with smtp (Exim 4.96) (envelope-from ) id 1uinmm-000dCS-24 for pgsql-docs@lists.postgresql.org; Mon, 04 Aug 2025 05:31:06 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mx2023; t=1754285458; bh=p+DPH6aQ142/NjJCgoHQ1aewhcDyuUtNvH1qB7trnG8=; h=Date:From:To:Cc:Subject:In-Reply-To:References:Message-ID:From; b=PdpAwIsEUd30h5XZCx5d8sYY4sIV184WmqkZqlTFmstJ1sTQjui2tD8T5GJMQRfdV wi+FuxH2GQVYhE8KEP+YOAyyzRqm9Sh4/CVO4bc/pppOJt/zbCGvhm/8G2hCbYfDq2 pW7tc6aOBEEKMezu31ADS8/vQJ6vFs3Pa6+df3f1bFU3OobYq8dwzktv6qirSm7tcS 2diFFpcr2AkuuHKPmzz0Ta8eQpKSLOQSkXyuGg9E1l/8/kmeW/UaId5qkLUZan7QbF uIB/uf8AWQ20fqKBL63nh5KXYBmevMOaKddApyfqW5TThVSbg8hNIS7vOyu7Y1xSCP CfTHbIERxC+3g== Received: from mail.postgrespro.ru (webmail-slave-mstn.l.postgrespro.ru [192.168.2.28]) (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 D645B60196; Mon, 4 Aug 2025 08:30:57 +0300 (MSK) MIME-Version: 1.0 Date: Mon, 04 Aug 2025 12:30:57 +0700 From: Oleg Tselebrovskiy To: Jeff Davis Cc: Alexander Korotkov , pgsql-docs@lists.postgresql.org Subject: Re: Initcap works differently with different locale providers In-Reply-To: <9247c1b9531136e15d83511270e8c43bf877c9ca.camel@j-davis.com> References: <804cc10ef95d4d3b298e76b181fd9437@postgrespro.ru> <0658C8F0-5ED4-4962-A2A3-524B0D899982@gmail.com> <9247c1b9531136e15d83511270e8c43bf877c9ca.camel@j-davis.com> Message-ID: X-Sender: o.tselebrovskiy@postgrespro.ru Organization: Postgres Pro Content-Type: multipart/mixed; boundary="=_48b9621db2b07ac69a6afe33b1d31271" X-KSMG-AntiPhishing: NotDetected, bases: 2025/08/04 04:42: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/08/04 02:49:00 #27628184 X-KSMG-AntiVirus-Status: NotDetected, skipped X-KSMG-LinksScanning: not scanned, disabled by settings X-KSMG-Message-Action: skipped X-KSMG-Rule-ID: 1 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --=_48b9621db2b07ac69a6afe33b1d31271 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed Jeff Davis wrote at 2025-07-31 02:58: Apologies for the late answer to a review > First, it doesn't mention the "builtin" provider, which uses the same > word break rules as libc. Completely forgot about builtin provider in the first patch, my bad > Second, word boundaries can be complex, and I'm wondering if we should > not be so precise about what ICU does or doesn't do. For instance, ICU > has options like U_TITLECASE_ADJUST_TO_CASED, > U_TITLECASE_NO_BREAK_ADJUSTMENT, etc., and I'm not sure exactly > which one of those we use. While [1] describes the default word boundary rules and could be useful as a starting point, I agree that in reality it probably is more complicated. I didn't exactly find any place where U_TITLECASE_ADJUST_TO_CASED and alike are set in non-test code, but U_TITLECASE_ADJUST_TO_CASED was used as a default prior to ICU 60, so initcap() will also behave differently depending on ICU version > I'd prefer that we try to explain that INITCAP() is intended for > convenient display, and the specific result should not be relied upon > (at least for ICU; maybe for all providers). If you want specific word > boundary rules, write your own function. First patch just adds this warning about not relying on initcap() exact result. The second one is the same, but removes the part "what is a word" since it's could be moot because we recommend writing custom functions, so understanding what is a word is not exactly needed. Still on the fence about which patch is better, though Thoughts? [1]: https://www.unicode.org/reports/tr29/#Word_Boundaries Regards, Oleg Tselebrovskiy --=_48b9621db2b07ac69a6afe33b1d31271 Content-Transfer-Encoding: base64 Content-Type: text/x-diff; name=v2-0001-initcap-documentation.patch Content-Disposition: attachment; filename=v2-0001-initcap-documentation.patch; size=1532 ZGlmZiAtLWdpdCBhL2RvYy9zcmMvc2dtbC9mdW5jLnNnbWwgYi9kb2Mvc3JjL3NnbWwvZnVuYy5z Z21sCmluZGV4IDc0YTE2YWYwNGFkLi44YTQ0ZTBhZTU5MyAxMDA2NDQKLS0tIGEvZG9jL3NyYy9z Z21sL2Z1bmMuc2dtbAorKysgYi9kb2Mvc3JjL3NnbWwvZnVuYy5zZ21sCkBAIC0zMTQ4LDEyICsz MTQ4LDE5IEBAIFNFTEVDVCBOT1QoUk9XKHRhYmxlLiopIElTIE5PVCBOVUxMKSBGUk9NIFRBQkxF OyAtLSBkZXRlY3QgYXQgbGVhc3Qgb25lIG51bGwgaW4KICAgICAgICA8L3BhcmE+CiAgICAgICAg PHBhcmE+CiAgICAgICAgIENvbnZlcnRzIHRoZSBmaXJzdCBsZXR0ZXIgb2YgZWFjaCB3b3JkIHRv IHVwcGVyIGNhc2UgYW5kIHRoZQotICAgICAgICByZXN0IHRvIGxvd2VyIGNhc2UuIFdoZW4gdXNp bmcgdGhlIDxsaXRlcmFsPmxpYmM8L2xpdGVyYWw+IGxvY2FsZQotICAgICAgICBwcm92aWRlciwg d29yZHMgYXJlIHNlcXVlbmNlcyBvZiBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBzZXBhcmF0ZWQK LSAgICAgICAgYnkgbm9uLWFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzOyB3aGVuIHVzaW5nIHRoZSBJ Q1UgbG9jYWxlIHByb3ZpZGVyLAotICAgICAgICB3b3JkcyBhcmUgc2VwYXJhdGVkIGFjY29yZGlu ZyB0bworICAgICAgICByZXN0IHRvIGxvd2VyIGNhc2UuIFdoZW4gdXNpbmcgdGhlIDxsaXRlcmFs PmxpYmM8L2xpdGVyYWw+IG9yCisgICAgICAgIDxsaXRlcmFsPiBidWlsdGluIDwvbGl0ZXJhbD4g bG9jYWxlIHByb3ZpZGVyLCB3b3JkcyBhcmUgc2VxdWVuY2VzCisgICAgICAgIG9mIGFscGhhbnVt ZXJpYyBjaGFyYWN0ZXJzIHNlcGFyYXRlZCBieSBub24tYWxwaGFudW1lcmljIGNoYXJhY3RlcnM7 CisgICAgICAgIHdoZW4gdXNpbmcgdGhlIElDVSBsb2NhbGUgcHJvdmlkZXIsIHdvcmRzIGFyZSBz ZXBhcmF0ZWQgYWNjb3JkaW5nIHRvCiAgICAgICAgIDx1bGluayB1cmw9Imh0dHBzOi8vd3d3LnVu aWNvZGUub3JnL3JlcG9ydHMvdHIyOS8jV29yZF9Cb3VuZGFyaWVzIj5Vbmljb2RlIFN0YW5kYXJk IEFubmV4ICMyOTwvdWxpbms+LgogICAgICAgIDwvcGFyYT4KKyAgICAgICA8cGFyYT4KKyAgICAg ICAgVGhpcyBmdW5jdGlvbiBpcyBwcmltYXJpbHkgdXNlZCBmb3IgY29udmVuaWVudAorICAgICAg ICBkaXNwbGF5LCBhbmQgdGhlIHNwZWNpZmljIHJlc3VsdCBzaG91bGQgbm90IGJlIHJlbGllZCB1 cG9uIGJlY2F1c2Ugb2YKKyAgICAgICAgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gbG9jYWxlIHBy b3ZpZGVycyBhbmQgYmV0d2VlbiBkaWZmZXJlbnQKKyAgICAgICAgSUNVIHZlcnNpb25zLiBJZiBz cGVjaWZpYyB3b3JkIGJvdW5kYXJ5IHJ1bGVzIGFyZSBkZXNpcmVkLAorICAgICAgICBpdCBpcyBy ZWNvbWVuZGVkIHRvIHdyaXRlIGEgY3VzdG9tIGZ1bmN0aW9uLgorICAgICAgIDwvcGFyYT4KICAg ICAgICA8cGFyYT4KICAgICAgICAgPGxpdGVyYWw+aW5pdGNhcCgnaGkgVEhPTUFTJyk8L2xpdGVy YWw+CiAgICAgICAgIDxyZXR1cm52YWx1ZT5IaSBUaG9tYXM8L3JldHVybnZhbHVlPgo= --=_48b9621db2b07ac69a6afe33b1d31271 Content-Transfer-Encoding: base64 Content-Type: text/x-diff; name=v2-0002-initcap-documentation.patch Content-Disposition: attachment; filename=v2-0002-initcap-documentation.patch; size=1213 ZGlmZiAtLWdpdCBhL2RvYy9zcmMvc2dtbC9mdW5jLnNnbWwgYi9kb2Mvc3JjL3NnbWwvZnVuYy5z Z21sCmluZGV4IDc0YTE2YWYwNGFkLi5jMDcxZDZkZjM2NiAxMDA2NDQKLS0tIGEvZG9jL3NyYy9z Z21sL2Z1bmMuc2dtbAorKysgYi9kb2Mvc3JjL3NnbWwvZnVuYy5zZ21sCkBAIC0zMTQ4LDExICsz MTQ4LDE0IEBAIFNFTEVDVCBOT1QoUk9XKHRhYmxlLiopIElTIE5PVCBOVUxMKSBGUk9NIFRBQkxF OyAtLSBkZXRlY3QgYXQgbGVhc3Qgb25lIG51bGwgaW4KICAgICAgICA8L3BhcmE+CiAgICAgICAg PHBhcmE+CiAgICAgICAgIENvbnZlcnRzIHRoZSBmaXJzdCBsZXR0ZXIgb2YgZWFjaCB3b3JkIHRv IHVwcGVyIGNhc2UgYW5kIHRoZQotICAgICAgICByZXN0IHRvIGxvd2VyIGNhc2UuIFdoZW4gdXNp bmcgdGhlIDxsaXRlcmFsPmxpYmM8L2xpdGVyYWw+IGxvY2FsZQotICAgICAgICBwcm92aWRlciwg d29yZHMgYXJlIHNlcXVlbmNlcyBvZiBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBzZXBhcmF0ZWQK LSAgICAgICAgYnkgbm9uLWFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzOyB3aGVuIHVzaW5nIHRoZSBJ Q1UgbG9jYWxlIHByb3ZpZGVyLAotICAgICAgICB3b3JkcyBhcmUgc2VwYXJhdGVkIGFjY29yZGlu ZyB0bwotICAgICAgICA8dWxpbmsgdXJsPSJodHRwczovL3d3dy51bmljb2RlLm9yZy9yZXBvcnRz L3RyMjkvI1dvcmRfQm91bmRhcmllcyI+VW5pY29kZSBTdGFuZGFyZCBBbm5leCAjMjk8L3VsaW5r Pi4KKyAgICAgICAgcmVzdCB0byBsb3dlciBjYXNlLgorICAgICAgIDwvcGFyYT4KKyAgICAgICA8 cGFyYT4KKyAgICAgICAgVGhpcyBmdW5jdGlvbiBpcyBwcmltYXJpbHkgdXNlZCBmb3IgY29udmVu aWVudAorICAgICAgICBkaXNwbGF5LCBhbmQgdGhlIHNwZWNpZmljIHJlc3VsdCBzaG91bGQgbm90 IGJlIHJlbGllZCB1cG9uIGJlY2F1c2Ugb2YKKyAgICAgICAgdGhlIGRpZmZlcmVuY2VzIGJldHdl ZW4gbG9jYWxlIHByb3ZpZGVycyBhbmQgYmV0d2VlbiBkaWZmZXJlbnQKKyAgICAgICAgSUNVIHZl cnNpb25zLiBJZiBzcGVjaWZpYyB3b3JkIGJvdW5kYXJ5IHJ1bGVzIGFyZSBkZXNpcmVkLAorICAg ICAgICBpdCBpcyByZWNvbWVuZGVkIHRvIHdyaXRlIGEgY3VzdG9tIGZ1bmN0aW9uLgogICAgICAg IDwvcGFyYT4KICAgICAgICA8cGFyYT4KICAgICAgICAgPGxpdGVyYWw+aW5pdGNhcCgnaGkgVEhP TUFTJyk8L2xpdGVyYWw+Cg== --=_48b9621db2b07ac69a6afe33b1d31271--