概要
DataGrip で MySQL に接続すると、 sql_mode を別途設定しているにも関わらず、STRICT_TRANS_TABLES が勝手に適用されていた。
グローバルの設定を確認すると、意図したものが設定されているが、セッションの設定は STRICT_TRANS_TABLES になってしまう。
DataGrip に限らず、 IntelliJ IDEA とか JetBrains 系 IDE の DB ツールで同じことが起きると思う。
-- グローバルは問題ないけど SELECT @@GLOBAL.sql_mode; -- SESSION だと何故か STRICT_TRANS_TABLES SELECT @@SESSION.sql_mode;
原因
DataGrip が MySQL の接続に JDBC ドライバを使用していたため。
JDBC は STRICT_TRANS_TABLES を有効にするようになっている。
以下はチケットに対して、バグじゃないよ、という話がされているのが下記リンク。
STRICT_TRANS_TABLES とは何か
sql_mod に設定することで、 SQL を Strict (厳密) にチェックしてくれるようになる。
逆にオフにしていると、たとえば文字列長超えを切り捨ててデータ登録できたり、デフォルト値を持つカラムに Null でクエリを発行した場合にデフォルト値で更新してくれたりする (警告は出る)。
MySQL 5.7.5 からはデフォルトで有効になっている。
JDBC は何故勝手に有効にするのか
jdbcCompliantTruncation を有効にするためには、 STRICT_TRANS_TABLES を有効にしておく必要があるため、jdbcCompliantTruncation を有効にすると自動的に sql_mode に設定されるようだ。
jdbcCompliantTruncation は JDBC の設定値で、前述のような値切り捨てが発生した場合に例外を投げるかどうかを設定できる。
リファレンスにも STRICT_TRANS_TABLES を有効にしないと効果がないことが書かれている。
DataGrip 等での設定のカスタマイズ方法
データソースの設定の「Advanced」でカスタマイズできる。
jdbcCompliantTruncation は true / false で指定すればよい。
sql_mode を変更したいときは sessionVariables に sql_mode='aaa,bbb'
のような形式で設定すれば OK。(まるっと無効にしたいときは sql_mode=0
)
終わりに
- JDBC を使っている DB クライアントやアプリケーションでは同じことが起きそう
- Strict でも問題なく動くように常日頃から実装していきたい