✍️blog

技術系のこととか

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() のシノニムです。

要は、CURDATECURRENT_DATEの短縮したものということ。つまり、CURCURRENTの先頭3文字を切り取ったものということですね。 でも、ここで疑問が一つ、CURRENT_DATEのシノニム(エイリアス)がCURDATEならなんとなくわかる気がするけど、 CURDATEのシノニムがCURRENT_DATEというのはよくわからん🤔

そこで、MySQLのソースに何かヒントがあるのではと思いMySQLのソースをGithubからCloneしてみました。 CURDATEが実装されたタイミングはどこかなと探ってみたのですが...

github.com

うん、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となっている理由は結局わかりませんでした。
歴史的な理由でそうなっているのか、実装者の好みでそうなったのか、 いずれにせよこういう当たり前のことの理由を調べるのは楽しい

via GIPHY

参考URL

dev.mysql.com