Crash issue in PG18.5 regression

Started by Masashi Kamura (Fujitsu)13 days ago17 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253371
psql -h localhost -U postgres

Built from patchset v17 (message #17), August 23, 2026 at 07:03 PM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253371_17 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253371_17 && git checkout t253371_17

Patchset v17 (message #17) is on t253371_17

Jump to latest
#1Masashi Kamura (Fujitsu)
kamura.masashi@fujitsu.com

Hi,

We found that the program crashes when following the steps below.

1) Create the instance
initdb -D data --encoding=UTF8 --no-locale

2) Execute following SQL
SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY');

We are analyzing the cause and the following commit seems the cause.
https://github.com/postgres/postgres/commit/011384ba45f

Could you please check this?

FYI)
- This did not occur in PG17. We suspect that this is because PG17 is using `str_toupper()`.
- Build option is as below :
--enable-nls --with-libedit-preferred --with-openssl --with-krb-srvnam=postgres --with-gssapi --with-ldap --with-libcurl --with-libnuma --with-ossp-uuid --with-libxml --with-libxslt --with-perl --with-python --with-tcl --with-tclconfig=/usr/lib64 --with-pam --with-lz4 --with-zstd --enable-tap-tests --with-selinux TCLSH=/usr/bin/tclsh 'CC=gcc ' CFLAGS=-O2 'CPPFLAGS=-DLINUX_OOM_SCORE_ADJ=0 -DLINUX_OOM_ADJ' 'LDFLAGS= -Wl,-rpath,'\''$$ORIGIN/../lib'\'',--enable-new-dtags' --with-llvm LLVM_CONFIG=/usr/bin/llvm-config CLANG=/usr/bin/clang

Regards,
Masashi Kamura
Fujitsu Limited

#2Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Masashi Kamura (Fujitsu) (#1)
Re: Crash issue in PG18.5 regression

On 2026-Aug-11, Masashi Kamura (Fujitsu) wrote:

Hi,

We found that the program crashes when following the steps below.

1) Create the instance
initdb -D data --encoding=UTF8 --no-locale

2) Execute following SQL
SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY');

We are analyzing the cause and the following commit seems the cause.
https://github.com/postgres/postgres/commit/011384ba45f

Could you please check this?

I confirm that this crashes with my regular build options also, as long
as initdb --no-locale is used. The backtrace from the crash point is

#0 __GI___towupper_l (wc=74, locale=locale@entry=0x0) at ./wctype/wcfuncs_l.c:69
#1 0x0000563291e315b8 in strupper_libc_mb (dest=0x7ffe3664f100 "\002", destsize=80, src=0x5632b0c066d8 "Jan",
srclen=3, locale=0x5632b0c02898) at ../../source/REL_18_STABLE/src/backend/utils/adt/pg_locale_libc.c:398
#2 strupper_libc (dst=dst@entry=0x7ffe3664f100 "\002", dstsize=dstsize@entry=80, src=src@entry=0x5632b0c066d8 "Jan",
srclen=<optimized out>, locale=locale@entry=0x5632b0c02898)
at ../../source/REL_18_STABLE/src/backend/utils/adt/pg_locale_libc.c:147
#3 0x0000563291e2f029 in pg_strupper (dst=dst@entry=0x7ffe3664f100 "\002", dstsize=dstsize@entry=80,
src=src@entry=0x5632b0c066d8 "Jan", srclen=<optimized out>, locale=locale@entry=0x5632b0c02898)
at ../../source/REL_18_STABLE/src/backend/utils/adt/pg_locale.c:1325

The relevant code in src/backend/utils/adt/pg_locale_libc.c's
strupper_libc_mb() from frame 1 is

397 │ for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
398 │ workspace[curr_char] = towupper_l(workspace[curr_char], loc);

where the important detail is that 'loc' is 0, which is not a valid
locale handle.

The locale code is quite the maze, but I'll see if I can find why is the
locale object not initialized.

--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
Maybe there's lots of data loss but the records of data loss are also lost.
(Lincoln Yeoh)

#3Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Alvaro Herrera (#2)
Re: Crash issue in PG18.5 regression

On 11/08/2026 09:32, Álvaro Herrera wrote:

On 2026-Aug-11, Masashi Kamura (Fujitsu) wrote:

