照合機能は、ソート順番と列ごともしくは操作ごとのデータの文字区別の振る舞いを指定することを許可します。
これは、作成後のデータベースのLC_COLLATE
とLC_CTYPE
の設定が変更できない制限を緩和します。
概念的に照合可能なデータ型のそれぞれの式は、照合を保持しています
(ビルトインされている照合可能なデータ型はtext
、varchar
、 char
です。
ユーザ定義の基本型は照合可能とマーキングできます。もちろん照合可能なデータ型上のドメインは照合可能となります)。
もし、式が列参照である場合は、式の照合は列の定義された照合となります。
もし、式が定数である場合は、照合は定数のデータ型のデフォルトの照合となります。
より複雑な式の照合は、下記に示すように、その入力の照合から引き出されます。
式の照合は、「default」照合となります。これはデータベースに対して定義されたロケール設定を意味しています。 式の照合は非決定となることもあります。そのような場合に、照合が必要となるような順序操作や他の操作は失敗するでしょう。
データベースシステムが並び変えや文字区別を行う場合、データベースは入力の照合を使用します。
これは、たとえばORDER BY
句や<
演算子や関数を使用する際に発生します。
ORDER BY
句に適用する照合は、単純にソートキーの照合です。
関数や演算子の呼び出しに対して適用される照合は、以下に述べるように引数により決まります。
比較演算子に加えて、照合はlower
、upper
、initcap
といった小文字と大文字を変換する関数やパターンマッチングの演算子、to_char
関連の関数で考慮されています。
関数や演算子の呼び出しに対して、引数の照合検査により得られた照合は実行時に特定の操作を行うために使用されます。 もし関数や演算子の呼び出しの結果が照合可能なデータ型であった場合、照合は関数もしくは演算子式の定義済みの照合として 解析時にも試用されます。このとき照合の知識が必要となるような囲み式があります。
式の照合の導出は暗黙でも明示的にでも可能です。
この区別は、複数の異なる照合が式中に現れるときに照合がどのように組み合わされるか、に影響を与えます。
明示的な照合の導出は、COLLATE
句が使用されたときに発生します。
他の全ての照合は暗黙となります。例えば関数呼び出しの中では、次の規則が用いられます。
入力式に明示的な照合の導出がある場合、入力式の中の明示的に導出された全ての照合は同一でなくてはなりません。 そうでない場合はエラーが発生します。もし明示的に導出された照合がある場合は、それは照合の組み合わせの結果となります。
そうでない場合は、全ての入力式は同一の暗黙の照合の導出またはデフォルトの照合を持たなくてはなりません。 もしデフォルトではない照合がある場合は、それは照合の組み合わせの結果となります。 もしそうでない場合は、結果はデフォルトの照合となります。
入力式内でデフォルトではない暗黙の照合が衝突している場合、決定不能な照合であるとみなされます。 これは、もし呼び出された特定の関数が適用するべき照合を知っておく必要がないかぎりエラーの条件ではありません。 もし知っておく必要がある場合は、実行時にエラーとなります。
例えば、このテーブル定義を考えてみます。
CREATE TABLE test1 ( a text COLLATE "de_DE", b text COLLATE "es_ES", ... );
このとき
SELECT a < 'foo' FROM test1;
<
の比較はde_DE
の規則により実行されます。
というのも式は暗黙的に導出されたデフォルトの照合と組み合わせます。しかし、
SELECT a < ('foo' COLLATE "fr_FR") FROM test1;
このとき比較は、明示的な照合の導出は暗黙の照合をオーバライドするためfr_FR
規則が用いられます。
さらに、次の例では
SELECT a < b FROM test1;
パーサはどの照合を適用するか決定できません。というのもa
とb
列は暗黙の衝突する照合を持つためです。
<
演算子がどちらの照合を使用するか知る必要があるため、これはエラーとなります。
SELECT a < b COLLATE "de_DE" FROM test1;
もしくは同じく
SELECT a COLLATE "de_DE" < b FROM test1;
一方で、以下のように構造的に似たケースとして
SELECT a || b FROM test1;
これはエラーとなりません。というのも||
演算子は、照合には関係がないためです。
この結果は照合とは関係なく同じになります。
もし関数や演算子が照合可能なデータ型の結果を出力する場合は、関数に割り当てられた照合、もしくは演算子の組み合わされた入力式は、関数もしくは演算子の結果に対しても 適用されると考えられます。よって、以下の例では
SELECT * FROM test1 ORDER BY a || 'foo';
順序はde_DE
規則に基づき実行されますが、以下のクエリでは
SELECT * FROM test1 ORDER BY a || b;
エラーとなります。というのも||
演算子が照合を知る必要がなかったとしても
ORDER BY
句が照合を知る必要があるためです。
以前と同様、この衝突は明示的に照合を指定することにより解決できます。
SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";
照合は、SQL名称とオペレーティングシステムのロケールをマッピングするSQLスキーマオブジェクトです。
特に照合はLC_COLLATE
とLC_CTYPE
の組み合わせにマッピングします。
(名称から推測されるように、照合の主な目的はソート順番を制御するLC_COLLATE
を設定することです。
しかし実際にはLC_CTYPE
の設定をLC_COLLATE
と異なるようにする必要はほとんどありません。
そのため、式ごとにLC_CTYPE
を設定するような別の機構を作成するより、これらの設定を収集する方が、より便利です。)
また、照合は文字エンコーディングと結びついています(22.3. 文字セットサポートを参照下さい)。
同一の照合名称は異なるエンコーディングに対して存在しています。
すべてのプラットフォーム上でdefault
、C
そしてPOSIX
という名称の照合が
利用できます。追加の照合はオペレーティングシステムにより利用可能となります。
default
照合は、データベース作成時にLC_COLLATE
値とLC_CTYPE
値を
選択します。C
とPOSIX
照合は共に「traditional C」の動作を指定します。
これはASCII文字の「A
」から「Z
」を文字として扱い、文字コードのバイト値により
厳密にソートします。
もし、オペレーティングシステムが単一のプログラム内(newlocale
や関連する関数)で複数のロケールを使用することをサポートしている場合、
データベースクラスタが初期化されるとinitdb
は、オペレーティングシステム上で見つけた全てのロケールに基づく照合を
システムカタログのpg_collation
に書き込みます。
例えば、オペレーティングシステムがde_DE.utf8
の名称のロケールを提供した場合、
initdb
は、de_DE.utf8
に設定されたLC_COLLATE
とLC_CTYPE
の両方を持つUTF8
エンコーディングのde_DE.utf8
という名称の照合を作成します。
同時に照合の名称から.utf8
を削除した照合も作成します。これは手間を省き、名称がエンコーディングに依存しないようになります。
いうまでもなく、照合名称の初期値はプラットフォーム依存となることに気をつけてください。
LC_COLLATE
とLC_CTYPE
に対して異なる値が必要な照合の場合のために、
新規の照合がCREATE COLLATIONコマンドにより作成されます。
このコマンドは、既存の照合から新規の照合を作成するためにも使用されます。これはアプリケーションにおいて
オペレーティングシステムに依存しない照合名を使用でき、便利です。
特定のデータベース内でデータベースのエンコーディングを使用している照合のみが興味の対象となります。
pg_collation
内の他のエントリは無視されます。
よってde_DE
といったようなエンコーディング名が省かれた照合は、包括的に一意でなくてもデータベース内で一意であるとみなされます。
データベースのエンコーディングを変更するときに、変更すべきものを1つ減らすことになるため、エンコーディング名が省かれた照合を使用するようにしてください。
default
、C
そしてPOSIX
照合は、データベースのエンコーディングに関係なく使用可能です。
PostgreSQLは、異なる照合オブジェクトは、それらが同じプロパティを持っていても 互換性がないものとみなします。例えば、
SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1;
は、C
とPOSIX
照合が同じ動作であってもエラーとなります。
よってエンコーディング名が省かれた照合を混ぜて使用することは推奨されません。