diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c index 350bc07f210..64147bc5b5c 100644 --- a/src/backend/utils/adt/like.c +++ b/src/backend/utils/adt/like.c @@ -191,12 +191,14 @@ Generic_Text_IC_like(text *str, text *pat, Oid collation) /* * For efficiency reasons, in the C locale we don't call lower() on the - * pattern and text, but instead lowercase each character lazily. + * pattern and text, but instead lowercase each character lazily. This + * only works for single-byte encodings, otherwise "_" may incorrectly + * match an incomplete byte sequence. * * XXX: use casefolding instead? */ - if (locale->ctype_is_c) + if (locale->ctype_is_c && pg_database_encoding_max_length() == 1) { p = VARDATA_ANY(pat); plen = VARSIZE_ANY_EXHDR(pat); diff --git a/src/test/regress/expected/collate.utf8.out b/src/test/regress/expected/collate.utf8.out index 99fdc111fa4..cdd1a37ba18 100644 --- a/src/test/regress/expected/collate.utf8.out +++ b/src/test/regress/expected/collate.utf8.out @@ -34,6 +34,13 @@ SELECT U&'\00C1\00E1' !~ '[[:alpha:]]' COLLATE regress_builtin_c; (1 row) DROP COLLATION regress_builtin_c; +-- a '_' matches a multibyte character +SELECT 'café' ILIKE 'caf_' COLLATE "C"; + ?column? +---------- + t +(1 row) + -- -- Test PG_C_UTF8 -- diff --git a/src/test/regress/sql/collate.utf8.sql b/src/test/regress/sql/collate.utf8.sql index 22aecee3a60..52cf068dd0c 100644 --- a/src/test/regress/sql/collate.utf8.sql +++ b/src/test/regress/sql/collate.utf8.sql @@ -26,6 +26,9 @@ SELECT U&'\00C1\00E1' !~ '[[:alpha:]]' COLLATE regress_builtin_c; DROP COLLATION regress_builtin_c; +-- a '_' matches a multibyte character +SELECT 'café' ILIKE 'caf_' COLLATE "C"; + -- -- Test PG_C_UTF8 --