summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/like.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/like.c')
-rw-r--r--src/backend/utils/adt/like.c53
1 files changed, 25 insertions, 28 deletions
diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c
index 8d9d285fb55..1f683ccd0f7 100644
--- a/src/backend/utils/adt/like.c
+++ b/src/backend/utils/adt/like.c
@@ -96,7 +96,7 @@ SB_lower_char(unsigned char c, pg_locale_t locale, bool locale_is_c)
return pg_ascii_tolower(c);
#ifdef HAVE_LOCALE_T
else if (locale)
- return tolower_l(c, locale);
+ return tolower_l(c, locale->info.lt);
#endif
else
return pg_tolower(c);
@@ -165,14 +165,36 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
*p;
int slen,
plen;
+ pg_locale_t locale = 0;
+ bool locale_is_c = false;
+
+ if (lc_ctype_is_c(collation))
+ locale_is_c = true;
+ else if (collation != DEFAULT_COLLATION_OID)
+ {
+ if (!OidIsValid(collation))
+ {
+ /*
+ * This typically means that the parser could not resolve a
+ * conflict of implicit collations, so report it that way.
+ */
+ ereport(ERROR,
+ (errcode(ERRCODE_INDETERMINATE_COLLATION),
+ errmsg("could not determine which collation to use for ILIKE"),
+ errhint("Use the COLLATE clause to set the collation explicitly.")));
+ }
+ locale = pg_newlocale_from_collation(collation);
+ }
/*
* For efficiency reasons, in the single byte case we don't call lower()
* on the pattern and text, but instead call SB_lower_char on each
- * character. In the multi-byte case we don't have much choice :-(
+ * character. In the multi-byte case we don't have much choice :-(.
+ * Also, ICU does not support single-character case folding, so we go the
+ * long way.
*/
- if (pg_database_encoding_max_length() > 1)
+ if (pg_database_encoding_max_length() > 1 || locale->provider == COLLPROVIDER_ICU)
{
/* lower's result is never packed, so OK to use old macros here */
pat = DatumGetTextPP(DirectFunctionCall1Coll(lower, collation,
@@ -190,31 +212,6 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation)
}
else
{
- /*
- * Here we need to prepare locale information for SB_lower_char. This
- * should match the methods used in str_tolower().
- */
- pg_locale_t locale = 0;
- bool locale_is_c = false;
-
- if (lc_ctype_is_c(collation))
- locale_is_c = true;
- else if (collation != DEFAULT_COLLATION_OID)
- {
- if (!OidIsValid(collation))
- {
- /*
- * This typically means that the parser could not resolve a
- * conflict of implicit collations, so report it that way.
- */
- ereport(ERROR,
- (errcode(ERRCODE_INDETERMINATE_COLLATION),
- errmsg("could not determine which collation to use for ILIKE"),
- errhint("Use the COLLATE clause to set the collation explicitly.")));
- }
- locale = pg_newlocale_from_collation(collation);
- }
-
p = VARDATA_ANY(pat);
plen = VARSIZE_ANY_EXHDR(pat);
s = VARDATA_ANY(str);