v1-0001-Avoid-gettext-0.20-performance-bug-on-Windows.patch
text/plain
Filename: v1-0001-Avoid-gettext-0.20-performance-bug-on-Windows.patch
Type: text/plain
Part: 0
From be63384836855ae5356362793f51f0ffdd554537 Mon Sep 17 00:00:00 2001
From: Bryan Green <dbryan.green@gmail.com>
Date: Tue, 9 Dec 2025 18:21:45 -0600
Subject: [PATCH v1] Avoid gettext 0.20+ performance bug on Windows.
gettext 0.20.1+ expects Windows locale format ("English_United States")
not POSIX format ("en_US"), and has a cache bug where failed lookups
cause repeated enumeration of all ~259 system locales on every gettext()
call. This makes exception-heavy workloads 5-6x slower.
PostgreSQL has always converted to POSIX format via IsoLocaleName()
before setting LC_MESSAGES, which triggers this bug. Setting lc_messages
to 'C' or 'POSIX' triggers it too, since these aren't Windows names.
Fix by using Windows format for gettext 0.20.1+, which handles it
correctly. Retain POSIX format for 0.19.8 and earlier. Detect version
via LIBINTL_VERSION macro.
Improves 1M exception test from ~180s to ~40s.
---
src/backend/utils/adt/pg_locale.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index b26257c0a8..eb8025438a 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -230,10 +230,19 @@ pg_perm_setlocale(int category, const char *locale)
case LC_MESSAGES:
envvar = "LC_MESSAGES";
#ifdef WIN32
+#if defined(LIBINTL_VERSION) && (LIBINTL_VERSION >= 0x001401)
+ if (locale == NULL || locale[0] == '\0' ||
+ strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0)
+ result = setlocale(LC_CTYPE, NULL);
+ else
+ result = (char *) locale;
+#else
+ /* Convert to ISO locale name */
result = IsoLocaleName(locale);
if (result == NULL)
result = (char *) locale;
- elog(DEBUG3, "IsoLocaleName() executed; locale: \"%s\"", result);
+#endif
+ elog(DEBUG3,"LC_MESSAGES locale: \"%s\"", result);
#endif /* WIN32 */
break;
#endif /* LC_MESSAGES */
--
2.52.0.windows.1