Skip to content

Commit 886cf85

Browse files
committed
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 eccfef8), so back-patch to v10 where that came in. Discussion: https://postgr.es/m/15892-e5d2bea3e8a04a1b@postgresql.org
1 parent b3670f4 commit 886cf85

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

src/backend/utils/adt/selfuncs.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5564,9 +5564,10 @@ find_join_input_rel(PlannerInfo *root, Relids relids)
55645564
/*
55655565
* Check whether char is a letter (and, hence, subject to case-folding)
55665566
*
5567-
* In multibyte character sets or with ICU, we can't use isalpha, and it does not seem
5568-
* worth trying to convert to wchar_t to use iswalpha. Instead, just assume
5569-
* any multibyte char is potentially case-varying.
5567+
* In multibyte character sets or with ICU, we can't use isalpha, and it does
5568+
* not seem worth trying to convert to wchar_t to use iswalpha or u_isalpha.
5569+
* Instead, just assume any non-ASCII char is potentially case-varying, and
5570+
* hard-wire knowledge of which ASCII chars are letters.
55705571
*/
55715572
static int
55725573
pattern_char_isalpha(char c, bool is_multibyte,
@@ -5577,7 +5578,8 @@ pattern_char_isalpha(char c, bool is_multibyte,
55775578
else if (is_multibyte && IS_HIGHBIT_SET(c))
55785579
return true;
55795580
else if (locale && locale->provider == COLLPROVIDER_ICU)
5580-
return IS_HIGHBIT_SET(c) ? true : false;
5581+
return IS_HIGHBIT_SET(c) ||
5582+
(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
55815583
#ifdef HAVE_LOCALE_T
55825584
else if (locale && locale->provider == COLLPROVIDER_LIBC)
55835585
return isalpha_l((unsigned char) c, locale->info.lt);

src/test/regress/expected/collate.icu.utf8.out

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,38 @@ SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_t
976976
collate_test1_idx4 | CREATE INDEX collate_test1_idx4 ON collate_tests.collate_test1 USING btree (((b || 'foo'::text)) COLLATE "POSIX")
977977
(4 rows)
978978

979+
set enable_seqscan = off;
980+
explain (costs off)
981+
select * from collate_test1 where b ilike 'abc';
982+
QUERY PLAN
983+
-------------------------------
984+
Seq Scan on collate_test1
985+
Filter: (b ~~* 'abc'::text)
986+
(2 rows)
987+
988+
select * from collate_test1 where b ilike 'abc';
989+
a | b
990+
---+-----
991+
1 | abc
992+
4 | ABC
993+
(2 rows)
994+
995+
explain (costs off)
996+
select * from collate_test1 where b ilike 'ABC';
997+
QUERY PLAN
998+
-------------------------------
999+
Seq Scan on collate_test1
1000+
Filter: (b ~~* 'ABC'::text)
1001+
(2 rows)
1002+
1003+
select * from collate_test1 where b ilike 'ABC';
1004+
a | b
1005+
---+-----
1006+
1 | abc
1007+
4 | ABC
1008+
(2 rows)
1009+
1010+
reset enable_seqscan;
9791011
-- schema manipulation commands
9801012
CREATE ROLE regress_test_role;
9811013
CREATE SCHEMA test_schema;

src/test/regress/sql/collate.icu.utf8.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,15 @@ CREATE INDEX collate_test1_idx6 ON collate_test1 ((a COLLATE "C")); -- fail
333333

334334
SELECT relname, pg_get_indexdef(oid) FROM pg_class WHERE relname LIKE 'collate_test%_idx%' ORDER BY 1;
335335

336+
set enable_seqscan = off;
337+
explain (costs off)
338+
select * from collate_test1 where b ilike 'abc';
339+
select * from collate_test1 where b ilike 'abc';
340+
explain (costs off)
341+
select * from collate_test1 where b ilike 'ABC';
342+
select * from collate_test1 where b ilike 'ABC';
343+
reset enable_seqscan;
344+
336345

337346
-- schema manipulation commands
338347

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy