byteaデータ型はバイナリ列の保存を可能にします。 表8-6を参照してください。
バイナリ文字列はオクテット(またはバイト)の連続です。 バイナリ文字列が文字列と異なる点は次の2点です。 1点目は、バイナリ文字列はゼロの値のオクテットと他の"表示できない"オクテット(通常32から126の範囲外のオクテット)を保存できるということです。 文字列ではゼロというオクテットは使用できません。 また、データベースで選択している文字セット符号化方式で無効なオクテット値やオクテット値の並びも使用できません。 2点目は、バイナリ文字列を演算すると実際のバイトが処理されるのに対して、文字列の処理はロケール設定に従うということです。 まとめると、バイナリ文字列はプログラマが"バイト列そのもの"と考えるものを格納するのに適し、文字列はテキストを格納するのに適しています。
bytea値を入力する際に、特定の値のオクテットをSQL文内の文字列リテラルの一部として使用するには、そのオクテットをエスケープする必要があります(なお、全てのオクテットの値をエスケープすることができます)。 一般的にあるオクテットをエスケープするには、その10進オクテット値に等しい3桁の8進番号に変換し、2つのバックスラッシュを前に付けます。 表8-7には、エスケープする必要がある文字と、その適用可能な代替エスケープシーケンスを示しています。
表 8-7. オクテットをエスケープしたbyteaリテラル
10進オクテット値 | 説明 | エスケープされた入力表現 | 例 | 出力表現 |
---|---|---|---|---|
0 | ゼロオクテット | E'\\000' | SELECT E'\\000'::bytea; | \000 |
39 | 単一引用符 | ''''もしくはE'\\047' | SELECT E'\''::bytea; | ' |
92 | バックスラッシュ | E'\\\\'もしくはE'\\134' | SELECT E'\\\\'::bytea; | \\ |
0 to 31 and 127 to 255 | "表示できない"オクテット | E'\\xxx' (8進数) | SELECT E'\\001'::bytea; | \001 |
実際には、"表示できない"オクテットに対するエスケープ要求はロケールの設定に依存して変化します。 インスタンスによっては、エスケープをしないで済むこともあります。 表8-7の例の各結果は、ゼロオクテットとバックスラッシュの出力表現が1文字以上であっても、長さは正確に1オクテットであることに注意してください。
表8-7で示したように、多くのバックスラッシュを付けなければならない理由は、文字列リテラルとして記述された入力文字列は、PostgreSQLサーバ上で2つの解析段階を通過する必要があることです。 各組み合わせの最初のバックスラッシュは文字列リテラル用パーサでエスケープ文字と解釈(エスケープ文字列構文の使用を前提)され、2番目のバックスラッシュを残して、そこで消費されます。 (この段階のエスケープを避けるためにドル引用符による文字列を使用することができます。) 残りのバックスラッシュは、bytea入力関数が3桁のオクテット値の先頭に付く記号、もしくは、他のバックスラッシュをエスケープする記号として認識します。 例えば、E'\\001'としてサーバに渡された文字列リテラルは、エスケープ文字列パーサを通過した後\001のようになります。 \001はその後bytea入力関数に送られ、10進数値1の1つのオクテットに変換されます。 単一引用符文字はbyteaでは特別に扱われず、通常の文字列リテラルの規則に従うことに注意してください (項4.1.2.1も参照してください)。
また、Byteaオクテットは出力時もエスケープされます。 一般的には、各"表示できない"オクテットは、1つのバックスラッシュの後に等価な3桁8進数という形に変換されます。 ほとんどの"表示できる"オクテットは、クライアント文字セットにおける標準表現で表されます。 10進数で92となるオクテット(バックスラッシュ)は、別の特別な出力表現となります。 詳細は表8-8に示します。
表 8-8. bytea出力のエスケープされたオクテット
10進オクテット値 | 説明 | エスケープされた出力表現 | 例 | 出力結果 |
---|---|---|---|---|
92 | バックスラッシュ | \\ | SELECT E'\\134'::bytea; | \\ |
0から31および127から255 | "表示できない"オクテット | \xxx(8進数) | SELECT E'\\001'::bytea; | \001 |
32から126 | "表示できる"オクテット | クライアント文字セットにおける表現 | SELECT E'\\176'::bytea; | ~ |
使用するPostgreSQLのフロントエンドによっては、bytea文字列をエスケープまたはアンエスケープする際に、追加的な作業が必要になることがあります。 例えば、使用するインタフェースが改行文字や復帰文字を自動的に翻訳してしまう場合、これらの文字もエスケープしなければなりません。
標準SQLでは、BLOBまたはBINARY LARGE OBJECTという異なるバイナリ文字列型を定義しています。 入力書式はbyteaと異なりますが、用意されている関数および演算子はほとんど同じです。