Bug #11940 The PreparedStatement causes invalid transformation unsigned int type
Submitted: 14 Jul 2005 14:06 Modified: 15 Jul 2005 12:05
Reporter: Eugene Andrewhin Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:3.1.10 OS:Windows (Windows XP)
Assigned to: CPU Architecture:Any

[14 Jul 2005 14:06] Eugene Andrewhin
Description:
  The 'PreparedStatement', where in query selected integer from unsigned integer field , gives the invalid numbers. But 'Statement' with such request gives the faithfull data. If the field to do signed, that problems no.
  In versions 3.1.8 and 3.1.7 such problems no - I have tested.

Note: Occurs convertation from unsigned integer to signed long with adding two senior bytes with included sign bit. See example ("How to repeat" section).

How to repeat:
-- Example --

create table: CREATE TABLE `test_table` (`int_field` int(6) unsigned NOT NULL default '0') ENGINE=InnoDB

insert value: INSERT `test_table` VALUES (123456);

fetching with Statement (no error):
  Statement stmt = conn.createStatement();
  ResultSet rs = stmt.executeQuery("SELECT `int_field` FROM `test_table` WHERE `int_field` = 123456");
  /* rs.getObject(1) = 123456 (can be other getXxx() int methods) */

fetching with PreparedStatement (error):
  PreparedStatement pstmt = conn.prepareStatement("SELECT `int_field` FROM `test_table` WHERE `int_field` = ?");
  pstmt.setInt(1,123456);
  rs = pstmt.executeQuery();
  /* ! rs.getObject(1) = 4295090752 (can use dif getXxx() int methods) */

Compares in bit notion:
123456        -                            11110001001000000
4295090752 - 100000000000000011110001001000000

That is to say occurs convertation from unsigned integer to signed long with adding two senior bytes with included sign bit.
[14 Jul 2005 19:30] Aleksey Kishkin
testcase

Attachment: Bug11940.java (text/x-java), 1.30 KiB.

[14 Jul 2005 19:37] Aleksey Kishkin
What version of mysql server did you use? 
Tested on linux (testcase attached) against mysql 5.0.10 and j/connector 3.1.10 - works properly. Plan to test on Windows. 

 /opt/java/jre/bin/java -classpath .:my.jar Bug11940 2>/dev/null
.Loading JDBC driver 'com.mysql.jdbc.Driver'
Done.

Done.

123456
123456

Time: 0,982

OK (1 test)
[15 Jul 2005 4:16] Aleksey Kishkin
on win xp sp2, against mysql.5.0.7 and jdbc 3.1.10 was not able to reproduce it as well 

.Loading JDBC driver 'com.mysql.jdbc.Driver'
Done.

Done.

Connected to 5.0.7-beta-nt
123456
123456

Time: 1,156

OK (1 test)
[15 Jul 2005 5:15] Eugene Andrewhin
Java source illustrated  trouble

Attachment: PreparedStatementBugFix.java (text/x-java), 3.47 KiB.

[15 Jul 2005 5:26] Eugene Andrewhin
I am use MySQL 4.1.12 and java sdk version 1.4.2_08-b03 and latest
MySQL Connector/J 3.1.10 verssion, and Windows XP sp2.
I think, it is trouble Connector/J 3.1.10. Because simple replacement to backword version Connector/J (on 3.1.8 & 3.1.7) trouble is gone.
I'm attach java test file for illustrated trouble.
[15 Jul 2005 5:38] Eugene Andrewhin
I also tested with mysql-connector-java-3.2.0-alpha and too allright. I Ask to pay attention to mysql-connector-java-3.1.10
[15 Jul 2005 5:45] Aleksey Kishkin
e:\java\bin\java -cp .;mysql-connector-java-3.1.10-bin.jar PreparedStatementBugFix
123456
123456

Win xp sp2, mysql 4.1.12 the only difference is - I use 
java -verson
java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode, sharing)

OK. going to try elder java
[15 Jul 2005 6:06] Aleksey Kishkin
Finaly got:

.Loading JDBC driver 'com.mysql.jdbc.Driver'
Done.

Done.

Connected to 4.1.12a-nt
123456
4295090752
F
Time: 0,547
There was 1 failure:
1) testUnsignedInt(Bug11940)junit.framework.AssertionFailedError: We must fetch
123456 but fetched 4295090752
        at Bug11940.testUnsignedInt(Bug11940.java:33)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
        at Bug11940.main(Bug11940.java:38)

FAILURES!!!
Tests run: 1,  Failures: 1,  Errors: 0

It looks like rs.getObject(1).toString() returns that wrong value. If I test rs.getInt(), no error appears.
[15 Jul 2005 6:06] Aleksey Kishkin
real test case

Attachment: Bug11940.java (text/x-java), 1.35 KiB.

[15 Jul 2005 9:42] Eugene Andrewhin
Yes really, getInt() returns faithfull importance because working like this
int value = (int) longValue, since in this instance returns rs.getObject().getClass().getName() = java.lang.Long.
 Usage getInt() this private output from situation, but the problem of  convertation remain. I think so be must not. What do you think?
[15 Jul 2005 12:05] Mark Matthews
Known issue already fixed in nightly builds of 3.1. See http://downloads.mysql.com/snapshots.php#connector-j for a version you can test.