MySQL 5.0.42および5.1.18以降で、日付型と日付時刻型とを比較するときの挙動が変更
サーバに入っているMySQLのバージョンを上げたら、それまでなんともなかったところで挙動が変わるようになって原因調べたときの出来事。
MySQL 5.0.42および5.1.18から、MySQL内部の仕様が変更されているそうです。
MySQL :: MySQL 5.0 Reference Manual :: 10.3 Date and Time Types
Prior to MySQL 5.0.42, when DATE values are compared with DATETIME values, the time portion of the DATETIME value is ignored, or the comparison could be performed as a string compare. Starting from MySQL 5.0.42, a DATE value is coerced to the DATETIME type by adding the time portion as '00:00:00'. To mimic the old behavior, use the CAST() function to cause the comparison operands to be treated as previously. For example:date_col = CAST(NOW() AS DATE);
MySQL :: MySQL 5.1 Reference Manual :: 10.3 Date and Time Types
こちらの5.1系のリファレンスサイトにも同様のことが書かれています。
ざっと訳すと、日付型(YYYY-MM-DD)と日付時刻型(YYYY-MM-DD hh:ii:ss)とで比較をする場合に、以前は日付部分だけをみて比較されていたものが、5.0.42以降は時刻部分も含めた文字列として比較されるようになっていて、その際に日付型は時刻 = 00:00:00 として扱われるため、比較の結果が以前と変わるケースがある。
なので日付型と日付時刻型とをまたいで比較をするときは、明示的にキャストして型変換をしてね。
ということらしい。
NOW() は日付時刻型を返す関数なので、たとえば
WHERE datecolumn = NOW()
なんてやってるとMySQLのバージョンによって比較結果が変わりますよ、と。
そもそもは、暗黙的な型変換には頼らずに、つねに型を意識してコードを書いていればこういう問題は起きないわけなのですが。いかんせん暗黙的に動いてしまうコードなので、世の中にも多数埋もれてそうな気がします。
今回、なによりハマったのは、日本語で検索してもなかなか同じような症例がみつからず、日本語版のMySQLリファレンスサイトにもちょうどこの段落だけ記載が抜け落ちていていること!原因がさっぱり見当つかず、しばらく路頭に迷いました。。。











