long型の恐怖

いま気づいたんだけど,パラメータに使用するReaderとかInputStreamの長さを指定する引数にlong型が使用されているのってJDBC 4.0ではいっぱいある(追加されたメソッド).

JDBC 3.0まではPreparedStatement.setBlobってのは(int, Blob)しかなかった.でもJDBC 4.0ではオーバーロードされて(int, InputStream, long)ってのも追加された.

BlobインタフェースやClobインタフェースのlengthメソッドとか位置を指定するpositionとかはJDBC 3.0時点でlong型だった.

Connector/J 5.0 (JDBC 3.0準拠)ではPreparedStatement.setBlob(int, Blob)の中でBlobのサイズを取得するためにBlob.length()メソッドを呼んでるけどこれは(int)キャストしている.2^31を超える値を持つlong型をint型にキャストすると値が0とかにぶっ壊れるのは前のエントリで触れたとおり.つまり2^31以上のサイズのBlobを使用するとサイズint 0とかで渡されてしまって悲劇が起こるようになっていたわけだ.

Blob自体は"int setBytes(long pos, byte bytes)"メソッドを複数回呼び出せば2^31以上のサイズのBlobが作れるようにインタフェース上はなってる.戻り値がint型なのはbyteの要素数が2^31を超えることは無いからだなw

まあでも基本的にjava.ioパッケージにあるクラスはサイズ指定などにint型のパラメータを取っているわけで,またbyte[]配列とかでサイズを指定する際もint型しか使えないわけで,Blobだけlong型使われてもDriver実装側は困るという話だったのだが.

JDBC 4.0に来て,long型でもちゃんと動くように(2^31byte以上のサイズのパラメータ)しましょうと明示的に言われてしまった.どーすんべか.JavaSE6のJavaDocを一日でも早くみたいんだけど,JavaSE6ではI/O系APIはlong型を受け入れてくれるんでしょうかね?配列のサイズ制限は? JDBC仕様だけでlong型に突っ走っても無理があるような・・・.

JDBC Driverはint型を前提に実装されている個所ってかなりあるはずだから,この修正は大変だぞ・・・.