Understanding MySQL Internalsを読む(6)

以前の記事

Fieldクラス

Fieldクラスは、数値型、文字列型、時間型といった各種データ型を定義するための抽象クラスです。クエリを処理する際、ほとんどのケースでテーブルのフィールドが関連してくるため、このクラスは主にパーサとオプティマイザでの処理に使用されます。Fieldクラスはsql/field.hに定義されていますが、一部はsql/field.ssに実装されています。このFieldクラスは抽象クラスであるため、このクラスにおける実装は限定されています。Field_というプレフィックスを持つサブクラス群において、完全な実装がほどこされています。

Fieldクラスはメンバはあまり多く持っていませんが、その代わり非常に多くのメソッドを持っています。そこでここではメンバについては全て扱いますが、メソッドについては比較的重要なもののみに言及することにします。

宣言 説明
char *ptr メモリ上にコピーされたレコード内の当該フィールドデータへのポインタ。
uchar *null_ptr メモリ上にコピーされたレコード内の、このフィールドがNULLかどうかを示すバイトへのポインタ。
const char *table_name このフィールドを含むテーブルの名前。
const char *field_name このフィールドの名前。
LEX_STRING comment このフィールドに対するコメント文。コメントはCREATE TABLEの際に次のように埋め込める。CREATE TABLE t1 (c INT COMMENT 'hoge');
ulong query_id このフィールドを使用している現在のクエリのID。
key_map key_start このフィールドがキーに含まれるかどうかのビットマスク。nビット目が立っていたら、n番目のキーの先頭フィールドであることを意味する。
key_map part_of_key このフィールドがキーに含まれるかどうかのビットマスク。nビット目が立っていたら、n番目のキーに含まれるフィールドであることを意味する。
key_map part_of_sortkey このフィールドがキーに含まれるかどうかのビットマスク。nビット目が立っていたら、n番目のキーに含まれるフィールドであり、このキーは昇順または降順での値探索に利用できることを意味する。キーがB-tree形式である場合これに該当するが、hashやfulltext形式の場合はこれに該当しない。
utype unireg_check テーブル定義ファイル(.frm)に記録されているフィールドの型コード。
uint32 field_length このフィールドに格納される可能性のある最大データ長。
uint16 flags フィールド定義時に定められた、属性の有無を表すビットマスク。例えばNOT NULL、AUTO_INCREMENT、ZEROFILLなど。
uchar null_bit このフィールドの値がNULLかどうかを示すレコードプレフィックスのビット。
int store(const char *from, uint length, CHARSET_INFO *cs) fromで指定された文字列をこのフィールドを含むレコードのメモリ上のコピーに格納する。
int store(double nr) fromで指定された倍精度浮動小数点数をこのフィールドを含むレコードのメモリ上のコピーに格納する。
int store(longlong nr) fromで指定された64bitの数値をこのフィールドを含むレコードのメモリ上のコピーに格納する。
void store_time(TIME *ltime,timestamp_type t_type) ltimeで指定された日時をこのフィールドを含むレコードのメモリ上のコピーに格納する。
double val_read(void) このフィールドを含むレコードのメモリ上のコピーに格納されている値を、倍精度浮動小数点数に変換して返す。
String *val_str(String *str) このフィールドを含むレコードのメモリ上のコピーに格納されている値を、文字列に変換して返す。文字列は引数で渡されたバッファに格納される。この関数の呼出元は、事前にStringオブジェクトを作成してから渡さなければならない。値が0のポインタ(null)を渡すとクラッシュする。
Item_result result_type() フィールドに格納されたデータの型を返す。現在この変数は範囲検索用のオプティマイザが適切な最適化を行うために使用されている。例えば、フィールド'a'が文字列型でキーが作成されている状況下では、SELECT * FROM t1 WHERE a > 1 AND a < 5を実行した場合、10を持つレコードがある場合、単純に('1','5')の範囲で結果を返すとなると誤りとなる。なぜならフィールド'a'は文字列型なので、キーは辞書順に並んでいるので、通常は'10'はこの範囲内に含まれる。しかしながら、投げられたクエリの構文は数値比較を行うように指定が行われているので、ここでは'10'は結果から除外されるべき値なのである。
Item_result cmp_type() フィールドに格納されたデータが他の値との比較演算が行われる際に、どのデータ型として比較されるべきかを返す。通常はresult_type()と同じ結果となる。異なる場合の例としては、timestamp型があげられる。timestamp型のresult_type()の戻り値はSTRING_RESULTだが、cmp_type()の戻り値はINT_RESULTとなっている。これにより、timestamp型のデータを数値型のデータと比較する際、数値型のデータを文字列に変換することなく、数値型同士として比較演算が可能となっている。
void reset(void) メモリ上にコピーされたレコード内の当該フィールドデータを初期化する。
bool binary() フィールドのデータをバイナリデータとして比較するのか、あるいは1バイトずつ(1文字ずつ)比較するのかを報告する。CHAR(N)型のフィールドはデフォルトでは大文字小文字の区別がなく、後続のスペースを切り捨てた状態で比較が行われる。
uint32 key_length() メモリ上でのキーの操作のため、フィールドの長さを返す。
enum_field_types type() テーブル定義情報に記されているフィールドの型を返す。
int cmp(const char *str) 引数strとメモリ上にコピーされたレコード内の当該フィールドデータを比較した結果を返す。データが引数strよりも小さい場合には-1、同じ場合には0、大きい場合には1を返す。strの長さはfield_lengthに格納されたバイト数であると推定して行う。
int key_cmp(const byte *str, uint length) 引数strと、キーに含まれるメモリ上にコピーされたレコード内の当該フィールドデータを比較した結果を返す。データが引数strよりも小さい場合には-1、同じ場合には0、大きい場合には1を返す。
bool is_null(uint now_offset=0) メモリ上にコピーされたレコード内の当該フィールドデータがSQLにおけるNULL値であるかどうかを返す。
void set_null(int row_offset=0) このフィールドのデータをSQLにおけるNULL値として設定する。
bool maybe_null(void) このフィールドがSQLにおけるNULL値を許容するか否かを返す。
void move_field(char *ptr_arg) 内部的なフィールドデータへのポインタを他の場所へ変更する。