diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2019-08-12 13:15:47 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2019-08-12 13:15:47 -0400 |
commit | 03c811a483b243952874d8e2b3f0c2e3793bc952 (patch) | |
tree | 0b55bd3212a7e94cc2c3368846b7dc01528e9589 /src/backend/utils/adt/like_support.c | |
parent | 3c926587b5928795e54dfea65c712a604f63cdeb (diff) | |
download | postgresql-03c811a483b243952874d8e2b3f0c2e3793bc952.tar.gz postgresql-03c811a483b243952874d8e2b3f0c2e3793bc952.zip |
Fix planner's test for case-foldable characters in ILIKE with ICU.
As coded, the ICU-collation path in pattern_char_isalpha() failed
to consider regular ASCII letters to be case-varying. This led to
like_fixed_prefix treating too much of an ILIKE pattern as being a
fixed prefix, so that indexscans derived from an ILIKE clause might
miss entries that they should find.
Per bug #15892 from James Inform. This is an oversight in the original
ICU patch (commit eccfef81e), so back-patch to v10 where that came in.
Discussion: https://postgr.es/m/15892-e5d2bea3e8a04a1b@postgresql.org
Diffstat (limited to 'src/backend/utils/adt/like_support.c')
-rw-r--r-- | src/backend/utils/adt/like_support.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/backend/utils/adt/like_support.c b/src/backend/utils/adt/like_support.c index 26e06348338..c8fec7863f4 100644 --- a/src/backend/utils/adt/like_support.c +++ b/src/backend/utils/adt/like_support.c @@ -1437,8 +1437,9 @@ regex_selectivity(const char *patt, int pattlen, bool case_insensitive, * Check whether char is a letter (and, hence, subject to case-folding) * * In multibyte character sets or with ICU, we can't use isalpha, and it does - * not seem worth trying to convert to wchar_t to use iswalpha. Instead, just - * assume any multibyte char is potentially case-varying. + * not seem worth trying to convert to wchar_t to use iswalpha or u_isalpha. + * Instead, just assume any non-ASCII char is potentially case-varying, and + * hard-wire knowledge of which ASCII chars are letters. */ static int pattern_char_isalpha(char c, bool is_multibyte, @@ -1449,7 +1450,8 @@ pattern_char_isalpha(char c, bool is_multibyte, else if (is_multibyte && IS_HIGHBIT_SET(c)) return true; else if (locale && locale->provider == COLLPROVIDER_ICU) - return IS_HIGHBIT_SET(c) ? true : false; + return IS_HIGHBIT_SET(c) || + (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); #ifdef HAVE_LOCALE_T else if (locale && locale->provider == COLLPROVIDER_LIBC) return isalpha_l((unsigned char) c, locale->info.lt); |