Upgrade to Pro — share decks privately, control downloads, hide ads and more …

mysql80-date-type-bug-fix

kentsu
July 25, 2020

 mysql80-date-type-bug-fix

kentsu

July 25, 2020
Tweet

More Decks by kentsu

Other Decks in Technology

Transcript

  1. 今⽇話すこと ▌DATE 型と⽂字列の評価が変わった話 n MySQL 8.0.16 で地味に修正 n MySQL 8.0.15

    以下の挙動と⽐較 n こいつが割とすごい挙動 n ⼀説によると MySQL 4.0 あたりから…︖
  2. sql_mode を疑ってみる ▌Incorrect Date Value で調べてみた ▌Sql_mode なるものが関係している(っぽい?) n Sql_mode

    はより厳密にデータを扱う設定 n DATE 以外にも SQL そのもの、数値など
  3. sql_mode を疑ってみる ▌NO_ZERO_IN_DATE n 0 ⽉, 0 ⽇を含む場合はエラー・警告 ▌NO_ZERO_DATE n

    '0000-00-00' という⼊⼒に対しエラー・警告 ▌これらが無効となっている場合は⾃動的に変換
  4. Release Note でそれっぽいやつを探す ▌MySQL 8.0.0 より⼤きいバージョンが対象 n Bugs Fixed n

    Functionality Added or Changed ▌SQL 構⽂などは恐らく関係ない ▌内部的な修正、DATE 型の変換に関わる部分
  5. MySQL 8.0.16 の Bugs Fixed When comparing DATE values with

    constant strings, MySQL first tries to convert the string to a DATE and then to perform the comparison. When the conversion failed, MySQL executed the comparison treating the DATE as a string, which could lead to unpredictable behavior. Now in such cases, if the conversion of the string to a DATE fails, the comparison fails with ER_WRONG_VALUE. (Bug #29025656) https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-16.html
  6. Bugs Fixed 要点整理 ▌MySQL 8.0.15 以下の⽐較⼿順 1. ⽂字列を DATE 型に変換して⽐較

    2. 変換に失敗した場合は DATE 型を⽂字列に変換して⽐較 ▌MySQL 8.0.16 以上の⽐較⼿順 1. ⽂字列を DATE 型に変換して⽐較 2. 変換に失敗した場合はエラーを返す
  7. Bug Report も⾒てみる ▌これバグじゃないのか︖と報告はされていた ▌回答↓ Documented fix as follows in

    the MySQL 8.0.16 changelog: When comparing DATE values with constant strings, MySQL first tries to convert the string to a DATE and then to perform the comparison. When the conversion failed, MySQL executed the comparison treating the DATE as a string. Now in such cases, if the conversion of the string to a DATE fails, the comparison fails with ER_WRONG_VALUE. Closed. https://bugs.mysql.com/bug.php?id=93513
  8. 番外編: MySQL に何が起こっているか ▌Item_cmpfunc.cc の set_cmp_func がそれっぽい can_compare_as_dates -> get_date_from_const

    -> get_date_from_str -> get_mysql_time_from_str -> str_to_datetime ▌str_to_datetime で MYSQL_TIME_WARN_TRUNCATED ▌make_truncated_value_warning
  9. 番外編: MySQL に何が起こっているか ▌⽐較対象の DATE 型が STRING_RESULT を持っている ▌cmp_context が

    STRING_RESULT になっている ▌その後は⽂字列として⽐較されている(みたい)