perl-DBD-MySQL 3.0007-2.el5でハマった件
Perl DBIのプログラムを書いていて、CentOS 5.3付属のDBD::mysqlをそのまま使ったら困ったという話です。
再現ケース
動く例です。
$sth = $dbh->prepare_cached('select ename from emp where empno = ?'); $sth->bind_param(1, 7788, SQL_INTEGER); $sth->execute();
動かない例です。bind_param()の引数を7788から-7788にしています。
$sth = $dbh->prepare_cached('select ename from emp where empno = ?'); $sth->bind_param(1, -7788, SQL_INTEGER); $sth->execute();
すると以下のようなエラーメッセージが出力され、SQLの実行が失敗してしまいます。
DBD::mysql::st execute failed: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 at test.pl line 17.
MySQLの一般クエリログを見ると、WHERE句に数値が入っていないことが分かります。
select ename from emp where empno =
解説
これは、SQL_INTEGERに対してマイナスの値をバインドできないというバグです。
2007-1-8 Jim Winstead <jimw@mysql.com> Patrick Galbraith <patg@patg.net> (4.001) * Fix handling of negative integers bound to a column marked as SQL_INTEGER. [rt.cpan.org #18976], patch from Mike Schilli.
このバグ自体はDBD::mysql 4.001で修正されていますが、4.001のリリースは2007年1月でありCentOS 5やRed Hat Enterprise Linux 5には取り込まれていません。そのためディストリビューションをそのまま使っている環境では、現在もこの問題を抱えていることになります。
こういう致命的なバグが2007年まで残っていたのは不思議です。bind_param()を使っている人がほとんどいないのかもしれませんね…。