[pgsql-jp: 28998] Re: 7.3.xのJDBC ドライバで,特定文字のみ文字化け

haruhiro @ ImagesWords.com haruhiro @ ImagesWords.com
2003年 2月 10日 (月) 17:53:29 JST


山口と申します。
ちょうど同じようなところでハマっており、解析していました。


> 7.3より,JDBCで"set client_encoding = 'UNICODE'" を実行している事から
> バックエンドとフロントエンド間での自動エンコーディング変換が使用されている
> 為,機種依存文字のエンコーディング箇所が,JVMとPostgreSQLの2箇所で行な
> われています.


問題は、PostgreSQL の EUC_JP と Unicode マッピングが
MS932 と同じコードポイントを利用するようになっている点だと思います。

それに対し Java (Sunの) では、MS932 のマッピングと、
EUC_JP, ISO2022JP, SJIS などのマッピングとは異なります。

7.3 の JDBC ではこれまでの流れでも明らかになりましたとおり、
"set client_encoding = 'UNICODE'" が実行され、
通信路は Unicode に固定しています。

こういった事情のため、以下のようなケースで問題が発生します。
ここでは「〜」を例にとってみます。

・PostgreSQL は EUC_JP、JVM との入出力も EUC_JP

  JVM へ入力されたとき、EUC の〜は WAVE DASH(\u301c) に変換されます。
  WAVE DASH は PostgreSQL に渡されたときに EUC_JP へ変換されますが、
  PostgreSQL は EUC_JP においても MS932 で変換するために、
  WAVE DASH を変換できません。従って、〜は警告と共に捨てられます。

  仮に psql などで〜を入力したものを JDBC で取得するとしましょう。
  PostgreSQL は EUC_JP から Unicode に変換しますが、WAVE DASH ではなく
  MS932 のコードポイントである FULLWIDTH TILDE(\uff5e) になります。
  JVM からこれを EUC_JP 出力するときは変換できませんので ? になります。
  
・PostgreSQL は Unicode、JVM との入出力は EUC_JP

  JVM へ入力されたとき、EUC の〜は WAVE DASH(\u301c) に変換されます。
  WAVE DASH は PostgreSQL に渡されてそのまま格納されます。
  当然ながら出力時もきちんと〜に戻りますので問題はありません。
  しかし psql などで、PostgresSQL で EUC_JP に変換するとなると、
  WAVE DASH はマッピングにありませんので警告とともに捨てられます。
  Unicode のまま取り出せば、これも問題ありません。


PostgreSQL のソースを変更しないですむワークアラウンドとしては、

・これまでにも出ましたが JVM との入出力を MS932 変換にしてしまう。
  1.4 ならば Windows-31J などです。
  # Shift_JIS はJDKのバージョンにより変換が異なりますので注意してください

・PostgreSQL のコンバータを使わない
  PostgreSQL を Unicode にして psql も Unicode にする。

などでしょうか。


--
Yamaguchi, Haruhiro <haruhiro @ ImagesWords.com>
Images & Words, Inc.



pgsql-jp メーリングリストの案内