STRICT_ALL_TABLESモード

mysqlではデフォルトではNOT NULL制約に明示的に値を与えない場合、勝手に空文字や0といった値を勝手に入れちゃう。

例えば

CREATE TABLE users (
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL
);

なテーブルに対して

INSERT INTO users(id) VALUES(1);

とかしたらエラーにならずid = 1, username = ''みたいなレコードが作られちゃう。

んで、これを許可しないようにするのが5.0.2以上でサポートされてるSTRICT_ALL_TABLESモード。知らんかったです。

SET sql_mode = 'STRICT_ALL_TABLES';

することによって

ERROR 1146 (42S02): Table 'users.users' doesn't exist

なエラーが返るようになります。
DBICで使うなら

my $schema = My::Schema->connect( 
    'dbi:mysql:users', 
    'root', 
    '',
    { on_connect_do => ["SET sql_mode = 'STRICT_ALL_TABLES'"] }
);

な感じですかね。

なんで、こっちがデフォルトじゃないんだろうか?
歴史的背景ですかね?

ちなみに似たようなオプションでSTRICT_TRANS_TABLESってのがありますが、こちらはトランザクションをサポートしているエンジンを使用しているテーブルのみ適用されるモード。
ちょっと存在価値がわからないです。

参考: