agora inbox for pgsql-hackers@postgresql.org
help / color / mirror / Atom feedFrom: Álvaro Herrera <alvherre@kurilemu.de>
To: Heikki Linnakangas <hlinnaka@iki.fi>
Cc: Masashi Kamura (Fujitsu) <kamura.masashi@fujitsu.com>
Cc: 'pgsql-hackers@lists.postgresql.org' <pgsql-hackers@lists.postgresql.org>
Cc: Jeff Davis <pgsql@j-davis.com>
Subject: Re: Crash issue in PG18.5 regression
Date: Tue, 11 Aug 2026 12:23:03 +0200
Message-ID: <anr2M1Wj_31k6aPD@alvherre.pgsql> (raw)
In-Reply-To: <f72a8fbe-7ef1-4cd3-8a4b-fd9106480510@iki.fi>
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:
[text/x-diff] 0001-Hardcode-str-lower-upper-title-for-the-C-locale.patch (4.5K, ../anr2M1Wj_31k6aPD@alvherre.pgsql/2-0001-Hardcode-str-lower-upper-title-for-the-C-locale.patch)
download | inline diff:
From e6df99c6ba63216297630a3b7057fb5ac1735db6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=81lvaro=20Herrera?= <alvherre@kurilemu.de>
Date: Tue, 11 Aug 2026 12:11:35 +0200
Subject: [PATCH] Hardcode str{lower,upper,title}() for the C locale
This avoids a crash when those functions are called directly rather than
via str_to{lower,upper,title} directly.
---
src/backend/utils/adt/pg_locale_libc.c | 64 +++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 2 deletions(-)
diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c
index 31274f069d2..afacb727efe 100644
--- a/src/backend/utils/adt/pg_locale_libc.c
+++ b/src/backend/utils/adt/pg_locale_libc.c
@@ -66,18 +66,24 @@ static int strncoll_libc_win32_utf8(const char *arg1, ssize_t len1,
pg_locale_t locale);
#endif
+static size_t strlower_libc_c(char *dest, size_t dstsize,
+ const char *src, ssize_t srclen);
static size_t strlower_libc_sb(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
static size_t strlower_libc_mb(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
+static size_t strtitle_libc_c(char *dest, size_t dstsize,
+ const char *src, ssize_t srclen);
static size_t strtitle_libc_sb(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
static size_t strtitle_libc_mb(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
+static size_t strupper_libc_c(char *dest, size_t dstsize,
+ const char *src, ssize_t srclen);
static size_t strupper_libc_sb(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
@@ -123,7 +129,9 @@ size_t
strlower_libc(char *dst, size_t dstsize, const char *src,
ssize_t srclen, pg_locale_t locale)
{
- if (pg_database_encoding_max_length() > 1)
+ if (locale->ctype_is_c)
+ return strlower_libc_c(dst, dstsize, src, srclen);
+ else if (pg_database_encoding_max_length() > 1)
return strlower_libc_mb(dst, dstsize, src, srclen, locale);
else
return strlower_libc_sb(dst, dstsize, src, srclen, locale);
@@ -133,6 +141,8 @@ size_t
strtitle_libc(char *dst, size_t dstsize, const char *src,
ssize_t srclen, pg_locale_t locale)
{
+ if (locale->ctype_is_c)
+ return strtitle_libc_c(dst, dstsize, src, srclen);
if (pg_database_encoding_max_length() > 1)
return strtitle_libc_mb(dst, dstsize, src, srclen, locale);
else
@@ -143,12 +153,26 @@ size_t
strupper_libc(char *dst, size_t dstsize, const char *src,
ssize_t srclen, pg_locale_t locale)
{
- if (pg_database_encoding_max_length() > 1)
+ if (locale->ctype_is_c)
+ return strupper_libc_c(dst, dstsize, src, srclen);
+ else if (pg_database_encoding_max_length() > 1)
return strupper_libc_mb(dst, dstsize, src, srclen, locale);
else
return strupper_libc_sb(dst, dstsize, src, srclen, locale);
}
+static size_t
+strlower_libc_c(char *dest, size_t dstsize, const char *src, ssize_t srclen)
+{
+ int i;
+
+ for (i = 0; i < srclen && i < dstsize; i++)
+ dest[i] = pg_ascii_tolower(src[i]);
+ if (i < dstsize)
+ dest[i] = '\0';
+ return srclen;
+}
+
static size_t
strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
@@ -280,6 +304,30 @@ strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
return srclen;
}
+static size_t
+strtitle_libc_c(char *dest, size_t dstsize, const char *src, ssize_t srclen)
+{
+ bool wasalnum = false;
+ int i;
+
+ for (i = 0; i < srclen && i < dstsize; i++)
+ {
+ char c = src[i];
+
+ if (wasalnum)
+ dest[i] = pg_ascii_tolower(c);
+ else
+ dest[i] = pg_ascii_toupper(c);
+
+ wasalnum = ((c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z'));
+ }
+ if (i < dstsize)
+ dest[i] = '\0';
+ return srclen;
+}
+
static size_t
strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
@@ -335,6 +383,18 @@ strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen,
return result_size;
}
+static size_t
+strupper_libc_c(char *dest, size_t dstsize, const char *src, ssize_t srclen)
+{
+ int i;
+
+ for (i = 0; i < srclen && i < dstsize; i++)
+ dest[i] = pg_ascii_toupper(src[i]);
+ if (i < dstsize)
+ dest[i] = '\0';
+ return srclen;
+}
+
static size_t
strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
pg_locale_t locale)
--
2.47.3
view thread (16+ messages) latest in thread
Message-ID: <anr2M1Wj_31k6aPD@alvherre.pgsql>
Permalink: ../anr2M1Wj_31k6aPD@alvherre.pgsql/
Also on: postgresql.org/message-id/anr2M1Wj_31k6aPD@alvherre.pgsql
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: alvherre@kurilemu.de, hlinnaka@iki.fi, kamura.masashi@fujitsu.com, pgsql-hackers@lists.postgresql.org, pgsql@j-davis.com
Subject: Re: Crash issue in PG18.5 regression
In-Reply-To: <anr2M1Wj_31k6aPD@alvherre.pgsql>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox