8.4. バイナリ列データ型

byteaデータ型はバイナリ列の保存を可能にします。 表8-6を参照してください。

表 8-6. バイナリ列データ型

型名格納サイズ説明
bytea4バイトと実際のバイナリ列の長さ可変長のバイナリ文字列

バイナリ文字列はオクテット(またはバイト)の連続です。 バイナリ文字列が、文字列と異なる点は次の2点です。 1点目は、バイナリ文字列はゼロの値のオクテットと他の"表示できない"オクテット(32から126の範囲外のオクテットとして定義されています)を保存できるということです。 2点目は、バイナリ文字列を演算すると実際のバイトが処理されるのに対して、文字列の符号化および処理はロケール設定に従うということです。

bytea値を入力する際に、特定の値のオクテットをSQL文内の文字列リテラルの一部として使用するには、そのオクテットをエスケープする必要があります(なお、すべてのオクテットの値をエスケープしても構いません)。 一般的にあるオクテットをエスケープするには、その10進オクテット値に等しい3桁の8進番号に変換し、2つのバックスラッシュを前に付けます。 表8-7には、エスケープする必要がある文字と、その代替エスケープシーケンスを示しています。

表 8-7. オクテットをエスケープしたbyteaリテラル

10進オクテット値説明エスケープされた入力表現出力表現
0ゼロオクテット'\\000'SELECT '\\000'::bytea;\000
39単一引用符'\'' もしくは '\\047'SELECT '\''::bytea;'
92バックスラッシュ'\\\\' もしくは '\\134'SELECT '\\\\'::bytea;\\
0 to 31 and 127 to 255"表示できない"オクテット'\\xxx' (8進数)SELECT '\\001'::bytea;\001

実際には、"表示できない"オクテットに対するエスケープ要求はロケールの設定に依存して変化します。 インスタンスによっては、エスケープをしないで済むこともあります。 表8-7の例の各結果は、ゼロオクテットとバックスラッシュの出力表現が1文字以上であっても、長さは正確に1オクテットであることに注意してください。

表8-7で示したように、多くのバックスラッシュを付けなければならない理由は、 文字列リテラルとして記述された入力文字列は、PostgreSQLサーバ上で2つの解析段階を通貨する必要があることです。 各組合せの最初のバックスラッシュは文字列リテラル用パーサでエスケープ文字と解釈され、2番目のバックスラッシュを残して、そこで消費されます。 残りのバックスラッシュは、bytea入力関数が3桁のオクテット値の先頭に付く記号、もしくは、他のバックスラッシュをエスケープする記号として認識します。 例えば、'\\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 '\\134'::bytea;\\
0から31および127から255"表示できない"オクテット\xxx (8進数)SELECT '\\001'::bytea;\001
32から126"表示できる"オクテットクライアント文字セットにおける表現SELECT '\\176'::bytea;~

使用するPostgreSQLのフロントエンドによっては、bytea文字列をエスケープまたはアンエスケープする際に、追加的な作業が必要になることがあります。 例えば、使用するインタフェースが改行文字や復帰文字を自動的に翻訳してしまう場合、これら文字もエスケープしなければなりません。

標準SQLでは、BLOBまたはBINARY LARGE OBJECTという異なるバイナリ文字列型を定義しています。 入力書式はbyteaと異なりますが、用意されている関数および演算子はほとんど同じです。