Wednesday, August 8, 2007
a bug in Oracle instant client 10.1.0.2
If you are familiar with Oracle's internal representation for number, you'd know the last byte can't be 101(0x65), since it is a positive number, the (last_byte -1) represents the last 2 digits of the number. 101-1=100, which isn't a 2 digits number. If it is a negative number, the last byte is 102. Through a bug in JDBC I recently encountered, it seems Oracle accepts 101 as the last byte, it treats it as 01, maybe it is just a protection against data corruption, or because it knows it has some buggy driver that could insert 101 when it should be 01. To test it, you can either hack the block directly and see if Oracle recognize it. I think sqlplus is OK with it, i.e, treat is as 01 so the last 2 digits are 00 which may look weird because instead of say "6.51", it'll show 6.5100. if you use other tools like sql*nav, you might get some funny character. Or if you don't want hack data block, you can use the buggy Oracle instant client 10.1.0.2, that is where I found the bug, last time I checked it wasn't in metalink. In java program, use preparedStatement to insert a value in ((0.0001, 0.0002, 0.0003,…0.0009, -0.0001, -0.0002,…,-0.0009) into a table. Then select dump() from table, you'll see "101" as the last byte. And if you user query the column and use getDouble() to get the value from resultset, it'll give you the right value. But, here is how I stumbled the bug, our application for some reason, always use getString to get value and I got an arrayoutofbound exception. So it looks there are 2 bugs here in JDBC, one is it inserts a malformed, or non-standard, number into the database. The other is getString function doesn't handle this non-standard format of number. To bypass the problem, either change getString to getDouble, or upgrade to 10.1.0.5 or 10.2.0.3 where the insert is correct in the first place.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment