web-dev-qa-db-ja.com

PostgreSQLはICU照合のオプションと設定をサポートしていますか?

ICUは異なる LDML照合順序設定 を指定します。それらのいくつかは、特にケースやアクセントに関するものなど、かなり興味深いようです。

  • 「アクセントを無視する」:strength=primary
  • 「アクセントを無視する」が大文字と小文字を区別します:strength=primary caseLevel=on
  • 「大文字と小文字を区別しない」:strength=secondary
  • 「句読点を無視する」(完全に):strength=tertiary alternate=shifted
  • 「句読点を無視する」が句読点を区別する:strength=quaternary alternate=shifted潜在的に何をするためのより良い方法

ここに記載されているこれらの も確認できます 。これらはICUオプションと設定が PostgreSQL 10で可能ですか?)ICU照合サポート

CREATE COLLATION special (provider = icu, locale = 'en@strength=primary');
SELECT 'Å' LIKE 'A' COLLATE "special"; # returns false

CLDR BCP47 も試しました

ICU 54以降、照合属性は、古いロケール拡張構文( "el@colCaseFirst=upper ")または言語タグ構文(" el-u-kf-upper ")。キーワードと値は大文字と小文字を区別しません。 LDML照合仕様、照合設定 、有効な照合キーワードとその値をリストした データファイル (非推奨の属性kh/colHiraganaQuaternaryおよびvt/variableTopはサポートされていません。)

そのため、これは正しく見えました

CREATE COLLATION special (provider = icu, locale = 'en-ks-level1');
SELECT 'Å' LIKE 'A' COLLATE "special"; # returns false

また試してみましたen-u-ks-level1そのメソッドは、ドキュメントの目的のようです。

CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk');
3
Evan Carroll

大文字と小文字を区別しない、またはアクセントを区別しない照合は、PostgreSQL 12より前では使用できません。内部でPostgreSQLは、異なるバイナリ表現の文字列は等しくないと見なしているためです。照合対応コンパレータが等しいと言った場合、照合非対応strcmp()関数を tie-breaker として使用して、Unicodeが呼び出すものを取得します 「確定的」比較 正規化なし。

PostgreSQL 12以降、照合順序にはdeterministicプロパティがあり、これはfalseに設定する必要があります。非バイナリの等しい文字列。から CREATE COLLATION

確定的

照合で確定的比較を使用するかどうかを指定します。デフォルトはtrueです。確定的比較では、バイト単位で等しくない文字列は、比較によって論理的に等しいと見なされても、等しくないと見なされます。 PostgreSQLは、バイト単位の比較を使用して関係を解除します。確定的でない比較では、照合で、たとえば、大文字と小文字やアクセントを区別しません。そのためには、適切なLC_COLLATE設定を選択し、照合順序をここで決定的でないように設定する必要があります。

非決定的照合は、ICUプロバイダーでのみサポートされています。

質問の正確なクエリは、LIKEまたは任意の形式のパターンマッチング(PostgreSQL 12以降)をサポートしていないため、非決定的照合では不可能です。また、ロケールには-u-照合サブタグの前。それ以外の場合、照合によって無視されます。

意図したとおりに機能するもの:

=# CREATE COLLATION special (
     provider = icu, locale = 'en-u-ks-level1', deterministic=false
   );

=# SELECT 'Å' = 'A' COLLATE "special";
 ?column? 
----------
 t
7
Daniel Vérité