bytea はバイナリ列の保存を可能にします。Table 5-6 を参照してください。
バイナリ文字列はオクテット (またはバイト) の連続です。 バイナリ文字列が、文字列と異なる点は次の 2 点です。 1 点目は、バイナリ文字列はゼロの値のオクテットと他の「表示できない」オクテットを保存できるということです。 2 点目は、バイナリ文字列を演算すると実際のバイトが処理されるのに対して、文字列のエンコードおよび処理はロケール設定に従うということです。
bytea 値を入力する際に、特定の値のオクテットを SQL 命令文内の文字列リテラルの一部として使用するには、そのオクテットをエスケープする必要があります (なお、すべてのオクテットの値をエスケープすることも可能です)。一般的にあるオクテットをエスケープするには、その 10 進オクテット値に等しい 3 桁の 8 進番号に変換し、2 つの逆スラッシュを前に付けます。Table 5-7 で示されているようにいくつかの値には代わりのエスケープシーケンスがあります。
Table 5-7. オクテットをエスケープした bytea リテラル
10 進オクテット値 | 説明 | 入力がエスケープされた表現 | 例 | 表示された結果 |
---|---|---|---|---|
0 | ゼロオクテット | '\\000' | SELECT '\\000'::bytea; | \000 |
39 | 単純引用符 | '\'' または '\\047' | SELECT '\''::bytea; | ' |
92 | 逆スラッシュ | '\\\\' または '\\134' | SELECT '\\\\'::bytea; | \\ |
Table 5-7 の例のそれぞれの結果は、ゼロオクテットと逆スラッシュの出力表現が 1 文字以上であっても、長さは正確に 1 オクテットであることに注意してください。bytea 出力オクテットも同様にエスケープされます。一般的に、それぞれの「表示できない」オクテット 10 進値はそれと等しい 3 桁の 8 進数値に変換され、1 つのバックスラッシュがその前に付きます。ほとんどの「表示可能な」オクテットはクライアントの文字セットにある標準表現により表現されます。10 進数 92 (バックスラッシュ)のオクテットには特別な代替の出力表現があります。詳細は Table 5-8 を参照してください。
Table 5-8. オクテットをエスケープした bytea 出力
10 進オクテット値 | 説明 | 出力がエスケープされた表現 | 例 | 表示された結果 |
---|---|---|---|---|
92 | 逆スラッシュ | \\ | SELECT '\\134'::bytea; | \\ |
0 〜 31 および 127 〜 255 | "表示できない"オクテット | \### (8 進数値) | SELECT '\\001'::bytea; | \001 |
32 から 126 | "表示できる"オクテット | ASCII 表現 | SELECT '\\176'::bytea; | ~ |
PostgreSQL サーバでは構文解析を 2 度通過する必要があるため、オクテットをエスケープした bytea 表記を使用するには、文字列リテラル (入力文字列) に逆スラッシュを 2 つ含める必要があります。 最初の逆スラッシュは文字列リテラル解析でエスケープ文字と解釈され、後に続く文字を残して、そこで消費されます。残りの逆スラッシュは、bytea 入力関数が 3 桁のオクテット値の先頭に付く記号と認識します。例えば、'\\001'としてバックエンドに渡された文字列リテラルは、文字列リテラル構文解析を通過した後 '\001' のようになります。'\001' はそこで bytea 入力関数に送られ、10 進数値 1 の 1 つのオクテットに変換されます。
似たような理由から、逆スラッシュは '\\\\'(もしくは '\\134')のように入力されなければなりません。最初と 3 番目の逆スラッシュはリテラル文字列構文解析でエスケープ文字と解釈され、2 つの逆スラッシュを bytea 入力関数に渡される文字列の中に残し、そして消費された後、bytea 入力関数が単一の逆スラッシュによる表現と解釈します。 例えば、'\\\\' としてサーバに渡された文字列リテラルは、文字列リテラル構文解析を通過した後 '\\' になります。'\\' はそこで bytea 入力関数に送られて、10 進数値 92 の 1 つのオクテットに変換されます。
単一引用符は '\\'' ではなく、'\'' (もしくは '\\047') のように入力されなければない点で多少の違いがあります。その理由はリテラル構文解析が単一引用符を特殊文字と解釈し、1 つのバックスラッシュ文字を消費し、bytea 入力関数が単一引用符を特別なオクテットと認識しません。したがって、'\'' としてバックエンドに渡される文字列リテラルは文字列リテラル構文解析を通過した後 ''' になります。その ''' はそこで bytea 入力関数に送られ、単一の 39 オクテット 10 進数値を所有します。
お使いになっている PostgreSQL のフロントエンドによっては、bytea 文字列をエスケープまたはアンエスケープする際に、追加的な作業が必要になることがあります。例えば、使っているインターフェイスが改行文字や復帰文字をそのまま翻訳するのであれば、これら文字もエスケープされなければなりません。あるいは、使用している言語または選択している環境がバックスラッシュをエスケープ文字として取り扱うのであれば二重にする必要があるかもしれません。
SQL 標準では、BLOB または BINARY LARGE OBJECT という異なるバイナリ列データ型を定義しています。入力形式は bytea と異なりますが、用意されている関数および演算子はほとんど同じです。