MySQL CURDATE
日頃MySQLで日付関連のSQLを書く際に何気なくCURDATE
使ってるけど
CUR
って何?ってなったので少し調べて見ました。
まずこの関数について。 この関数は現在の日付をYYYYMMDDで返してくれます。
SELECT CURDATE(); -- > '2022-12-29' SELECT CURDATE() + 0; -- > 20221229
日付関係といえば、NOW関数
も割と使うかと思いますが、こちらは日時をYYYYMMDDhhmmssで返してくれる関数です。
SELECT NOW(); -- > '2022-12-29 20:45:10' SELECT NOW() + 0; -- > 20221229204510.000000
で、本題ですがCUR
何なのかはMySQLのドキュメントを読めば一発で分かります。
以下、ドキュメントからの引用です。
CURRENT_DATE および CURRENT_DATE() は CURDATE() のシノニムです。
要は、CURDATE
はCURRENT_DATE
の短縮したものということ。つまり、CUR
はCURRENT
の先頭3文字を切り取ったものということですね。
でも、ここで疑問が一つ、CURRENT_DATE
のシノニム(エイリアス)がCURDATE
ならなんとなくわかる気がするけど、
CURDATE
のシノニムがCURRENT_DATE
というのはよくわからん🤔
そこで、MySQLのソースに何かヒントがあるのではと思いMySQLのソースをGithubからCloneしてみました。
CURDATE
が実装されたタイミングはどこかなと探ってみたのですが...
うん、git logが残っている範囲では一番最初から入ってますね。そりゃそうですよね~ コード上にヒントがないとすると仮説を立てていくしかない。
今に比べれば限られたリソースの中で動作させなければいけないことを考えるとSQLに埋め込む関数名は短くしておきたかった? もしそれであれば他の関数名も比較的短いはずなので上記コミットのコードをあさってみると...
関数の一覧らしきファイルを見つけました。
github.com
以下、抜粋です。
ソース展開
// 省略 static SYMBOL sql_functions[] = { { "ABS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)}, { "ACOS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)}, { "ADDDATE", SYM(DATE_ADD_INTERVAL),0,0}, { "ASCII", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ascii)}, { "ASIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)}, { "ATAN", SYM(ATAN),0,0}, { "ATAN2", SYM(ATAN),0,0}, { "BENCHMARK", SYM(BENCHMARK_SYM),0,0}, { "BIN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bin)}, { "BIT_COUNT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)}, { "BIT_OR", SYM(BIT_OR),0,0}, { "BIT_AND", SYM(BIT_AND),0,0}, { "CEILING", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)}, { "CHAR_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "CHARACTER_LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)}, { "COALESCE", SYM(COALESCE),0,0}, { "CONCAT", SYM(CONCAT),0,0}, { "CONCAT_WS", SYM(CONCAT_WS),0,0}, { "CONNECTION_ID", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, { "CONV", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, { "COUNT", SYM(COUNT_SYM),0,0}, { "COS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, { "COT", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, { "CURDATE", SYM(CURDATE),0,0}, { "CURTIME", SYM(CURTIME),0,0}, { "DATE_ADD", SYM(DATE_ADD_INTERVAL),0,0}, { "DATE_FORMAT", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_date_format)}, { "DATE_SUB", SYM(DATE_SUB_INTERVAL),0,0}, { "DAYNAME", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayname)}, { "DAYOFMONTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofmonth)}, { "DAYOFWEEK", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofweek)}, { "DAYOFYEAR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)}, { "DECODE", SYM(DECODE_SYM),0,0}, { "DEGREES", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)}, { "ELT", SYM(ELT_FUNC),0,0}, { "ENCODE", SYM(ENCODE_SYM),0,0}, { "ENCRYPT", SYM(ENCRYPT),0,0}, { "EXTRACT", SYM(EXTRACT_SYM),0,0}, { "EXP", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)}, { "EXPORT_SET", SYM(EXPORT_SET),0,0}, { "FIELD", SYM(FIELD_FUNC),0,0}, /* For compability */ { "FIND_IN_SET", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)}, { "FLOOR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)}, { "FORMAT", SYM(FORMAT_SYM),0,0}, { "FROM_DAYS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)}, { "FROM_UNIXTIME", SYM(FROM_UNIXTIME),0,0}, { "GET_LOCK", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)}, { "GREATEST", SYM(GREATEST_SYM),0,0}, { "GROUP_UNIQUE_USERS", SYM(GROUP_UNIQUE_USERS),0,0}, // 省略
うん、長い関数名あるね。
CURRENT_DATE
ではなく、CURDATE
となっている理由は結局わかりませんでした。
歴史的な理由でそうなっているのか、実装者の好みでそうなったのか、
いずれにせよこういう当たり前のことの理由を調べるのは楽しい