aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-08-12 13:15:48 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2019-08-12 13:15:48 -0400
commitc914e74d2dee0ecf372c1d40f87499d94d591935 (patch)
treeaa2eb47af4a4f2465c2639df4a9f8b2d34958e2b /src/backend
parentceb850d4a30c06f2f127487acd898847b80dcfc5 (diff)
downloadpostgresql-c914e74d2dee0ecf372c1d40f87499d94d591935.tar.gz
postgresql-c914e74d2dee0ecf372c1d40f87499d94d591935.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')
-rw-r--r--src/backend/utils/adt/selfuncs.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 8592e6cb87c..7622edb9dd4 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -5815,9 +5815,10 @@ find_join_input_rel(PlannerInfo *root, Relids relids)
/*
* 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.
+ * 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 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,
@@ -5828,7 +5829,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);