SET client_min_messages = warning; CREATE EXTENSION IF NOT EXISTS icu_parser CASCADE; -- icu_normalize passes tokens it changes on to the next dictionary, and returns NULL for the rest SELECT input, ts_lexize('icu_normalize', input) FROM (VALUES ('plain'), ('Café'), ('McDonald''s'), ('McDonald’s'), ('セブン'), ('ABC123'), ('㈱'), (U&'\0E19\0E4D\0E32'), (U&'\0E99\0ECD\0EB2'), ('น้ำ'), ('’')) v(input); input | ts_lexize --------------+------------- plain | Café | McDonald's | {McDonalds} McDonald’s | {McDonalds} セブン | {セブン} ABC123 | {ABC123} ㈱ | {(株)} นํา | {นำ} ນໍາ | {ນຳ} น้ำ | ’ | {} (11 rows) -- icu_search chains icu_normalize, unaccent and simple (ts_debug shows only the first dictionary's output) SELECT to_tsvector('icu_search', 'McDonald’s Café セブンイレブン Пятёрочка ร้านอาหาร ABC123'); to_tsvector ------------------------------------------------------------------------------------------- 'abc123':8 'cafe':2 'mcdonalds':1 'пятерочка':5 'ร้าน':6 'อาหาร':7 'イレブン':4 'セブン':3 (1 row) -- Names match regardless of accents, apostrophes, ё/е and character width SELECT q, name, to_tsvector('icu_simple', name) @@ phraseto_tsquery('icu_simple', q) AS icu_simple, to_tsvector('icu_search', name) @@ phraseto_tsquery('icu_search', q) AS icu_search FROM (VALUES ('mcdonalds', 'McDonald''s'), ('mcdonalds', 'McDonald’s Restaurant'), ('cafe', 'Café Müller'), ('café', 'Cafe Central'), ('пятёрочка', 'Пятерочка'), ('ラーメン', 'ラーメン屋'), ('abc', 'ABCストア'), ('ร้านอาหาร', 'ร้านอาหารครัวไทย'), ('อาหาร', 'ร้านอาหาร'), ('अस्पताल', 'सिटी अस्पताल'), ('セブンイレブン', 'セブン-イレブン渋谷店'), ('中国银行', '中国银行北京分行')) v(q, name); q | name | icu_simple | icu_search ----------------+-----------------------+------------+------------ mcdonalds | McDonald's | f | t mcdonalds | McDonald’s Restaurant | f | t cafe | Café Müller | f | t café | Cafe Central | f | t пятёрочка | Пятерочка | f | t ラーメン | ラーメン屋 | f | t abc | ABCストア | f | t ร้านอาหาร | ร้านอาหารครัวไทย | t | t อาหาร | ร้านอาหาร | t | t अस्पताल | सिटी अस्पताल | t | t セブンイレブン | セブン-イレブン渋谷店 | t | t 中国银行 | 中国银行北京分行 | t | t (12 rows) -- Headlines keep the original text SELECT ts_headline('icu_search', 'McDonald’s Café, Zürich', phraseto_tsquery('icu_search', 'mcdonalds cafe')); ts_headline --------------------------------------- McDonald’s Café, Zürich (1 row) -- The dictionary takes no options CREATE TEXT SEARCH DICTIONARY icu_normalize_bad (TEMPLATE = icu_normalize_template, form = 'nfc'); ERROR: unrecognized icu_normalize parameter: "form"