bytea はバイナリ列の保存を可能にします。
バイナリ列は文字セットあるいはそれと結び付く照合機構を持たないオクテットの数列です。bytea はゼロの値のオクテットと他の「表示できない」オクテットを特に保存するものです。
SQL 命令文で文字列リテラルの一部として使用される時、ある値のオクテットは必ずエスケープされなければなりません(すべてのオクテット値をエスケープしても構いません)。一般的にあるオクテットをエスケープするには、その10 進オクテット値に等しい 3 桁の 8 進番号に変換し、2 つの逆スラッシュを前に付けます。Table 3-7 で示されているようにいくつかの値には代わりのエスケープシーケンスがあります。
Table 3-7. オクテットをエスケープした SQL リテラル
10 進オクテット値 | 説明 | 入力がエスケープされた表現 | 例 | 表示された結果 |
---|---|---|---|---|
0 | ゼロオクテット | '\\000' | select '\\000'::bytea; | \000 |
39 | 単純引用符 | '\\'' または '\\047' | select '\''::bytea; | ' |
92 | 逆スラッシュ | '\\\\' または '\\134' | select '\\\\'::bytea; | \\ |
上記の例のそれぞれの結果は、ゼロオクテットと逆スラッシュの出力表現が 1 文字以上であっても、長さは正確に 1 オクテットであることに注意してください。bytea 出力オクテットも同様にエスケープされます。一般的に、それぞれの「表示できない」オクテット 10 進値はそれと等しい 3 桁の 8 進数値に変換され、1 つのバックスラッシュがその前に付きます。ほとんどの「表示可能な」オクテットはクライアントの文字セットにある標準表現により表現されます。10 進数 92 (バックスラッシュ)のオクテットには特別な代替の出力表現があります。詳細は Table 3-8 にあります。
Table 3-8. オクテットをエスケープした SQL 出力
10 進オクテット値 | 説明 | 出力がエスケープされた表現 | 例 | 表示された結果 |
---|---|---|---|---|
92 | 逆スラッシュ | \\ | select '\\134'::bytea; | \\ |
0 〜 31 および 127 〜 255 | "表示できない"オクテット | \### (8 進数値) | select '\\001'::bytea; | \001 |
32 〜 126 | "表示できる"オクテット | ASCII 表現 | select '\\176'::bytea; | ~ |
SQL の文字列リテラル(入力文字列)は PostgreSQL のバックエンドの 2 つの構文解析を通過しなければならないという事実により2 つの逆スラッシュが前に付いていなければなりません。最初の逆スラッシュは文字列リテラル解析でエスケープ文字と解釈され、次に続くオクテットを残して、そこで消費されます。残りの逆スラッシュは、 bytea 入力関数が 3 桁のオクテット値の先頭に付く記号と認識します。例えば、'\\001'としてバックエンドに渡された文字列リテラルは、文字列リテラル構文解析を通過した後 '\001' のようになります。 '\001' はそこで bytea 入力関数に送られ、10 進数値 1 の 1 つのオクテットに変換されます。
似たような理由から、逆スラッシュは '\\\\'(もしくは '\\134')のように入力されなければなりません。最初と 3 番目の逆スラッシュはリテラル文字列構文解析でエスケープ文字と解釈され、2 つの逆スラッシュを bytea 入力関数に渡される文字列の中に残し、そして消費された後、bytea 入力関数が単一の逆スラッシュによる表現と解釈します。例えば、 '\\\\' としてバックエンドに渡された文字列リテラルは、文字列リテラル構文解析を通過した後 '\\' になります。'\\' はそこで bytea 入力関数に送られて、10 進数値 92 の 1 つのオクテットに変換されます。
単一引用符は中身がちょっと違っていて '\\'' では 無く、'\'' (もしくは '\\134')のように入力されなければなりません。その理由はリテラル構文解析が単一引用符を特殊文字と解釈し、1 つのバックスラッシュ文字を消費し、bytea 入力関数が単一引用符を特別なオクテットと認識しません。したがって、'\'' としてバックエンドに渡される文字列リテラルは文字列リテラル構文解析を通過した後 ''' になります。その ''' はそこで bytea 入力関数に送られ、単一の 39 オクテット 10 進数値を所有します。
お使いになっている PostgreSQL のフロントエンドによっては、bytea 文字列をエスケープしたりしなかったりするにあたり、追加的な作業が必要になることがあります。例えば、使っているインターフェイスが改行文字や復帰文字をそのまま翻訳するのであれば、これら文字もエスケープされなければなりません。あるいは、使用している言語または選択している環境がバックスラッシュをエスケープ文字として取り扱うのであれば二重にする必要があるかもしれません。
bytea は SQL99 第 4.3 節によるバイナリ文字列型の機能のほとんどを提供します。SQL99 のバイナリ列と PostgreSQL の bytea の比較は Table 3-9 で示されています。
Table 3-9. SQL99 バイナリ文字列と PostgreSQL BYTEA データ型の比較
SQL99 | BYTEA |
---|---|
BINARY LARGE OBJECT または BLOB のデータ型名 | BYTEA のデータ型名 |
文字セットあるいはそれと結び付く照合機構を持たないオクテットの数列。 | 同じ |
オクテットの中のデータ型名と最大語長を含むバイナリデータ型記述子の記述による。 | 特定の最大語長のないデータ型を含むバイナリデータ型記述子の記述による。 |
比較属性のルールに従ってすべてのバイナリ列は基本的に比較可能。 | 同じ |
バイナリ文字列値は「等しい」のみ比較可能。 | バイナリ文字列は「等しい」、「大なり」、「以上」、「小なり」または「以下」で比較可能。 |
結合、部分文字列、オーバレイおよびトリムを含むバイナリ文字列に作用しそこからバイナリ列を返す演算子。 | 結合、部分文字列、オーバレイおよびトリムを含むバイナリ文字列に作用しそこからバイナリ列を返す演算子。トリムに対する 開始 と 終結 の引数は未だ実装されていません。 |
語長、配置および LIKE 記述を含むバイナリ列に関連したその他の演算子。 | 同じ |
バイナリ列リテラルは、例えば X'1a43fe' のように "X" で始まり、単純引用符で囲まれた16 進数の偶数個により構成されます。 | バイナリ文字列リテラルは Table 3-7 に示されたルールに基づいてエスケープされたオクテットで構成されます。 |