知りたい情報は何処に SELECTの結果

日本語の問題というのはつまり文字エンコードの問題のことを言っているわけでして,文字化けしてしまったりした場合には,どこまでは想定通り行っていてどこから化けたのかというのを知ることが必要なわけです.

お題

  • JDBC APIであるexecuteQueryメソッドを呼んで取得したデータを画面出力したら日本語の文字列であるべき部分が全て"??????????"になっていたのはなんで?

要するに今日ぶち当たった問題というのがこれ.日本語で作ったテーブル名でJavaUnicode)からMySQLにその日本語名でテーブルを作成.そしてそのテーブル名を"SHOW CREATE TABLE ほげほげ"構文で取得して見ようという試み.

MySQLへのデータ格納時には,Shift_JIS(sjis),EUC-JP(ujisまたはeucjpms),UTF-8(utf8)他の日本人が使う文字コードのうちのどれかを毎回使用.(というか,リストで全部定義してIterator化してwhile文で全部まわした.)

日本語が"????????"に化けたといってすぐ思いつくのは日本語がlatin1などの日本語が使えない文字コードに間違って変換されちゃった時.今回もこの線で洗ったわけです.

そして今日もまた懲りずにConnector/Jのソースコードを捜査すること数時間・・・.

  • MySQLはカラムごとに文字コードが設定可能なので,逆にいうとSELECTを発行しMySQL Serverから受け取ったデータ(byte配列)には,各行のデータ以外に各カラムがどんな文字コードなのかの情報も入っている.Connector/Jはそれを各カラムごとに読んで,データ中の該当部分を切り出してnew String(byte[] bytes, String encoding)で復元する.それをやっているのは,MysqlIOクラスunpackFieldメソッドとその中で呼ばれるFieldクラスのコンストラクタ.

とりあえずサーバ側が何の文字コードを指定してデータ送信したのか知るにはそこにSystem.out.printlnしてみなさいってことだ.

やってみた結果・・・.binary(JavaのUS-ASCIIにマッピングされる)になってたよ.MySQLはMetaデータは全てUTF-8で持っていると聞いたのだけれども,何で"SHOW CREATE TABLE"がbinaryで返すのか理解不能

ちなみに,Connector/Jはnightly-build 20050504(ver3.1.8+α)の時点でJava-MySQL間の文字コードマッピング情報をCharsetMappingクラスからCharset.propertiesというファイルに外だししています.でもMySQLから受け取った文字コード識別番号から対応Java文字コードを解決するためのインデックスはCharsetMappingクラスの中のままです.

で,気づいちゃったんですが,CharsetMappingのそのインデックスにまだ"cp932"入っていません・・・

某M氏など,もしこの点について懸念ありましたらご連絡下さい.