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
関連リンク
ysql.ccに戻って、文字幅とキャラクタセットの関係を考えてみよう。
文字列の幅を求める関数は、 キャラクタセットの情報へのポインタである charset_info に依存するらしい。
定義および初期化がある。
178 static CHARSET_INFO *charset_info= &my_charset_latin1;
まず、latin1 つまり 英語、ASCII に初期化されている。
他に変更されているのは、どうも 関数 get_options() の中の 933行だけのようだ。
892 static int get_options(int argc, char **argv)
893 {
‥‥‥‥中略‥‥‥‥
932 if (strcmp(default_charset, charset_info->csname) &&
933 !(charset_info= get_charset_by_csname(default_charset,
934 MY_CS_PRIMARY, MYF(MY_WME))))
935 exit(1);
‥‥‥‥中略‥‥‥‥
950 }
これは、オプション、つまり mysqlクライアントの起動時に デフォルトキャラクタセットを直接指定するか、
mysql --default-character-set=eucjpms
オプションファイルに以下のように記述した場合に対応しているのだろう。
/etc/my.cnf または ~/.my.cnf [mysql] default-character-set=eucjpms
しかし、この2個所にしかないということは、 起動時にしか変更されないということである。
これは、mysqlのオプション指定でテーブルの縦線を揃える で説明した情况と完全に一致しているので、 以上の解釈で間違いないと思われる。
文字幅の調整は如何に行なわれているか
文字幅の調整が行なわれていたことは分ったのだが、
2212 tee_fprintf(PAGER, num_flag[off] ? "%*s |" : " %-*s|", 2213 maxlength + currlength - numcells, str);
この中の maxlength + currlength - numcells の意味について考えよう。
2201 uint maxlength= field->max_length;
とあるので、 maxlengthは カラムの表示幅に違いない。
currlength - numcell の部分が調整であろう。
numcellは、表示される文字列の実際の幅である。
currlengthは
2209 uint currlength= (uint) lengths[off];
となっており、lengths[]という配列から取得するのであるが、 このlengthsは、1レコードをフェッチする毎に result (リザルトセット) を引数にして求めている。
2194 ulong *lengths= mysql_fetch_lengths(result);
関数mysql_fetch_length()は、以下にあった。
sql-common/client.c
2669 ulong * STDCALL
2670 mysql_fetch_lengths(MYSQL_RES *res)
2671 {
2672 MYSQL_ROW column;
2673
2674 if (!(column=res->current_row))
2675 return 0; /* Something is wrong */
2676 if (res->data)
2677 (*res->methods->fetch_lengths)(res->lengths, column, res->field_count);
2678 return res->lengths;
2679 }
難しく考えるのは止めて、フェッチした長さ、要するにバイト数ではないかと思う。
そうすると、maxlength + currlength - numcells は
カラムの幅 + 文字列バイト数 - 文字列幅
ということになる。
たとえば、カラム幅が 10で、文字列が 'サカマチ' (eucjpmsとする)の場合を考えよう。
すると、
バイト数は 8, 文字列幅は 4、したがって
maxlength + currlength - numcells = 10 + 8 - 4 = 14
となる。本来の10より4つ多くなっている。
tee_fprintf() は fprintf() と同じような動きをするであろうから、 カラムのうちスペースになるのは、文字列のバイト数分だけ減るので、 10-8 = 2 であり、'サカマチ'の後にスペースが2つの表示になる。 つまり
|サカマチ |
である。これでは、カラムの幅は10ではなく、6になってしまったので、 減った分だけ加えなくては成らない。その部分が
currlength - numcells = 8 - 4
である。4つ加えられて、
|サカマチ |
と表示され、正しいカラム幅の10になる。めでたし、めでたし。
しかし、この説明はちょっと解りにくいかな。
それにしても、ソースを眺めて考えるだけではつまらないねぇ。
戻る:文字幅を求める関数my_numcells_eucjp()
フィードバック:
There is no comment.