Bug #5729 Bug in com.mysql.jdbc.ResultSet
Submitted: 24 Sep 2004 10:46 Modified: 20 Oct 2004 0:45
Reporter: Bjarte Andre Eide Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S1 (Critical)
Version:3.1.4-beta OS:Windows (Windows-2000)
Assigned to: Mark Matthews CPU Architecture:Any

[24 Sep 2004 10:46] Bjarte Andre Eide
Description:
The static method "protected static BigInteger convertLongToUlong(long longVal)" in "com.mysql.jdbc.ResultSet" is creating a wrong BigInteger compared to the long value given as a parameter. 

The reason for this is as far as I can see caused by the byte array sent to the BigInteger constructor. The byte array is today holding the longValue in "Little-Endian", but should be in "Big-Endian". "Big Endian" is the format that the BigInteger constructor expects.

How to repeat:
import java.math.BigInteger;

public class MySqlBug extends com.mysql.jdbc.ResultSet {

   public MySqlBug() {
      super(0, 0, null, null);
   }

   public static void main(String[] args) {
      long num = 1095923280000L;
      BigInteger dec = MySqlBug.convertLongToUlong(num);
      System.out.println("numOrig=" + num);
      System.out.println("numNew=" + dec.longValue());
   }
}

//System.out
//numOrig=1095923280000
//numNew=-9212079867770699776

Suggested fix:
Reverse the byte-array sent to BigInteger constructor:

    protected static BigInteger convertLongToUlong(long longVal) {
        byte[] asBytes = new byte[8];
        asBytes[7] = (byte) (longVal & 0xff);
        asBytes[6] = (byte) (longVal >>> 8);
        asBytes[5] = (byte) (longVal >>> 16);
        asBytes[4] = (byte) (longVal >>> 24);
        asBytes[3] = (byte) (longVal >>> 32);
        asBytes[2] = (byte) (longVal >>> 40);
        asBytes[1] = (byte) (longVal >>> 48);
        asBytes[0] = (byte) (longVal >>> 56);

        return new BigInteger(1, asBytes);
    }
[8 Oct 2004 0:48] Matthew Lord
Hi,

Thank you for your bug report!

I was able to repeat this using 3.1.4-beta on linux (2.4.21 #SMP i386 i686 GNU/Linux) using java 1.4.1_02-b06

Best Regards
[18 Oct 2004 20:19] Mark Matthews
I can't repeat this with the current nightly snapshot of 3.1 from http://downloads.mysql.com/snapshots.php
[19 Oct 2004 18:02] Bjarte Andre Eide
TestCase for Bug 5729

Attachment: TestBug5729.java (application/octet-stream, text), 1.85 KiB.

[19 Oct 2004 18:20] Bjarte Andre Eide
Hi, 
I have downloaded the lastest build ("mysql-connector-java-3.1-nightly-20041011.zip"), but the error still occurs. 

I have uploaded a TestCase ("TestBug5729.java") which contains two tests where the bug occurs.

The following stacktrace shows the "execution path" for test01()  
 
main@1 prio=5, in group "main", status: RUNNING
	  convertLongToUlong():4884, ResultSet.java
	  unpackBinaryResultSetRow():3675, MysqlIO.java
	  nextRow():1269, MysqlIO.java
	  readSingleRowSet():2185, MysqlIO.java
	  getResultSet():402, MysqlIO.java
	  readResultsForQueryOrUpdate():1886, MysqlIO.java
	  readAllResults():1334, MysqlIO.java
	  serverExecute():1375, ServerPreparedStatement.java
	  executeInternal():944, ServerPreparedStatement.java
	  executeQuery():1657, PreparedStatement.java
	  test01():33, TestBug5729.java

I hope this will help you to find the bug.

Regards, 
Bjarte Andre Eide
[20 Oct 2004 0:45] Mark Matthews
Thank you for your bug report. This issue has been committed to our
source repository of that product and will be incorporated into the
next release.

If necessary, you can access the source repository and build the latest
available version, including the bugfix, yourself. More information 
about accessing the source trees is available at
    http://www.mysql.com/doc/en/Installing_source_tree.html

Additional info:

Checked in the fix (didn't realize it was related to server-side prepared statements until I saw your testcase).

This will be in Wednesday's nightly build (Tuesday's already went out earlier today, at midnight).