We found that the program crashes when following the steps below.

1) Create the instance
initdb -D data --encoding=UTF8 --no-locale

2) Execute following SQL
SELECT to_date('01 ŞUB 2010', 'DD TMMON YYYY');

We are analyzing the cause and the following commit seems the cause.
https://github.com/postgres/postgres/commit/011384ba45f

Could you please check this?

I confirm that this crashes with my regular build options also, as long
as initdb --no-locale is used. The backtrace from the crash point is

#0 __GI___towupper_l (wc=74, locale=locale@entry=0x0) at ./wctype/wcfuncs_l.c:69
#1 0x0000563291e315b8 in strupper_libc_mb (dest=0x7ffe3664f100 "\002", destsize=80, src=0x5632b0c066d8 "Jan",
srclen=3, locale=0x5632b0c02898) at ../../source/REL_18_STABLE/src/backend/utils/adt/pg_locale_libc.c:398
#2 strupper_libc (dst=dst@entry=0x7ffe3664f100 "\002", dstsize=dstsize@entry=80, src=src@entry=0x5632b0c066d8 "Jan",
srclen=<optimized out>, locale=locale@entry=0x5632b0c02898)
at ../../source/REL_18_STABLE/src/backend/utils/adt/pg_locale_libc.c:147
#3 0x0000563291e2f029 in pg_strupper (dst=dst@entry=0x7ffe3664f100 "\002", dstsize=dstsize@entry=80,
src=src@entry=0x5632b0c066d8 "Jan", srclen=<optimized out>, locale=locale@entry=0x5632b0c02898)
at ../../source/REL_18_STABLE/src/backend/utils/adt/pg_locale.c:1325

The relevant code in src/backend/utils/adt/pg_locale_libc.c's
strupper_libc_mb() from frame 1 is

397 │ for (curr_char = 0; workspace[curr_char] != 0; curr_char++)
398 │ workspace[curr_char] = towupper_l(workspace[curr_char], loc);

where the important detail is that 'loc' is 0, which is not a valid
locale handle.

The locale code is quite the maze,

Indeed :-(.

but I'll see if I can find why is the locale object not
initialized.

For C locale, there is no locale object. Before commit 011384ba45f, none
of the callers called pg_strupper() with the C locale, they checked and
special-cased it and called asc_toupper() directly. See str_toupper().

Interestingly this only fails on REL_18_STABLE. On REL_19_STABLE,
pg_strupper() checks if locale->ctype is NULL, and does the equivalent
of asc_toupper() internally. On REL_17_STABLE and below didn't have
pg_strupper() so the equivalent of commit 011384ba45f uses str_toupper()
instead on those branches, which works.

I think the best fix is to make pg_strupper() in REL_18_STABLE also work
with the C locale. It's an accident waiting to happen if it doesn't.
(And same for all the other pg_str*() functions, of course)

- Heikki

#4Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Heikki Linnakangas (#3)
Re: Crash issue in PG18.5 regression

On 11/08/2026 12:19, Heikki Linnakangas wrote:

I think the best fix is to make pg_strupper() in REL_18_STABLE also work
with the C locale. It's an accident waiting to happen if it doesn't.
(And same for all the other pg_str*() functions, of course)

Like the attached.

There's some code duplication: the strupper_c() function is essentially
the same as asc_toupper(), and str_toupper() wouldn't really need to
have the special case for C locale anymore, it could just rely on
pg_strupper() now. But that's so in 'master' too, so I think cleaning
that up should be left for a separate patch.

- Heikki

Attachments:

0001-Fix-pg_strupper-lower-fold-functions-work-with-C-loc.patchtext/x-patch; charset=UTF-8; name=0001-Fix-pg_strupper-lower-fold-functions-work-with-C-loc.patchDownload+64-5
#5Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Heikki Linnakangas (#4)
Re: Crash issue in PG18.5 regression

On 2026-Aug-11, Heikki Linnakangas wrote:

On 11/08/2026 12:19, Heikki Linnakangas wrote:

I think the best fix is to make pg_strupper() in REL_18_STABLE also work
with the C locale. It's an accident waiting to happen if it doesn't.
(And same for all the other pg_str*() functions, of course)

Like the attached.

Hm, this looks really similar to what I wrote (attached here for the
curious), except you chose a different layer (directly in pg_locale.c,
whereas I put mine under the libc implementation). Probably yours is
the better choice since it also covers the builtin provider.

There's some code duplication: the strupper_c() function is essentially the
same as asc_toupper(), and str_toupper() wouldn't really need to have the
special case for C locale anymore, it could just rely on pg_strupper() now.
But that's so in 'master' too, so I think cleaning that up should be left
for a separate patch.

Agreed.

It's unclear to me how to get the strtitle() thing called, since the
only caller seems to be str_initcap() which will use asc_initcap anyway.
Maybe such a cleanup should remove some part of this code.

--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/

Attachments:

0001-Hardcode-str-lower-upper-title-for-the-C-locale.patchtext/x-diff; charset=utf-8Download+62-3
#6Masashi Kamura (Fujitsu)
kamura.masashi@fujitsu.com
In reply to: Alvaro Herrera (#5)
RE: Crash issue in PG18.5 regression

Hi Heikki san, Álvaro san,

Thank you for sharing the patch.
I have confirmed both patches passed the test without any issues.

Regards,
Masashi Kamura
Fujitsu Limited

#7Andres Freund
andres@anarazel.de
In reply to: Heikki Linnakangas (#4)
Re: Crash issue in PG18.5 regression

Hi,

On 2026-08-11 12:41:49 +0300, Heikki Linnakangas wrote:

On 11/08/2026 12:19, Heikki Linnakangas wrote:

I think the best fix is to make pg_strupper() in REL_18_STABLE also work
with the C locale. It's an accident waiting to happen if it doesn't.
(And same for all the other pg_str*() functions, of course)

Like the attached.

There's some code duplication: the strupper_c() function is essentially the
same as asc_toupper(), and str_toupper() wouldn't really need to have the
special case for C locale anymore, it could just rely on pg_strupper() now.
But that's so in 'master' too, so I think cleaning that up should be left
for a separate patch.

I wonder if we also ought to do something about the other uses of
pg_locale_t->info.lt in pg_locale_libc.c? That's at least strncoll_libc(),
strnxfrm_libc(). I think all the in-core callers guard them, but the
protection seems mighty far away in some cases.

Greetings,

Andres Freund

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#7)
Re: Crash issue in PG18.5 regression

Andres Freund <andres@anarazel.de> writes:

On 2026-08-11 12:41:49 +0300, Heikki Linnakangas wrote:

Like the attached.

I wonder if we also ought to do something about the other uses of
pg_locale_t->info.lt in pg_locale_libc.c? That's at least strncoll_libc(),
strnxfrm_libc(). I think all the in-core callers guard them, but the
protection seems mighty far away in some cases.

We don't have a lot of time to think about this, and AFAICS the
security patch only added calls to pg_strupper and pg_strlower.
So as long as those are protected I'm content to ship.

regards, tom lane

#9Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Tom Lane (#8)
Re: Crash issue in PG18.5 regression

On 11/08/2026 20:02, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

On 2026-08-11 12:41:49 +0300, Heikki Linnakangas wrote:

Like the attached.

I wonder if we also ought to do something about the other uses of
pg_locale_t->info.lt in pg_locale_libc.c? That's at least strncoll_libc(),
strnxfrm_libc(). I think all the in-core callers guard them, but the
protection seems mighty far away in some cases.

We don't have a lot of time to think about this, and AFAICS the
security patch only added calls to pg_strupper and pg_strlower.
So as long as those are protected I'm content to ship.

+1. It'd be good to look at those, but not right now.

I have pushed the fix.

- Heikki

#10Andres Freund
andres@anarazel.de
In reply to: Heikki Linnakangas (#4)
Re: Crash issue in PG18.5 regression

Hi,

On 2026-08-11 12:41:49 +0300, Heikki Linnakangas wrote:

+/* lowercasing/casefolding in C locale */
+static size_t
+strlower_c(char *dst, size_t dstsize, const char *src, size_t srclen)
+{
+	int			i;
+
+	for (i = 0; i < srclen && i < dstsize; i++)
+		dst[i] = pg_ascii_tolower(src[i]);
+	if (i < dstsize)
+		dst[i] = '\0';
+	return srclen;
+}

Hm. If I infer the pg_strlower() API correctly - it's utterly underdocumented
- it seems to be inteded to support a few things in 18:

1) srclen = -1 works

Inferred from unicode_strlower()'s comment:

* String src must be encoded in UTF-8. If srclen < 0, src must be
* NUL-terminated.

Also note that srclen is ssize_t. This changed in 6d22c67c3bf5 (recently).

2) The required length for the conversion is returned, even if the destination
is too short (including when dstlen = 0)

* Result string is stored in dst, truncating if larger than dstsize. If
* dstsize is greater than the result length, dst will be NUL-terminated;
* otherwise not.
*
* If dstsize is zero, dst may be NULL. This is useful for calculating the
* required buffer size before allocating.

It's really a guessing game though, due to the religious under documentation
of the generic functions. Why does unicode_strlower() have docs, but
pg_strlower() does not?

Both don't seem quite right given this implementation.

I don't quite know whether we need to fix these, given the lack of problematic
uses in tree, the time pressure, but it also seems like a recipe for future
disaster to leave it like this.

I'd also make i size_t, given that the input is size_t. Perhaps practically
no problem, but I see no reason to not use size_t here.

It also seems like we really ought to have an actually reachable, currently
crashing, to_date() call in the tests? It seems concerning that
seq_search_localized(), casefold_str_cmp() are completely uncovered today, and
quite obviously we can't be relied upon to get this right.

https://coverage.postgresql.org/src/backend/utils/adt/formatting.c.gcov.html#L2379

Greetings,

Andres Freund

#11Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#3)
Re: Crash issue in PG18.5 regression

On Tue, 2026-08-11 at 12:19 +0300, Heikki Linnakangas wrote:

Interestingly this only fails on REL_18_STABLE. On REL_19_STABLE,
pg_strupper() checks if locale->ctype is NULL, and does the
equivalent
of asc_toupper() internally.

Ugh. I should have backported 1476028225, sorry :-(

Thank you for catching it quickly, Masashi!

Regards,
Jeff Davis

#12Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#10)
Re: Crash issue in PG18.5 regression

Andres Freund <andres@anarazel.de> writes:

It also seems like we really ought to have an actually reachable, currently
crashing, to_date() call in the tests? It seems concerning that
seq_search_localized(), casefold_str_cmp() are completely uncovered today, and
quite obviously we can't be relied upon to get this right.

All that code is reached when I run the core regression tests under
LANG=C.utf8 or LANG=en_US.utf8, except for the "As last resort"
stanza at the bottom of seq_search_localized()'s loop. I suppose the
coverage.postgresql.org animal is either not Linux or doesn't test
any UTF8 encoding, but that's not the fault of our test cases, and
it doesn't reflect what I think actually happens in the buildfarm.
Yeah, it'd be good if we could devise a test case that reaches the
"As last resort" bit, but that's irrelevant to the current problem.

The reason we failed to notice this sooner is that the crash is only
reached with (a) locale = "C" and (b) either a multi-byte encoding,
so that we reach strupper_libc_mb, or a single-byte encoding with
some high-bit-set characters, so that strupper_libc_sb invokes libc.
The regression test cases that might have noticed this are in
collate.linux.utf8.sql, so we need locale = "C" + encoding = UTF8 +
a Linux test machine that has a reasonable set of locales installed.
That would have been enough to find it, except that the buildfarm
client doesn't have any easy way to test locale = "C" with
encoding = UTF8. It will test locale = "C" with encoding SQL_ASCII,
which doesn't run collate.linux.utf8.sql, and it will test other
cases as set up by the machine owner, but there's no way to tell it
to use that specific locale+encoding combination. I've tried
"LANG=C.utf8", but that doesn't reach the crash, probably because
it doesn't cause us to take the locale_is_c optimization paths.
(Should it? I'm unsure.)

So I'm not seeing a huge failure to test here. We missed a very
narrow combination of cases.

regards, tom lane

#13Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#12)
Re: Crash issue in PG18.5 regression

Hi,

On 2026-08-11 16:04:15 -0400, Tom Lane wrote:

Andres Freund <andres@anarazel.de> writes:

It also seems like we really ought to have an actually reachable, currently
crashing, to_date() call in the tests? It seems concerning that
seq_search_localized(), casefold_str_cmp() are completely uncovered today, and
quite obviously we can't be relied upon to get this right.

All that code is reached when I run the core regression tests under
LANG=C.utf8 or LANG=en_US.utf8, except for the "As last resort"
stanza at the bottom of seq_search_localized()'s loop. I suppose the
coverage.postgresql.org animal is either not Linux or doesn't test
any UTF8 encoding, but that's not the fault of our test cases, and
it doesn't reflect what I think actually happens in the buildfarm.

I tested locally on a database that triggered the problem, the skip condition
query was true, which lead me to hastily misread what the query is trying to
do. Turns out the reason it doesn't run here - and likely the reason that it
doesn't run for coverage.pg.o - is that the test afaict *never* matches for a
meson build :(

no_enc2[3902736][1]=# SELECT version();
┌────────────────────────────────────────────────────────────────────┐
│ version │
├────────────────────────────────────────────────────────────────────┤
│ PostgreSQL 20devel on x86_64-linux, compiled by gcc-16.1.0, 64-bit │
└────────────────────────────────────────────────────────────────────┘
(1 row)

That will obviously never match "linux-gnu".

I guess I should start a separate thread about that.

Greetings,

Andres Freund

#14Jeff Davis
pgsql@j-davis.com
In reply to: Andres Freund (#10)
Re: Crash issue in PG18.5 regression

On Tue, 2026-08-11 at 14:31 -0400, Andres Freund wrote:

Hm. If I infer the pg_strlower() API correctly - it's utterly
underdocumented

Agreed. Patch attached.

I'd also make i size_t, given that the input is size_t.  Perhaps
practically
no problem, but I see no reason to not use size_t here.

Patch attached for that, too.

I also attached patches to make all the functions work with
collate_is_c, and fixed up the -1 API in 18.

Regards,
Jeff Davis

Attachments:

vPG18-0001-Fixup-5f003855e7-for-srclen-0.patchtext/x-patch; charset=UTF-8; name=vPG18-0001-Fixup-5f003855e7-for-srclen-0.patchDownload+8-1
vPG18-0002-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchtext/x-patch; charset=UTF-8; name=vPG18-0002-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchDownload+5-6
vPG18-0003-Add-missing-comments-in-pg_locale.c.patchtext/x-patch; charset=UTF-8; name=vPG18-0003-Add-missing-comments-in-pg_locale.c.patchDownload+63-14
vPG18-0004-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchtext/x-patch; charset=UTF-8; name=vPG18-0004-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchDownload+58-7
vPG19-0001-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchtext/x-patch; charset=UTF-8; name=vPG19-0001-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchDownload+5-6
vPG19-0002-Add-missing-comments-in-pg_locale.c.patchtext/x-patch; charset=UTF-8; name=vPG19-0002-Add-missing-comments-in-pg_locale.c.patchDownload+60-11
vPG19-0003-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchtext/x-patch; charset=UTF-8; name=vPG19-0003-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchDownload+49-7
vPG20-0001-Add-missing-comments-in-pg_locale.c.patchtext/x-patch; charset=UTF-8; name=vPG20-0001-Add-missing-comments-in-pg_locale.c.patchDownload+60-11
vPG20-0002-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchtext/x-patch; charset=UTF-8; name=vPG20-0002-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchDownload+49-7
#15Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#14)
Re: Crash issue in PG18.5 regression

On Thu, 2026-08-13 at 22:17 -0700, Jeff Davis wrote:

On Tue, 2026-08-11 at 14:31 -0400, Andres Freund wrote:

Hm. If I infer the pg_strlower() API correctly - it's utterly
underdocumented

Agreed. Patch attached.

I'd also make i size_t, given that the input is size_t.  Perhaps
practically
no problem, but I see no reason to not use size_t here.

Patch attached for that, too.

I also attached patches to make all the functions work with
collate_is_c, and fixed up the -1 API in 18.

Now with a C test module (made with AI assistance).

I plan to start committing these fairly soon. I'm not sure whether to
backport the C test module, but I included the patches to do so.

Regards,
Jeff Davis

Attachments:

vPG18-0001-Fixup-5f003855e7-for-srclen-0.patchtext/x-patch; charset=UTF-8; name=vPG18-0001-Fixup-5f003855e7-for-srclen-0.patchDownload+8-1
vPG18-0002-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchtext/x-patch; charset=UTF-8; name=vPG18-0002-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchDownload+5-6
vPG18-0003-Add-missing-comments-in-pg_locale.c.patchtext/x-patch; charset=UTF-8; name=vPG18-0003-Add-missing-comments-in-pg_locale.c.patchDownload+63-14
vPG18-0004-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchtext/x-patch; charset=UTF-8; name=vPG18-0004-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchDownload+58-7
vPG18-0005-Add-C-test-module-for-pg_locale.h-APIs.patchtext/x-patch; charset=UTF-8; name=vPG18-0005-Add-C-test-module-for-pg_locale.h-APIs.patchDownload+306-1
vPG19-0001-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchtext/x-patch; charset=UTF-8; name=vPG19-0001-pg_locale.c-unicode_case.c-use-size_t-for-iter.patchDownload+5-6
vPG19-0002-Add-missing-comments-in-pg_locale.c.patchtext/x-patch; charset=UTF-8; name=vPG19-0002-Add-missing-comments-in-pg_locale.c.patchDownload+60-11
vPG19-0003-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchtext/x-patch; charset=UTF-8; name=vPG19-0003-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchDownload+49-7
vPG19-0004-Add-C-test-module-for-pg_locale.h-APIs.patchtext/x-patch; charset=UTF-8; name=vPG19-0004-Add-C-test-module-for-pg_locale.h-APIs.patchDownload+290-1
vPG20-0001-Add-missing-comments-in-pg_locale.c.patchtext/x-patch; charset=UTF-8; name=vPG20-0001-Add-missing-comments-in-pg_locale.c.patchDownload+60-11
vPG20-0002-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchtext/x-patch; charset=UTF-8; name=vPG20-0002-Ensure-all-pg_locale.h-APIs-work-with-collate_.patchDownload+49-7
vPG20-0003-Add-C-test-module-for-pg_locale.h-APIs.patchtext/x-patch; charset=UTF-8; name=vPG20-0003-Add-C-test-module-for-pg_locale.h-APIs.patchDownload+290-1
#16Andres Freund
andres@anarazel.de
In reply to: Jeff Davis (#15)
Re: Crash issue in PG18.5 regression

Hi,

On 2026-08-15 14:53:39 -0700, Jeff Davis wrote:

On Thu, 2026-08-13 at 22:17 -0700, Jeff Davis wrote:

On Tue, 2026-08-11 at 14:31 -0400, Andres Freund wrote:

Hm. If I infer the pg_strlower() API correctly - it's utterly
underdocumented

Agreed. Patch attached.

I'd also make i size_t, given that the input is size_t.  Perhaps
practically
no problem, but I see no reason to not use size_t here.

Patch attached for that, too.

I also attached patches to make all the functions work with
collate_is_c, and fixed up the -1 API in 18.

Now with a C test module (made with AI assistance).

I plan to start committing these fairly soon. I'm not sure whether to
backport the C test module, but I included the patches to do so.

Thanks for working on these.

From f669e9fafb9bf435c946dcc2c2dd98efb4aa46cb Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Thu, 13 Aug 2026 21:12:34 -0700
Subject: [PATCH vPG18 2/5] pg_locale.c, unicode_case.c: use size_t for
iteration.

No actual problem, just cleanup. Only relevant to 18 and 19.

FWIW, I think this is actually a bug, it just turns out that we don't know of
any callers that hit it.

From a8e72bb34c979ac43ee8480fd10ed4e73db47b10 Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Wed, 12 Aug 2026 07:32:19 -0700
Subject: [PATCH vPG18 3/5] Add missing comments in pg_locale.c.

Suggested-by: Andres Freund <andres@anarazel.de>
Discussion: /messages/by-id/v3nniwcrxejmcfvz56xbd22hphprqleuornd6hqkmw2bl7kgmz@cnytz2ee5ltk
Backpatch-through: 18

Nice, that's much better than before.

+/*
+ * pg_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not including
+ * terminating NUL).

Might not hurt to actually say what titlecase and folded strings are.

From adeef54179a11f5b7817054bc53f8b7b584d2b6a Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Sat, 15 Aug 2026 12:26:09 -0700
Subject: [PATCH vPG18 5/5] Add C test module for pg_locale.h APIs.

Test the API independently to account for fallback paths that aren't
adequately tested from SQL.

The backport to 18 also tests the previously-supported behavior where
a size of -1 meant that the string was NUL-terminated. That behavior
was later removed in 19.

Discussion: /messages/by-id/v36ssaygf7grb3qzfsjhtdzi7kqd45ds56nyuf7gi5qjml4qbb@ezmfqzmhlrs2
Backpatch-through: 18
---
src/test/modules/Makefile | 1 +
src/test/modules/meson.build | 1 +
src/test/modules/test_pg_locale/.gitignore | 4 +
src/test/modules/test_pg_locale/Makefile | 23 +++
src/test/modules/test_pg_locale/README | 2 +
.../expected/test_pg_locale.out | 38 ++++
src/test/modules/test_pg_locale/meson.build | 33 ++++
.../test_pg_locale/sql/test_pg_locale.sql | 23 +++
.../test_pg_locale/test_pg_locale--1.0.sql | 8 +
.../modules/test_pg_locale/test_pg_locale.c | 169 ++++++++++++++++++
.../test_pg_locale/test_pg_locale.control | 4 +
11 files changed, 306 insertions(+)
create mode 100644 src/test/modules/test_pg_locale/.gitignore
create mode 100644 src/test/modules/test_pg_locale/Makefile
create mode 100644 src/test/modules/test_pg_locale/README
create mode 100644 src/test/modules/test_pg_locale/expected/test_pg_locale.out
create mode 100644 src/test/modules/test_pg_locale/meson.build
create mode 100644 src/test/modules/test_pg_locale/sql/test_pg_locale.sql
create mode 100644 src/test/modules/test_pg_locale/test_pg_locale--1.0.sql
create mode 100644 src/test/modules/test_pg_locale/test_pg_locale.c
create mode 100644 src/test/modules/test_pg_locale/test_pg_locale.control

I very much like that this is tested now, but this really need its own
initdb'd cluster? Every full testrun writes ginormous amounts of data (~73GB
for one master run on macos!), due to the number of clusters we create, and
the amount is growing from release to release at an alarming clip.

Sometimes that's unavoidable, because you need a server configured in a
specific way, the tests take a good while and should therefore run
concurrently, or such. But that shouldn't be the case her. Can't you stuff
this into regress.c or such?

Other than that complaint, I'd probably backpatch this. Seems unlikely to be
flappy or such?

Greetings,

Andres Freund

#17Jeff Davis
pgsql@j-davis.com
In reply to: Andres Freund (#16)
Re: Crash issue in PG18.5 regression

On Tue, 2026-08-18 at 14:36 -0400, Andres Freund wrote:

FWIW, I think this is actually a bug, it just turns out that we don't
know of
any callers that hit it.

Committed.

Also committed the change to support collate_is_c always, for
consistency with ctype_is_c.

+/*
+ * pg_strtitle()
+ *
+ * Convert src to titlecase, and return the result length (not
including
+ * terminating NUL).

Might not hurt to actually say what titlecase and folded strings are.

Attached follow-up patch that includes explanatory comments, and adds a
couple tiny SQL tests to cover the new examples.

Sometimes that's unavoidable, because you need a server configured in
a
specific way, the tests take a good while and should therefore run
concurrently, or such. But that shouldn't be the case her. Can't you
stuff
this into regress.c or such?

Attached new test patch that just adds it to regress.c and calls it
from misc_functions.sql.

Other than that complaint, I'd probably backpatch this. Seems
unlikely to be
flappy or such?

Agreed. It would have caught 27e2afb492.

Thank you for looking at it.

Regards,
Jeff Davis

Attachments:

t253371_17
v3.pg20-0001-Add-C-test-function-for-pg_locale.h-APIs.patchtext/x-patch; charset=UTF-8; name=v3.pg20-0001-Add-C-test-function-for-pg_locale.h-APIs.patchDownload+199-1
v3.pg20-0002-pg_locale.c-add-explanatory-comments-and-tes.patchtext/x-patch; charset=UTF-8; name=v3.pg20-0002-pg_locale.c-add-explanatory-comments-and-tes.patchDownload+80-5