agora inbox for pgsql-docs@postgresql.org
help / color / mirror / Atom feedInitcap works differently with different locale providers
16+ messages / 4 participants
[nested] [flat]
* Initcap works differently with different locale providers
@ 2024-09-25 15:13 Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
0 siblings, 1 reply; 16+ messages in thread
From: Oleg Tselebrovskiy @ 2024-09-25 15:13 UTC (permalink / raw)
To: pgsql-docs@lists.postgresql.org
Greetings, everyone!
One of our clients has found a difference in behaviour of initcap
function when
using different locale providers, shown below
postgres=# create database test_db_1 locale_provider=icu
locale="ru_RU.UTF-8" template=template0;
NOTICE: using standard form "ru-RU" for ICU locale "ru_RU.UTF-8"
CREATE DATABASE
postgres=# \c test_db_1;
You are now connected to database "test_db_1" as user "postgres".
test_db_1=# select initcap('ЧиЮ А.Ю.');
initcap
----------
Чию А.ю.
(1 row)
test_db_1=# select initcap('joHn d.e.');
initcap
-----------
John D.e.
(1 row)
postgres=# create database test_db_2 locale_provider=libc
locale="ru_RU.UTF-8" template=template0;
CREATE DATABASE
postgres=# \c test_db_2
You are now connected to database "test_db_2" as user "postgres".
test_db_2=# select initcap('ЧиЮ А.Ю.');
initcap
----------
Чию А.Ю.
(1 row)
test_db_2=# select initcap('joHn d.e.');
initcap
-----------
John D.E.
(1 row)
And an easier reproduction (should work for REL_12_STABLE and up)
postgres=# SELECT initcap('first.second' COLLATE "en-x-icu");
initcap
--------------
First.second
(1 row)
postgres=# SELECT initcap('first.second' COLLATE "en_US");
initcap
--------------
First.Second
(1 row)
This behaviour is reproducible on REL_12_STABLE and up to master
I don't believe that this is an erroneous behaviour, just a differing
one, hence
just a documentation change proposition
I suggest adding a clarification that this function works differently
with libc
and ICU providers because there is a difference in what a "word" is
between them
In libc a word is a sequence of alphanumeric characters, separated by
non-alphanumeric characters (as it is written in documentation right
now)
In ICU words are divided according to Unicode® Standard Annex #29 [1]
Similar issue was briefly discussed in [2]
The suggested documentation patch is attached (versions for
REL_13_STABLE+ and
for REL_12_STABLE only)
[1]: https://www.unicode.org/reports/tr29/#Word_Boundaries
[2]:
https://www.postgresql.org/message-id/CAEwbS1R8pwhRkwRo3XsPt24ErBNtFWuReAZhVPJwA3oqo148tA%40mail.gma...
Oleg Tselebrovskiy, Postgres Professional
Attachments:
[text/x-diff] v1-0001-string-functions.patch (952B, ../../804cc10ef95d4d3b298e76b181fd9437@postgrespro.ru/2-v1-0001-string-functions.patch)
download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 1bde4091ca6..3ce5ad1d1f1 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -3100,8 +3100,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
</para>
<para>
Converts the first letter of each word to upper case and the
- rest to lower case. Words are sequences of alphanumeric
- characters separated by non-alphanumeric characters.
+ rest to lower case. When using the <literal>libc</literal> locale
+ provider, words are sequences of alphanumeric characters separated
+ by non-alphanumeric characters; when using the ICU locale provider,
+ words are separated according to
+ <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode® Standard Annex #29</ulink>.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
[text/x-diff] v1-0002-string-functions-REL_12.patch (931B, ../../804cc10ef95d4d3b298e76b181fd9437@postgrespro.ru/3-v1-0002-string-functions-REL_12.patch)
download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 487bb103637..1cd281dd90b 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1932,8 +1932,11 @@
<entry><type>text</type></entry>
<entry>
Convert the first letter of each word to upper case and the
- rest to lower case. Words are sequences of alphanumeric
- characters separated by non-alphanumeric characters.
+ rest to lower case. When using the <literal>libc</literal> locale
+ provider, words are sequences of alphanumeric characters separated
+ by non-alphanumeric characters; when using the ICU locale provider,
+ words are separated according to
+ <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode® Standard Annex #29</ulink>.
</entry>
<entry><literal>initcap('hi THOMAS')</literal></entry>
<entry><literal>Hi Thomas</literal></entry>
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-07-28 10:20 Alexander Korotkov <aekorotkov@gmail.com>
parent: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
0 siblings, 2 replies; 16+ messages in thread
From: Alexander Korotkov @ 2025-07-28 10:20 UTC (permalink / raw)
To: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; +Cc: pgsql-docs@lists.postgresql.org
Hi, Oleg!
> On 25 Sep 2024, at 18:13, Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> wrote:
>
> Greetings, everyone!
>
> One of our clients has found a difference in behaviour of initcap function when
> using different locale providers, shown below
>
> postgres=# create database test_db_1 locale_provider=icu locale="ru_RU.UTF-8" template=template0;
> NOTICE: using standard form "ru-RU" for ICU locale "ru_RU.UTF-8"
> CREATE DATABASE
> postgres=# \c test_db_1;
> You are now connected to database "test_db_1" as user "postgres".
> test_db_1=# select initcap('ЧиЮ А.Ю.');
> initcap
> ----------
> Чию А.ю.
> (1 row)
> test_db_1=# select initcap('joHn d.e.');
> initcap
> -----------
> John D.e.
> (1 row)
> postgres=# create database test_db_2 locale_provider=libc locale="ru_RU.UTF-8" template=template0;
> CREATE DATABASE
> postgres=# \c test_db_2
> You are now connected to database "test_db_2" as user "postgres".
> test_db_2=# select initcap('ЧиЮ А.Ю.');
> initcap
> ----------
> Чию А.Ю.
> (1 row)
> test_db_2=# select initcap('joHn d.e.');
> initcap
> -----------
> John D.E.
> (1 row)
>
> And an easier reproduction (should work for REL_12_STABLE and up)
>
> postgres=# SELECT initcap('first.second' COLLATE "en-x-icu");
> initcap
> --------------
> First.second
> (1 row)
> postgres=# SELECT initcap('first.second' COLLATE "en_US");
> initcap
> --------------
> First.Second
> (1 row)
>
> This behaviour is reproducible on REL_12_STABLE and up to master
>
> I don't believe that this is an erroneous behaviour, just a differing one, hence
> just a documentation change proposition
>
> I suggest adding a clarification that this function works differently with libc
> and ICU providers because there is a difference in what a "word" is between them
>
> In libc a word is a sequence of alphanumeric characters, separated by
> non-alphanumeric characters (as it is written in documentation right now)
> In ICU words are divided according to Unicode® Standard Annex #29 [1]
>
> Similar issue was briefly discussed in [2]
>
> The suggested documentation patch is attached (versions for REL_13_STABLE+ and
> for REL_12_STABLE only)
>
> [1]: https://www.unicode.org/reports/tr29/#Word_Boundaries
> [2]: https://www.postgresql.org/message-id/CAEwbS1R8pwhRkwRo3XsPt24ErBNtFWuReAZhVPJwA3oqo148tA%40mail.gma...
>
> Oleg Tselebrovskiy, Postgres Professional<v1-0001-string-functions.patch><v1-0002-string-functions-REL_12.patch>
I can confirm inicap works with libc and libicu as you stated. The documentation patch looks good to me. I’ve written a commit message. The REL_12_STABLE branch is not relevant anymore as it’s out of support. I’m going to push this if no objections.
------
Regards,
Alexander Korotkov
Supabase
=
Attachments:
[application/octet-stream] v2-0001-Clarify-documentation-for-the-initcap-function.patch (1.6K, ../../0658C8F0-5ED4-4962-A2A3-524B0D899982@gmail.com/3-v2-0001-Clarify-documentation-for-the-initcap-function.patch)
download | inline diff:
From 1e6631804d6e56003dd1c7ed04458bd3d6f7b9f3 Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Mon, 28 Jul 2025 13:06:26 +0300
Subject: [PATCH v2] Clarify documentation for the initcap function
This commit documents differences in the definition of word separators for
the initcap function between libc and ICU locale providers.
Backpatch to all supported branches.
Discussion: https://postgr.es/m/804cc10ef95d4d3b298e76b181fd9437%40postgrespro.ru
Author: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
Backpatch-through: 13
---
doc/src/sgml/func.sgml | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index de5b5929ee0..64ce2b448e6 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -3148,8 +3148,11 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
</para>
<para>
Converts the first letter of each word to upper case and the
- rest to lower case. Words are sequences of alphanumeric
- characters separated by non-alphanumeric characters.
+ rest to lower case. When using the <literal>libc</literal> locale
+ provider, words are sequences of alphanumeric characters separated
+ by non-alphanumeric characters; when using the ICU locale provider,
+ words are separated according to
+ <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode® Standard Annex #29</ulink>.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
--
2.39.5 (Apple Git-154)
=
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-07-28 10:23 Alexander Korotkov <aekorotkov@gmail.com>
parent: Alexander Korotkov <aekorotkov@gmail.com>
1 sibling, 1 reply; 16+ messages in thread
From: Alexander Korotkov @ 2025-07-28 10:23 UTC (permalink / raw)
To: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; +Cc: pgsql-docs@lists.postgresql.org
On Mon, Jul 28, 2025 at 1:20 PM Alexander Korotkov <aekorotkov@gmail.com> wrote:
>
> On 25 Sep 2024, at 18:13, Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> wrote:
>
> Greetings, everyone!
>
> One of our clients has found a difference in behaviour of initcap function when
> using different locale providers, shown below
>
> postgres=# create database test_db_1 locale_provider=icu locale="ru_RU.UTF-8" template=template0;
> NOTICE: using standard form "ru-RU" for ICU locale "ru_RU.UTF-8"
> CREATE DATABASE
> postgres=# \c test_db_1;
> You are now connected to database "test_db_1" as user "postgres".
> test_db_1=# select initcap('ЧиЮ А.Ю.');
> initcap
> ----------
> Чию А.ю.
> (1 row)
> test_db_1=# select initcap('joHn d.e.');
> initcap
> -----------
> John D.e.
> (1 row)
> postgres=# create database test_db_2 locale_provider=libc locale="ru_RU.UTF-8" template=template0;
> CREATE DATABASE
> postgres=# \c test_db_2
> You are now connected to database "test_db_2" as user "postgres".
> test_db_2=# select initcap('ЧиЮ А.Ю.');
> initcap
> ----------
> Чию А.Ю.
> (1 row)
> test_db_2=# select initcap('joHn d.e.');
> initcap
> -----------
> John D.E.
> (1 row)
>
> And an easier reproduction (should work for REL_12_STABLE and up)
>
> postgres=# SELECT initcap('first.second' COLLATE "en-x-icu");
> initcap
> --------------
> First.second
> (1 row)
> postgres=# SELECT initcap('first.second' COLLATE "en_US");
> initcap
> --------------
> First.Second
> (1 row)
>
> This behaviour is reproducible on REL_12_STABLE and up to master
>
> I don't believe that this is an erroneous behaviour, just a differing one, hence
> just a documentation change proposition
>
> I suggest adding a clarification that this function works differently with libc
> and ICU providers because there is a difference in what a "word" is between them
>
> In libc a word is a sequence of alphanumeric characters, separated by
> non-alphanumeric characters (as it is written in documentation right now)
> In ICU words are divided according to Unicode® Standard Annex #29 [1]
>
> Similar issue was briefly discussed in [2]
>
> The suggested documentation patch is attached (versions for REL_13_STABLE+ and
> for REL_12_STABLE only)
>
> [1]: https://www.unicode.org/reports/tr29/#Word_Boundaries
> [2]: https://www.postgresql.org/message-id/CAEwbS1R8pwhRkwRo3XsPt24ErBNtFWuReAZhVPJwA3oqo148tA%40mail.gma...
>
> Oleg Tselebrovskiy, Postgres Professional<v1-0001-string-functions.patch><v1-0002-string-functions-REL_12.patch>
>
>
> I can confirm inicap works with libc and libicu as you stated. The documentation patch looks good to me. I’ve written a commit message. The REL_12_STABLE branch is not relevant anymore as it’s out of support. I’m going to push this if no objections.
I'm sorry for these many messages. My email client just gone crazy.
Must be fixed now.
------
Regards,
Alexander Korotkov
Supabase
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-07-29 04:03 Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
parent: Alexander Korotkov <aekorotkov@gmail.com>
0 siblings, 0 replies; 16+ messages in thread
From: Oleg Tselebrovskiy @ 2025-07-29 04:03 UTC (permalink / raw)
To: Alexander Korotkov <aekorotkov@gmail.com>; +Cc: pgsql-docs@lists.postgresql.org
Alexander Korotkov wrote at 2025-07-28 17:23:
> On Mon, Jul 28, 2025 at 1:20 PM Alexander Korotkov
> <aekorotkov@gmail.com> wrote:
>>
>> On 25 Sep 2024, at 18:13, Oleg Tselebrovskiy
>> <o.tselebrovskiy@postgrespro.ru> wrote:
>>
>> Greetings, everyone!
>>
>> One of our clients has found a difference in behaviour of initcap
>> function when
>> using different locale providers, shown below
>>
>> postgres=# create database test_db_1 locale_provider=icu
>> locale="ru_RU.UTF-8" template=template0;
>> NOTICE: using standard form "ru-RU" for ICU locale "ru_RU.UTF-8"
>> CREATE DATABASE
>> postgres=# \c test_db_1;
>> You are now connected to database "test_db_1" as user "postgres".
>> test_db_1=# select initcap('ЧиЮ А.Ю.');
>> initcap
>> ----------
>> Чию А.ю.
>> (1 row)
>> test_db_1=# select initcap('joHn d.e.');
>> initcap
>> -----------
>> John D.e.
>> (1 row)
>> postgres=# create database test_db_2 locale_provider=libc
>> locale="ru_RU.UTF-8" template=template0;
>> CREATE DATABASE
>> postgres=# \c test_db_2
>> You are now connected to database "test_db_2" as user "postgres".
>> test_db_2=# select initcap('ЧиЮ А.Ю.');
>> initcap
>> ----------
>> Чию А.Ю.
>> (1 row)
>> test_db_2=# select initcap('joHn d.e.');
>> initcap
>> -----------
>> John D.E.
>> (1 row)
>>
>> And an easier reproduction (should work for REL_12_STABLE and up)
>>
>> postgres=# SELECT initcap('first.second' COLLATE "en-x-icu");
>> initcap
>> --------------
>> First.second
>> (1 row)
>> postgres=# SELECT initcap('first.second' COLLATE "en_US");
>> initcap
>> --------------
>> First.Second
>> (1 row)
>>
>> This behaviour is reproducible on REL_12_STABLE and up to master
>>
>> I don't believe that this is an erroneous behaviour, just a differing
>> one, hence
>> just a documentation change proposition
>>
>> I suggest adding a clarification that this function works differently
>> with libc
>> and ICU providers because there is a difference in what a "word" is
>> between them
>>
>> In libc a word is a sequence of alphanumeric characters, separated by
>> non-alphanumeric characters (as it is written in documentation right
>> now)
>> In ICU words are divided according to Unicode® Standard Annex #29 [1]
>>
>> Similar issue was briefly discussed in [2]
>>
>> The suggested documentation patch is attached (versions for
>> REL_13_STABLE+ and
>> for REL_12_STABLE only)
>>
>> [1]: https://www.unicode.org/reports/tr29/#Word_Boundaries
>> [2]:
>> https://www.postgresql.org/message-id/CAEwbS1R8pwhRkwRo3XsPt24ErBNtFWuReAZhVPJwA3oqo148tA%40mail.gma...
>>
>> Oleg Tselebrovskiy, Postgres
>> Professional<v1-0001-string-functions.patch><v1-0002-string-functions-REL_12.patch>
>>
>>
>> I can confirm inicap works with libc and libicu as you stated. The
>> documentation patch looks good to me. I’ve written a commit message.
>> The REL_12_STABLE branch is not relevant anymore as it’s out of
>> support. I’m going to push this if no objections.
>
> I'm sorry for these many messages. My email client just gone crazy.
> Must be fixed now.
>
> ------
> Regards,
> Alexander Korotkov
> Supabase
Commit message looks good to me, also no objections on ignoring
REL_12_STABLE :)
Thank you!
Regards, Oleg Tselebrovskiy
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-07-30 19:58 Jeff Davis <pgsql@j-davis.com>
parent: Alexander Korotkov <aekorotkov@gmail.com>
1 sibling, 2 replies; 16+ messages in thread
From: Jeff Davis @ 2025-07-30 19:58 UTC (permalink / raw)
To: Alexander Korotkov <aekorotkov@gmail.com>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; +Cc: pgsql-docs@lists.postgresql.org
On Mon, 2025-07-28 at 13:20 +0300, Alexander Korotkov wrote:
> I can confirm inicap works with libc and libicu as you stated. The
> documentation patch looks good to me. I’ve written a commit message.
> The REL_12_STABLE branch is not relevant anymore as it’s out of
> support. I’m going to push this if no objections.
Apologies for the late review.
First, it doesn't mention the "builtin" provider, which uses the same
word break rules as libc.
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.[1], and I'm not sure exactly
which one of those we use.
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.
Regards,
Jeff Davis
[1]
https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/stringoptions_8h.html#a4975f537b9960f0330b23...
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-04 05:30 Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
parent: Jeff Davis <pgsql@j-davis.com>
1 sibling, 1 reply; 16+ messages in thread
From: Oleg Tselebrovskiy @ 2025-08-04 05:30 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; +Cc: Alexander Korotkov <aekorotkov@gmail.com>; pgsql-docs@lists.postgresql.org
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
Attachments:
[text/x-diff] v2-0001-initcap-documentation.patch (1.5K, ../../cdfa64230784d7e330c1a2a55237b94e@postgrespro.ru/2-v2-0001-initcap-documentation.patch)
download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 74a16af04ad..8a44e0ae593 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -3148,12 +3148,19 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
</para>
<para>
Converts the first letter of each word to upper case and the
- rest to lower case. When using the <literal>libc</literal> locale
- provider, words are sequences of alphanumeric characters separated
- by non-alphanumeric characters; when using the ICU locale provider,
- words are separated according to
+ rest to lower case. When using the <literal>libc</literal> or
+ <literal> builtin </literal> locale provider, words are sequences
+ of alphanumeric characters separated by non-alphanumeric characters;
+ when using the ICU locale provider, words are separated according to
<ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard Annex #29</ulink>.
</para>
+ <para>
+ This function is primarily used for convenient
+ display, and the specific result should not be relied upon because of
+ the differences between locale providers and between different
+ ICU versions. If specific word boundary rules are desired,
+ it is recomended to write a custom function.
+ </para>
<para>
<literal>initcap('hi THOMAS')</literal>
<returnvalue>Hi Thomas</returnvalue>
[text/x-diff] v2-0002-initcap-documentation.patch (1.2K, ../../cdfa64230784d7e330c1a2a55237b94e@postgrespro.ru/3-v2-0002-initcap-documentation.patch)
download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 74a16af04ad..c071d6df366 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -3148,11 +3148,14 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
</para>
<para>
Converts the first letter of each word to upper case and the
- rest to lower case. When using the <literal>libc</literal> locale
- provider, words are sequences of alphanumeric characters separated
- by non-alphanumeric characters; when using the ICU locale provider,
- words are separated according to
- <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard Annex #29</ulink>.
+ rest to lower case.
+ </para>
+ <para>
+ This function is primarily used for convenient
+ display, and the specific result should not be relied upon because of
+ the differences between locale providers and between different
+ ICU versions. If specific word boundary rules are desired,
+ it is recomended to write a custom function.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-04 20:59 Jeff Davis <pgsql@j-davis.com>
parent: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
0 siblings, 2 replies; 16+ messages in thread
From: Jeff Davis @ 2025-08-04 20:59 UTC (permalink / raw)
To: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; +Cc: Alexander Korotkov <aekorotkov@gmail.com>; pgsql-docs@lists.postgresql.org
On Mon, 2025-08-04 at 12:30 +0700, Oleg Tselebrovskiy wrote:
> 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
One more thing: we should also change it to "... to upper case (or
title case) and the rest to lower case...". Title case is for scripts
that have characters like 'Dž' (U+01C5).
Other than that I like the second version, which un-documents the
specific word boundary rules. I'll admit I'm not quite sure how people
use this function in practice, but I expect that it's mostly convenient
(or lazy) display.
Alexander, is there a reason you backported this change? I don't
normally backport doc improvements like this, but I'm not sure what
standard others use. The fact that it's on 7 branches makes me more
reluctant to commit these extra improvements on top. Can you take care
of these follow-up patches? Or, just revert the change and I can make
the improvements in master.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-05 09:01 Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
parent: Jeff Davis <pgsql@j-davis.com>
1 sibling, 0 replies; 16+ messages in thread
From: Oleg Tselebrovskiy @ 2025-08-05 09:01 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; +Cc: Alexander Korotkov <aekorotkov@gmail.com>; pgsql-docs@lists.postgresql.org
Jeff Davis wrote at 2025-08-05 03:59:
> One more thing: we should also change it to "... to upper case (or
> title case) and the rest to lower case...". Title case is for scripts
> that have characters like 'Dž' (U+01C5).
Done based upon second version of previous patch. Again, there are two
versions - the first one has a mention of digraphs, like 'Dž' (U+01C5),
and the second one doesn't. And again, don't know which version is
better - title case without mentioning digraphs could be interpreted
as "don't capitalise articles and prepositions" or just "don't
capitalize articles", since the definition of "title case" is vague.
We have a "write your own function" clause, but still.
Maybe we should add an example of a digraph to the first patch to
make it more clear, if we go that path.
Attachments:
[text/x-diff] v3-0001-initcap-documentation.patch (1.3K, ../../31964db3672feeb6a527d8f7191d48e1@postgrespro.ru/2-v3-0001-initcap-documentation.patch)
download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 74a16af04ad..b32ec6e2cea 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -3147,12 +3147,15 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
<returnvalue>text</returnvalue>
</para>
<para>
- Converts the first letter of each word to upper case and the
- rest to lower case. When using the <literal>libc</literal> locale
- provider, words are sequences of alphanumeric characters separated
- by non-alphanumeric characters; when using the ICU locale provider,
- words are separated according to
- <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard Annex #29</ulink>.
+ Converts the first letter of each word to upper case (or title case
+ if the letter is a digraph) and the rest to lower case.
+ </para>
+ <para>
+ This function is primarily used for convenient
+ display, and the specific result should not be relied upon because of
+ the differences between locale providers and between different
+ ICU versions. If specific word boundary rules are desired,
+ it is recomended to write a custom function.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
[text/x-diff] v3-0002-initcap-documentation.patch (1.3K, ../../31964db3672feeb6a527d8f7191d48e1@postgrespro.ru/3-v3-0002-initcap-documentation.patch)
download | inline diff:
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 74a16af04ad..f799b34dca7 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -3147,12 +3147,15 @@ SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in
<returnvalue>text</returnvalue>
</para>
<para>
- Converts the first letter of each word to upper case and the
- rest to lower case. When using the <literal>libc</literal> locale
- provider, words are sequences of alphanumeric characters separated
- by non-alphanumeric characters; when using the ICU locale provider,
- words are separated according to
- <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard Annex #29</ulink>.
+ Converts the first letter of each word to upper case (or title case)
+ and the rest to lower case.
+ </para>
+ <para>
+ This function is primarily used for convenient
+ display, and the specific result should not be relied upon because of
+ the differences between locale providers and between different
+ ICU versions. If specific word boundary rules are desired,
+ it is recomended to write a custom function.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-06 11:44 Peter Eisentraut <peter@eisentraut.org>
parent: Jeff Davis <pgsql@j-davis.com>
1 sibling, 2 replies; 16+ messages in thread
From: Peter Eisentraut @ 2025-08-06 11:44 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; +Cc: Alexander Korotkov <aekorotkov@gmail.com>; pgsql-docs@lists.postgresql.org
On 04.08.25 22:59, Jeff Davis wrote:
> On Mon, 2025-08-04 at 12:30 +0700, Oleg Tselebrovskiy wrote:
>> 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
>
> One more thing: we should also change it to "... to upper case (or
> title case) and the rest to lower case...". Title case is for scripts
> that have characters like 'Dž' (U+01C5).
>
> Other than that I like the second version, which un-documents the
> specific word boundary rules. I'll admit I'm not quite sure how people
> use this function in practice, but I expect that it's mostly convenient
> (or lazy) display.
It's meant to be an Oracle-compatible function, so maybe someone can
check there for some details.
https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/INITCAP.html
I think we should try to document the behavior more precisely. But we
probably first have to agree what it should be.
> Alexander, is there a reason you backported this change? I don't
> normally backport doc improvements like this, but I'm not sure what
> standard others use. The fact that it's on 7 branches makes me more
> reluctant to commit these extra improvements on top. Can you take care
> of these follow-up patches? Or, just revert the change and I can make
> the improvements in master.
Yes, I was not in favor of backpatching this, since it was not a bug
fix. And it turns out it was incomplete. I think we should revert all
the backpatches and iterate on getting the documentation the way we want
in master.
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-06 14:13 Alexander Korotkov <aekorotkov@gmail.com>
parent: Peter Eisentraut <peter@eisentraut.org>
1 sibling, 0 replies; 16+ messages in thread
From: Alexander Korotkov @ 2025-08-06 14:13 UTC (permalink / raw)
To: Peter Eisentraut <peter@eisentraut.org>; +Cc: Jeff Davis <pgsql@j-davis.com>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; pgsql-docs@lists.postgresql.org
On Wed, Aug 6, 2025 at 2:44 PM Peter Eisentraut <peter@eisentraut.org> wrote:
>
> On 04.08.25 22:59, Jeff Davis wrote:
> > On Mon, 2025-08-04 at 12:30 +0700, Oleg Tselebrovskiy wrote:
> >> 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
> >
> > One more thing: we should also change it to "... to upper case (or
> > title case) and the rest to lower case...". Title case is for scripts
> > that have characters like 'Dž' (U+01C5).
> >
> > Other than that I like the second version, which un-documents the
> > specific word boundary rules. I'll admit I'm not quite sure how people
> > use this function in practice, but I expect that it's mostly convenient
> > (or lazy) display.
>
> It's meant to be an Oracle-compatible function, so maybe someone can
> check there for some details.
>
> https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/INITCAP.html
>
> I think we should try to document the behavior more precisely. But we
> probably first have to agree what it should be.
>
> > Alexander, is there a reason you backported this change? I don't
> > normally backport doc improvements like this, but I'm not sure what
> > standard others use. The fact that it's on 7 branches makes me more
> > reluctant to commit these extra improvements on top. Can you take care
> > of these follow-up patches? Or, just revert the change and I can make
> > the improvements in master.
>
> Yes, I was not in favor of backpatching this, since it was not a bug
> fix. And it turns out it was incomplete. I think we should revert all
> the backpatches and iterate on getting the documentation the way we want
> in master.
Got it. Sorry for the confusion. I'll revert patches from back
branches and then continue to work on the subject for master.
------
Regards,
Alexander Korotkov
Supabase
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-06 18:21 Jeff Davis <pgsql@j-davis.com>
parent: Peter Eisentraut <peter@eisentraut.org>
1 sibling, 2 replies; 16+ messages in thread
From: Jeff Davis @ 2025-08-06 18:21 UTC (permalink / raw)
To: Peter Eisentraut <peter@eisentraut.org>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; +Cc: Alexander Korotkov <aekorotkov@gmail.com>; pgsql-docs@lists.postgresql.org
On Wed, 2025-08-06 at 13:44 +0200, Peter Eisentraut wrote:
> It's meant to be an Oracle-compatible function, so maybe someone can
> check there for some details.
If it's purely a compatibility function, then using ICU's sophisticated
word break iterator doesn't make sense.
> https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/INITCAP.html
>
> I think we should try to document the behavior more precisely.
I don't think ICU purely follows Unicode on this point (does it?), so
we'd have to point to the ICU documentation.
> But we
> probably first have to agree what it should be.
I still don't fully understand the use case here. I've used the
function a few times to assemble a few strings into a page heading, but
that was some time ago so I don't even clearly remember my use case. It
seems plausible there are quite a few people doing something similar,
and they'd benefit from ICU's more sophisticated approach.
But if the primary use case is for compatibility, then we might be
trying to hard to make this a provider-specific feature.
>
> Yes, I was not in favor of backpatching this, since it was not a bug
> fix. And it turns out it was incomplete. I think we should revert
> all
> the backpatches and iterate on getting the documentation the way we
> want
> in master.
+1.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-07 13:11 Alexander Korotkov <aekorotkov@gmail.com>
parent: Jeff Davis <pgsql@j-davis.com>
1 sibling, 0 replies; 16+ messages in thread
From: Alexander Korotkov @ 2025-08-07 13:11 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; +Cc: Peter Eisentraut <peter@eisentraut.org>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; pgsql-docs@lists.postgresql.org
On Wed, Aug 6, 2025 at 9:21 PM Jeff Davis <pgsql@j-davis.com> wrote:
> > Yes, I was not in favor of backpatching this, since it was not a bug
> > fix. And it turns out it was incomplete. I think we should revert
> > all
> > the backpatches and iterate on getting the documentation the way we
> > want
> > in master.
>
> +1.
Done, reverted everywhere except master.
------
Regards,
Alexander Korotkov
Supabase
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-16 21:29 Alexander Korotkov <aekorotkov@gmail.com>
parent: Jeff Davis <pgsql@j-davis.com>
1 sibling, 0 replies; 16+ messages in thread
From: Alexander Korotkov @ 2025-08-16 21:29 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; +Cc: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; pgsql-docs@lists.postgresql.org
On Wed, Jul 30, 2025 at 10:58 PM Jeff Davis <pgsql@j-davis.com> wrote:
>
> On Mon, 2025-07-28 at 13:20 +0300, Alexander Korotkov wrote:
> > I can confirm inicap works with libc and libicu as you stated. The
> > documentation patch looks good to me. I’ve written a commit message.
> > The REL_12_STABLE branch is not relevant anymore as it’s out of
> > support. I’m going to push this if no objections.
>
> Apologies for the late review.
>
> First, it doesn't mention the "builtin" provider, which uses the same
> word break rules as libc.
>
> 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.[1], and I'm not sure exactly
> which one of those we use.
I think none of these options is used, because options could be
processed by ucasemap_toTitle() [1] while we use u_strToTitle() [2]
which takes no options.
Links
1. https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/ucasemap_8h.html#aa49d8b403bd91c52f127fe8067...
2. https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/ustring_8h.html#a47602e2c2012d77ee91908b9bbf...
------
Regards,
Alexander Korotkov
Supabase
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-17 21:44 Alexander Korotkov <aekorotkov@gmail.com>
parent: Jeff Davis <pgsql@j-davis.com>
1 sibling, 1 reply; 16+ messages in thread
From: Alexander Korotkov @ 2025-08-17 21:44 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; +Cc: Peter Eisentraut <peter@eisentraut.org>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; pgsql-docs@lists.postgresql.org
On Wed, Aug 6, 2025 at 9:21 PM Jeff Davis <pgsql@j-davis.com> wrote:
>
> On Wed, 2025-08-06 at 13:44 +0200, Peter Eisentraut wrote:
> > It's meant to be an Oracle-compatible function, so maybe someone can
> > check there for some details.
>
> If it's purely a compatibility function, then using ICU's sophisticated
> word break iterator doesn't make sense.
>
> > https://docs.oracle.com/en/database/oracle/oracle-database/18/sqlrf/INITCAP.html
> >
> > I think we should try to document the behavior more precisely.
>
> I don't think ICU purely follows Unicode on this point (does it?), so
> we'd have to point to the ICU documentation.
>
> > But we
> > probably first have to agree what it should be.
>
> I still don't fully understand the use case here. I've used the
> function a few times to assemble a few strings into a page heading, but
> that was some time ago so I don't even clearly remember my use case. It
> seems plausible there are quite a few people doing something similar,
> and they'd benefit from ICU's more sophisticated approach.
>
> But if the primary use case is for compatibility, then we might be
> trying to hard to make this a provider-specific feature.
I'd like to propose a new version of patch. It includes specification
of behavior for each locale provider including particular ICU
function. Also it saves the note from upthread that initcap() is
intended for display convenience. What do you think about that?
------
Regards,
Alexander Korotkov
Supabase
Attachments:
[application/octet-stream] v4-0001-Further-clarify-documentation-for-the-initcap-fun.patch (2.2K, ../../CAPpHfdvC2-kekJKi6L3+ZngBS2WFoTaAcxZ8ymSEd8UXakY+cg@mail.gmail.com/2-v4-0001-Further-clarify-documentation-for-the-initcap-fun.patch)
download | inline diff:
From 5204faf8187f9c9c52ed6d7e0417422a6cfa78db Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Mon, 18 Aug 2025 00:40:05 +0300
Subject: [PATCH v4] Further clarify documentation for the initcap function
* Document that title case is used for digraphs
* Reference particular ICU function used
* Add note about purpose of the function
---
doc/src/sgml/func/func-string.sgml | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/doc/src/sgml/func/func-string.sgml b/doc/src/sgml/func/func-string.sgml
index 3eec93eb339..022b9f3c4cf 100644
--- a/doc/src/sgml/func/func-string.sgml
+++ b/doc/src/sgml/func/func-string.sgml
@@ -693,12 +693,19 @@
<returnvalue>text</returnvalue>
</para>
<para>
- Converts the first letter of each word to upper case and the
- rest to lower case. When using the <literal>libc</literal> locale
- provider, words are sequences of alphanumeric characters separated
- by non-alphanumeric characters; when using the ICU locale provider,
- words are separated according to
- <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard Annex #29</ulink>.
+ Converts the first letter of each word to upper case (or title case
+ if the letter is a digraph) and the rest to lower case. When using
+ the <literal>libc</literal> or <literal>builtin</literal> locale
+ provider, words are sequences of alphanumeric characters separated by non-alphanumeric characters;
+ when using the ICU locale provider, words are separated according to
+ <ulink url="https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/ustring_8h.html#a47602e2c2012d77ee91908b9bbfdc063">u_strToTitle ICU function</ulink>.
+ </para>
+ <para>
+ This function is primarily used for convenient
+ display, and the specific result should not be relied upon because of
+ the differences between locale providers and between different
+ ICU versions. If specific word boundary rules are desired,
+ it is recommended to write a custom function.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
--
2.39.5 (Apple Git-154)
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-20 21:55 Jeff Davis <pgsql@j-davis.com>
parent: Alexander Korotkov <aekorotkov@gmail.com>
0 siblings, 1 reply; 16+ messages in thread
From: Jeff Davis @ 2025-08-20 21:55 UTC (permalink / raw)
To: Alexander Korotkov <aekorotkov@gmail.com>; +Cc: Peter Eisentraut <peter@eisentraut.org>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; pgsql-docs@lists.postgresql.org
On Mon, 2025-08-18 at 00:44 +0300, Alexander Korotkov wrote:
> I'd like to propose a new version of patch.
Nit: it only uses the title case in ICU or builtin PG_UNICODE_FAST.
Regards,
Jeff Davis
^ permalink raw reply [nested|flat] 16+ messages in thread
* Re: Initcap works differently with different locale providers
@ 2025-08-24 09:48 Alexander Korotkov <aekorotkov@gmail.com>
parent: Jeff Davis <pgsql@j-davis.com>
0 siblings, 0 replies; 16+ messages in thread
From: Alexander Korotkov @ 2025-08-24 09:48 UTC (permalink / raw)
To: Jeff Davis <pgsql@j-davis.com>; +Cc: Peter Eisentraut <peter@eisentraut.org>; Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>; pgsql-docs@lists.postgresql.org
On Thu, Aug 21, 2025 at 12:55 AM Jeff Davis <pgsql@j-davis.com> wrote:
> On Mon, 2025-08-18 at 00:44 +0300, Alexander Korotkov wrote:
> > I'd like to propose a new version of patch.
>
> Nit: it only uses the title case in ICU or builtin PG_UNICODE_FAST.
Corrected, thank you. Any objections if I push this?
------
Regards,
Alexander Korotkov
Supabase
Attachments:
[application/octet-stream] v5-0001-Further-clarify-documentation-for-the-initcap-fun.patch (2.8K, ../../CAPpHfdte35bAUNw69S-FRQb5paEYhF8XnXSiD+W3qTSDZX=VvA@mail.gmail.com/2-v5-0001-Further-clarify-documentation-for-the-initcap-fun.patch)
download | inline diff:
From 2922f372e0ab400bc744ef90ac89ee04bed239db Mon Sep 17 00:00:00 2001
From: Alexander Korotkov <akorotkov@postgresql.org>
Date: Mon, 18 Aug 2025 00:40:05 +0300
Subject: [PATCH v5] Further clarify documentation for the initcap function
This is a follow-up for commit c2c2c7e225. It further clarifies the
following in the initcap function documentation:
* Document that title case is used for digraphs in specific locales,
* Reference particular ICU function used,
* Add note about the purpose of the function.
Discussion: https://postgr.es/m/804cc10ef95d4d3b298e76b181fd9437%40postgrespro.ru
Author: Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
Co-authored-by: Alexander Korotkov <aekorotkov@gmail.com>
Reviewed-by: Jeff Davis <pgsql@j-davis.com>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
---
doc/src/sgml/func/func-string.sgml | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/doc/src/sgml/func/func-string.sgml b/doc/src/sgml/func/func-string.sgml
index 3eec93eb339..01cc94c234e 100644
--- a/doc/src/sgml/func/func-string.sgml
+++ b/doc/src/sgml/func/func-string.sgml
@@ -693,12 +693,21 @@
<returnvalue>text</returnvalue>
</para>
<para>
- Converts the first letter of each word to upper case and the
- rest to lower case. When using the <literal>libc</literal> locale
- provider, words are sequences of alphanumeric characters separated
- by non-alphanumeric characters; when using the ICU locale provider,
- words are separated according to
- <ulink url="https://www.unicode.org/reports/tr29/#Word_Boundaries">Unicode Standard Annex #29</ulink>.
+ Converts the first letter of each word to upper case (or title case
+ if the letter is a digraph and locale is <literal>ICU</literal> or
+ <literal>builtin</literal> <literal>PG_UNICODE_FAST</literal>)
+ and the rest to lower case. When using the <literal>libc</literal> or
+ <literal>builtin</literal> locale provider, words are sequences of
+ alphanumeric characters separated by non-alphanumeric characters;
+ when using the ICU locale provider, words are separated according to
+ <ulink url="https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/ustring_8h.html#a47602e2c2012d77ee91908b9bbfdc063">u_strToTitle ICU function</ulink>.
+ </para>
+ <para>
+ This function is primarily used for convenient
+ display, and the specific result should not be relied upon because of
+ the differences between locale providers and between different
+ ICU versions. If specific word boundary rules are desired,
+ it is recommended to write a custom function.
</para>
<para>
<literal>initcap('hi THOMAS')</literal>
--
2.39.5 (Apple Git-154)
^ permalink raw reply [nested|flat] 16+ messages in thread
end of thread, other threads:[~2025-08-24 09:48 UTC | newest]
Thread overview: 16+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-09-25 15:13 Initcap works differently with different locale providers Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
2025-07-28 10:20 ` Alexander Korotkov <aekorotkov@gmail.com>
2025-07-28 10:23 ` Alexander Korotkov <aekorotkov@gmail.com>
2025-07-29 04:03 ` Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
2025-07-30 19:58 ` Jeff Davis <pgsql@j-davis.com>
2025-08-04 05:30 ` Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
2025-08-04 20:59 ` Jeff Davis <pgsql@j-davis.com>
2025-08-05 09:01 ` Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru>
2025-08-06 11:44 ` Peter Eisentraut <peter@eisentraut.org>
2025-08-06 14:13 ` Alexander Korotkov <aekorotkov@gmail.com>
2025-08-06 18:21 ` Jeff Davis <pgsql@j-davis.com>
2025-08-07 13:11 ` Alexander Korotkov <aekorotkov@gmail.com>
2025-08-17 21:44 ` Alexander Korotkov <aekorotkov@gmail.com>
2025-08-20 21:55 ` Jeff Davis <pgsql@j-davis.com>
2025-08-24 09:48 ` Alexander Korotkov <aekorotkov@gmail.com>
2025-08-16 21:29 ` Alexander Korotkov <aekorotkov@gmail.com>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox