Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
mysqlのオプション指定でテーブルの縦線を揃えるで、 mysqlクライアントを起動するときに、 --default_character_set=キャラクタセット で デフォルトキャラクタセットを指定したら、テーブルが揃った。
これと同じ事をやってみよう。
shell$ gdb /usr/local/mysql/bin/mysql メッセージがごちゃごちゃと出るが省略 (gdb) r -u root --default_character_set=eucjpms Starting program: /usr/local/mysql/bin/mysql -u root --default_character_set=eucjpms Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 33 to server version: 5.0.10-beta-debug-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> select 'サカマチ'; +----------+ | サカマチ | +----------+ | サカマチ | +----------+ 1 row in set (0.27 sec) mysql>
タイトルの方は揃わなかったが、SELECTされたものはちゃんと揃っている。 今のところ、タイトルについては無視しておこう。
さて、このとき、変数 charset_info がどうなっているか調べてみよう。
一度止めて、ブレイクポイントを設定してから同じ事をしてみよう。
mysql> \q Bye Program exited normally. (gdb) b mysql.cc:2232 Breakpoint 1 at 0x8054f62: file mysql.cc, line 2232. (gdb) r Starting program: /usr/local/mysql/bin/mysql -u root --default_character_set=eucjpms Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 35 to server version: 5.0.10-beta-debug-log Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> select 'サカマチ'; +----------+ | サカマチ | +----------+ Breakpoint 1, print_table_data (result=0x809cab0) at mysql.cc:2232 2232 uint currlength= (uint) lengths[off]; (gdb)
表示幅を示す変数 numcellsの値がいくつになるか調べてみよう。
(gdb) n 2233 uint numcells= charset_info->cset->numcells(charset_info, (gdb) n 2235 tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|", (gdb) p numcells $1 = 4 (gdb)
'サカマチ'は、半角カタカナが4つだから、幅は4であり、計算結果も4になっている。 これなら、正しく表示されそうだ。
ここで、*charset_info を見てみよう。
(gdb) p *charset_info
$2 = {number = 97, primary_number = 0, binary_number = 0, state = 801,
csname = 0x8089d70 "eucjpms", name = 0x8089d78 "eucjpms_japanese_ci",
comment = 0x8089d50 "UJIS for Windows Japanese", tailoring = 0x0, ctype = 0x400ea220 "",
to_lower = 0x400ea340 "", to_upper = 0x400ea440 "", sort_order = 0x400ea540 "",
contractions = 0x0, sort_order_big = 0x0, tab_to_uni = 0x0, tab_from_uni = 0x0,
caseinfo = 0x4012b960,
state_map = 0x80808a0 .....以下省略 ,
ident_map = 0x80809a0 "", strxfrm_multiply = 1, caseup_multiply = 1 '\001',
casedn_multiply = 1 '\001', mbminlen = 1, mbmaxlen = 3, min_sort_char = 0,
max_sort_char = 255, cset = 0x401051a0, coll = 0x40105160}
(gdb)
今度は、charset_info-csname = 0x8089d70 "eucjpms" となっており、 キャラクタセットがちゃんとeucjpmsとして認識されている。 これで文字幅の調整が正しくなったのであろう。
utf8 にしても動くだろうか
まず、gnome-terminalのCharacter CodingをUTF-8にする。 それから、実行してみよう。
(gdb) r -u root --default_character_set=utf8
Starting program: /usr/local/mysql/bin/mysql -u root --default_character_set=utf8
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 37 to server version: 5.0.10-beta-debug-log
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> select 'サカマチ';
+--------------+
| サカマチ |
+--------------+
Breakpoint 1, print_table_data (result=0x809cad8) at mysql.cc:2232
2232 uint currlength= (uint) lengths[off];
(gdb) n
2233 uint numcells= charset_info->cset->numcells(charset_info,
(gdb) n
2235 tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|",
(gdb) p numcells
$1 = 4
(gdb) p *charset_info
$2 = {number = 33, primary_number = 0, binary_number = 0, state = 993,
csname = 0x8089380 "utf8", name = 0x8089388 "utf8_general_ci",
comment = 0x8089370 "UTF-8 Unicode", tailoring = 0x0, ctype = 0x4012b640 "",
to_lower = 0x4012b760 "", to_upper = 0x4012b860 "", sort_order = 0x4012b860 "",
contractions = 0x0, sort_order_big = 0x0, tab_to_uni = 0x0, tab_from_uni = 0x0,
caseinfo = 0x4012b960,
state_map = 0x807e6a0 .....以下省略 ,
strxfrm_multiply = 1, caseup_multiply = 1 '\001',
casedn_multiply = 1 '\001', mbminlen = 1, mbmaxlen = 3, min_sort_char = 0,
max_sort_char = 65535, cset = 0x4012c1a0, coll = 0x4012c160}
(gdb)
ということで、utf8に指定しても、ちゃんと文字幅は4のままで、 charset_info->csname = 0x8089380 "utf8" となって、これもOKである。
ブレイクポイントを削除して実行を継続すると次のようになった。
(gdb) delete 1 (gdb) c Continuing. | サカマチ | +--------------+ 1 row in set (0.02 sec) mysql>
タイトル部分の文字幅調整
値の方には、
2233 uint numcells= charset_info->cset->numcells(charset_info, 2234 str, str + currlength);
があって、実際に表示されたときの幅が求められているが、 タイトル部分に対するループには、そういう計算がまったくされていない。
とりあえず、あまり大切なことでもないので、ここでは省略しよう。
どうやったら、ちゃんと揃うようになるのか
さて、調べるだけではつまらない。 ここまで分ったのだから、
プログラムを改変してしまおう。
どうやったら、各フィールドのキャラクタセットに合わせた表示をすることが できるのであろうか。
各フィールド毎にキャラクタセットは任意に指定できるので、 フィールド毎にちゃんと指定し直す必要がある。
さて、どうやったら良いのだろうか、次回までの宿題だ。
戻る:SET NAMESで変更してもcharset_infoはlatin1のままだ
フィードバック:
There is no comment.