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.96) (envelope-from ) id 1wtjdZ-000Cyb-01 for pgsql-hackers@arkaria.postgresql.org; Tue, 11 Aug 2026 10:23:13 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wtjdW-002EzN-2q for pgsql-hackers@arkaria.postgresql.org; Tue, 11 Aug 2026 10:23:12 +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.96) (envelope-from ) id 1wtjdW-002EzF-0E for pgsql-hackers@lists.postgresql.org; Tue, 11 Aug 2026 10:23:11 +0000 Received: from fhigh-a3-smtp.messagingengine.com ([103.168.172.154]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wtjdU-000000005y7-1zzx for pgsql-hackers@lists.postgresql.org; Tue, 11 Aug 2026 10:23:10 +0000 Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailfhigh.phl.internal (Postfix) with ESMTP id 4FBA0140014C; Tue, 11 Aug 2026 06:23:07 -0400 (EDT) Received: from phl-frontend-03 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Tue, 11 Aug 2026 06:23:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kurilemu.de; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to; s=fm1; t=1786443787; x= 1786530187; bh=PnlMfH48oB1/Xj+Ta7DXUZfR61dxH+NahrAFe0qzBoE=; b=E iXzQIIZ+eoXRb8jWGI+TGRypPO/Lu6dF5r5X/2Ji6gcCXni6f9Ku1gwljQTVdOMD LcF9RDsngRhlLhri7WMdisRJhA48YYsvI+3WVe4gMouCNHErGkp+yUwM8E9bjw+p hEyUk8ss4XcTVmS6pe5Y0Fo7W2HrWinaiJvST3oCDKxUiVOkQVnfFM6C1hMzg6cL up/E84xS26E0y8cpZdZOU0ZiVzqjDJLuklGuO0L/Z0BH2V9Q7a3KeLRZxOYQcPn7 AoTa1es3tfVYBkOk/SJ9PCT6wGe5FVKJLVccvqQFHZDRd5N++rsin5wIqNf92qQo fMlCeE4WJTqYGSz1J59aA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1786443787; x=1786530187; bh=P nlMfH48oB1/Xj+Ta7DXUZfR61dxH+NahrAFe0qzBoE=; b=E5MVtS81H7O5tgMVB p4cZCY1sXSg+jLctqO3wcyesdXkzcah7TNJQIp78L2DsUWBAfNJkbi651Un6RY8v 4FpUg19mZrTnLCi/AE12YHgwSqudza84TdhY9eGL/qiJx/MBdpxlBfbdMQUVdXyL idDsoSfiBaXxRbdvg7bqLEX2AG8eFjmavvOR26b+GDEG1uj10ivZ0aSbjQ9cv0NR /DBFvh/LEfGy6ngHNB1fqDsfvt0735U1AzdDcI9Nyc83aH8WER9hNSFL09k82eF5 lgTtM0RfKmoMo1KtSALH2kZsh2SCxsTGGCzvb2Ni1X+X+FSYe5juiAnnSttdz5Aj ehPiw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: dmFkZTGSXwJqNqWYjEhNBI0MaQQ1JJAcGFusfrNEzGsbs8lNaxpNmbVEZtGrEWOn1Do7Iz nFYfDOQjyFgJVrT5StyZxlxOjgim65ZKecHgInV4UAPI95u18aielC4Krb8r9BPUITbOlQ njBnMd5qMq/X8MhLGzYK37llgThKXWc2klwoIL8w9+TV4zLO4jo9Pk3FH4W1Kn7ab620NA 2MehDGD/h3SZRvE6a8yN0Fvzb4HjVE2njrSZlkQxSSJAUcYxXYH/Y2rg7Z3vlZreITOkz4 SyYytsnXhEI3bvP6Lf3AzEOInAGaD8ig7Gut+vJXfqXk5WT0uDTU8EKrNECzgbQ/b6sefL c7VsSohEnEdLpycdyzBzZeMlctE8wXveNPysWOwRtun2LMG85hvR4+Iv3wZ4q9z1+WX6u/ QI5np0C5ChIqmZndITOKzzuP35IwFw0MrSS/3ulabSzp7Ohz3IZPQVmGvWHwCc7xQOKe4H 2rG3O81BSMA+uD3lZQpuzhrbJbXEt4EUirKGf/7VeG0qT7Xns5JC5C3N8IAqUXU+c6vUSJ QH7CWnnwQeeUHxB2RZ9Dd/kJ9lYUQ5+HJNv+69lq3j/UCjDmsBJpP32bQ7pTH9MpVO0wls Ev2G9nCa3449rx4VYUvHidGpav8RKrMwNaZMFGNAye18/rkecK2+/pOPUOJg X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Tue, 11 Aug 2026 06:23:06 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1786443783; bh=uImJdmk8gwKPC7k9pZfYrx00PZENKiQJWuFMmPGdqos=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=oKeab+Rckgjc4AG+OVtqamfMhI0T39r3mDi3gXuunWqqV/NCTC4R/FH7qLaHi39g6 lHIBtPX4G60MijMYaB4zNzXUPjlU5V9zhNttcw3LRp7fsRJd/6pk3Q1fxfieVN3b74 6KMNTEx7q1pB8SYGiMKMqP7wfdKct7Xaeeiw/XulJShzNYsoYMT4YPz5t/+NaIcZEg YABnlwm2zcvYU+MTyM4XUSTj03dp/9Zwi34pe8nvkZSbgPI/t0/4zPtGUtLI11gu/K GzBgGKjopVhVMRLzKbSAV/Z5mvlZJer70Txx6nnr3Z+0bIOYG6yiQTorQR4MZqiI8x AxRka6GMnj0sg== Received: by ida.kurilemu.internal (Postfix, from userid 1000) id 9F034B001E5; Tue, 11 Aug 2026 12:23:03 +0200 (CEST) Date: Tue, 11 Aug 2026 12:23:03 +0200 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: Heikki Linnakangas Cc: "Masashi Kamura (Fujitsu)" , "'pgsql-hackers@lists.postgresql.org'" , Jeff Davis Subject: Re: Crash issue in PG18.5 regression Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="bynzpkhnelsy7sdt" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --bynzpkhnelsy7sdt Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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/ --bynzpkhnelsy7sdt Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename=0001-Hardcode-str-lower-upper-title-for-the-C-locale.patch From e6df99c6ba63216297630a3b7057fb5ac1735db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= 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 --bynzpkhnelsy7sdt--