無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

22.2. 照合サポート

照合機能は、ソート順番と列ごともしくは操作ごとのデータの文字区別の振る舞いを指定することを許可します。 これは、作成後のデータベースの LC_COLLATE LC_CTYPE の設定が変更できない制限を緩和します。

22.2.1. 概念

概念的に照合可能なデータ型のそれぞれの式は、照合を保持しています (ビルトインされている照合可能なデータ型は text varchar char です。 ユーザ定義の基本型は照合可能とマーキングできます。もちろん照合可能なデータ型上のドメインは照合可能となります)。 もし、式が列参照である場合は、式の照合は列の定義された照合となります。 もし、式が定数である場合は、照合は定数のデータ型のデフォルトの照合となります。 より複雑な式の照合は、下記に示すように、その入力の照合から引き出されます。

式の照合は、 "default" 照合となります。これはデータベースに対して定義されたロケール設定を意味しています。 式の照合は非決定となることもあります。そのような場合に、照合が必要となるような順序操作や他の操作は失敗するでしょう。

データベースシステムが並び変えや文字区別を行う場合、データベースは入力の照合を使用します。 これは、たとえば ORDER BY 句や < 演算子や関数を使用する際に発生します。 ORDER BY 句に適用する照合は、単純にソートキーの照合です。 関数や演算子の呼び出しに対して適用される照合は、以下に述べるように引数により決まります。 比較演算子に加えて、照合は lower upper initcap といった小文字と大文字を変換する関数や パターンマッチングの演算子、 to_char 関連の関数で考慮されています。

関数や演算子の呼び出しに対して、引数の照合検査により得られた照合は実行時に特定の操作を行うために使用されます。 もし関数や演算子の呼び出しの結果が照合可能なデータ型であった場合、照合は関数もしくは演算子式の定義済みの照合として 解析時にも試用されます。このとき照合の知識が必要となるような囲み式があります。

式の 照合の導出 は暗黙でも明示的にでも可能です。 この区別は、複数の異なる照合が式中に現れるときに照合がどのように組み合わされるか、に影響を与えます。 明示的な照合の導出は、 COLLATE 句が使用されたときに発生します。 他の全ての照合は暗黙となります。例えば関数呼び出しの中では、次の規則が用いられます。

  1. 入力式に明示的な照合の導出がある場合、入力式の中の明示的に導出された全ての照合は同一でなくてはなりません。 そうでない場合はエラーが発生します。もし明示的に導出された照合がある場合は、それは照合の組み合わせの結果となります。

  2. そうでない場合は、全ての入力式は同一の暗黙の照合の導出またはデフォルトの照合を持たなくてはなりません。 もしデフォルトではない照合がある場合は、それは照合の組み合わせの結果となります。 もしそうでない場合は、結果はデフォルトの照合となります。

  3. 入力式内でデフォルトではない暗黙の照合が衝突している場合、決定不能な照合であるとみなされます。 これは、もし呼び出された特定の関数が適用するべき照合を知っておく必要がないかぎりエラーの条件ではありません。 もし知っておく必要がある場合は、実行時にエラーとなります。

例えば、このテーブル定義を考えてみます。

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";

22.2.2. 照合の管理

照合は、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 照合が同じ動作であってもエラーとなります。 よってエンコーディング名が省かれた照合を混ぜて使用することは推奨されません。


powered by SEO.CUG.NET