更新: 質問の編集を参照してください。この回答は、uuid の一般的な 16 バイトのシリアル化に適用されます。Javaのシリアル化を反映するように質問が修正されました。
興味深い問題です。私はそれを効率的に行うために単純な C 拡張機能を作成することになりましたが、以下の PL/Python バージョンを使用する方がおそらく賢明です。
uuid
は固定サイズの型であり、可変長フィールド ヘッダーが邪魔になるため、単純にバイナリ強制することbytea
はvarlena
できません。create cast ... as implicit
bytea 入力が uuid を返す組み込み関数はありません。あると便利ですが、まだ誰もやっていないと思います。
最も簡単な方法
更新:実際にはこれを行う簡単な方法があります。in 16 形式は、 orなしのプレーンな装飾されていない 16 進数を受け入れるためbytea
、 が取り除かれると実際には有効な uuid リテラルです。これだけ:\x
uuid_in
-
{}
regress=> SET bytea_output = 'hex';
SET
regress=> SELECT CAST( substring(CAST (BYTEA '\x0FCC6350118D11E4A5597DE5338EB025' AS text) from 3) AS uuid);
substring
--------------------------------------
0fcc6350-118d-11e4-a559-7de5338eb025
(1 row)
これには、いくつかの文字列のコピーと 16 進のエンコード/デコード サイクルが含まれますが、以前に提案した PL の回答よりもはるかに高速ですが、C よりは遅くなります。
その他のオプション
個人的には、PL/Perl または pl/pythonu を使用することをお勧めします。私は例をフォローアップします。
uuid が 16 進形式のバイトリテラルであると仮定します。
'\x0FCC6350118D11E4A5597DE5338EB025'
uuid
次のタイプに変換できます。
PL/パール
create language plperlu;
create or replace function to_uuid(bytea) returns uuid language plperlu immutable as $$
use Data::UUID;
my $ug = new Data::UUID;
my $uuid = $ug->from_hexstring(substr($_[0],2));
return $ug->to_string($uuid);
$$
SET bytea_output = hex;
SELECT to_uuid(BYTEA '\x0FCC6350118D11E4A5597DE5338EB025');
PL/パイソン
PL/Python インターフェイスはbytea
16 進文字列ではなく生のバイトとして渡すため、Python の方がおそらく高速でクリーンです。
CREATE LANGUAGE plpythonu;
CREATE or replace function to_uuid(uuidbytes bytea)
RETURNS uuid LANGUAGE plpythonu IMMUTABLE
AS $$
import uuid
return uuid.UUID(bytes=uuidbytes)
$$;
SELECT to_uuid(BYTEA '\x0FCC6350118D11E4A5597DE5338EB025');
C では、キック用です。醜いハック。
C 拡張モジュールはこちらで確認できます。
しかし、本当に、私はそれが醜いということを意味します. C で適切に実行する場合は、拡張機能を使用するのではなく、実際に PostgreSQL にパッチを適用することをお勧めします。