From 6c47dd2986f96778603bfb6690dd670f2ed79567 Mon Sep 17 00:00:00 2001 From: shihao zhong Date: Mon, 12 Oct 2026 19:42:18 -0400 Subject: [PATCH v1] Fix pg_iswcased() for libc UTF8 case mappings Some C libraries, such as macOS, case-map characters that they do not classify as upper or lower. On macOS that is 117 code points. ILIKE index scans could then miss rows, because those characters stayed in the fixed prefix. Ask about the mapping, which is what ILIKE uses. --- src/backend/utils/adt/pg_locale_libc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index 02c419aa62a..801f3dcafe0 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -328,10 +328,14 @@ wc_iscased_libc_utf8(pg_wchar wc, pg_locale_t locale) /* * For UTF8, pg_wchar is a codepoint and we assume we can pass it directly - * to iswupper_l()/iswlower_l(). + * to iswupper_l()/iswlower_l(). Some C libraries case-map characters + * that they do not classify as upper or lower, so also check the mapping, + * which is what ILIKE uses. */ return iswupper_l((wint_t) wc, locale->lt) || - iswlower_l((wint_t) wc, locale->lt); + iswlower_l((wint_t) wc, locale->lt) || + towupper_l((wint_t) wc, locale->lt) != (wint_t) wc || + towlower_l((wint_t) wc, locale->lt) != (wint_t) wc; } static pg_wchar -- 2.37.1 (Apple Git-137.1)