| From: | Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com> |
|---|---|
| To: | shihao zhong <zhong950419(at)gmail(dot)com> |
| Cc: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Jeff Davis <pgsql(at)j-davis(dot)com>, Noah Misch <noah(at)leadboat(dot)com> |
| Subject: | Re: [PG19] ILIKE index scan misses rows with a libc UTF-8 collation on macOS |
| Date: | 2026-10-19 02:04:32 |
| Message-ID: | 66318549-4413-4633-AFFC-B6257DB0224F@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
> On Oct 18, 2026, at 11:52, shihao zhong <zhong950419(at)gmail(dot)com> wrote:
>
> Hi,
>
> This is the first low item from my list in [1]. It has the same cause as
> the EUC_* report in [2], and 43a948b7b25 did not fix it.
>
> wc_iscased_libc_utf8() asks iswupper() and iswlower(), but ILIKE
> compares with towlower(). The macOS C library case-maps 117 code points
> that are neither upper nor lower, like U+2160 (Roman numeral one). So
> U+2160 stays in the index prefix:
>
> create table t (x text collate "en_US.UTF-8");
> insert into t values (U&'\2160q'), (U&'\2170q');
> insert into t select 'filler' || g from generate_series(1, 2000) g;
> create index on t (x text_pattern_ops);
> analyze t;
> select count(*) from t where x ilike U&'\2160q%';
>
> On the master and REL_19_STABLE heads the index scan returns 1. A seq
> scan returns 2. glibc on Linux classifies all of them, so it is fine.
>
> The attached patch also counts a character as cased when towupper() or
> towlower() changes it.
>
>
> [1] https://postgr.es/m/CAGRkXqSFdjqZP_kwRz7dv6LHX-CSrkDnynNXgntRsCEnQTKxmg@mail.gmail.com
> [2] https://postgr.es/m/20260826221526.89.noahmisch@microsoft.com
>
> Thanks,
> Shihao
> <v1-0001-Fix-pg_iswcased-for-libc-UTF8-case-mappings.patch>
I can reproduce the issue on my MacBook too.
Given that this issue has only been confirmed on macOS so far, does it make sense to add the extra checks only for macOS, like this:
```
return iswupper_l((wint_t) wc, locale->lt) ||
iswlower_l((wint_t) wc, locale->lt)
#if defined(__darwin__)
|| towupper_l((wint_t) wc, locale->lt) != (wint_t) wc
|| towlower_l((wint_t) wc, locale->lt) != (wint_t) wc
#endif
;
```
I see that #if defined(__darwin__) is already used in many places.
Then, I would suggest adding a regression test so that CI can help check whether the problem exists on other platforms.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Richard Guo | 2026-10-19 02:13:04 | Re: Assert failure in create_lateral_join_info |
| Previous Message | Scott Ray | 2026-10-19 02:02:18 | Re: pg_xmin_horizon: a system view of everything pinning the xmin horizon |