| Bug #27174 | Procssor dependent Sign Expansion Problem with BigDecimal / DECIMAL(24) | ||
|---|---|---|---|
| Submitted: | 15 Mar 2007 14:19 | Modified: | 3 Jan 2011 9:13 |
| Reporter: | Klaus Halfmann | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S3 (Non-critical) |
| Version: | 5.0.5-bin.jar | OS: | Windows (Windows-XP) |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | BIGDECIMAL, Intel, sign | ||
[15 Mar 2007 14:47]
Klaus Halfmann
OK, does not happen on Linux / Intel java.vm.version : 1.5.0_11-b03 java.vm.vendor : Sun Microsystems Inc. java.runtime.version : 1.5.0_11-b03 os.name : Linux os.version : null sun.management.compiler : HotSpot 64-Bit Server Compiler processor : 7 vendor_id : GenuineIntel cpu family : 6 model : 15 model name : Intel(R) Xeon(R) CPU E5310 @ 1.60GHz stepping : 7 cpu MHz : 1596.044 cache size : 4096 KB physical id : 1 siblings : 4 core id : 3 cpu cores : 4 fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl vmx tm2 cx16 xtpr lahf_lm bogomips : 3192.20 clflush size : 64 cache_alignment : 64 address sizes : 36 bits physical, 48 bits virtual power management:
[29 Mar 2007 6:35]
Tonci Grgin
Hi Klaus and thanks for the nice report. What I am wondering about is this: - Where is MySQL server in your failed test and what is it's version? Please be specific. - Is JDK/JRE the same on laptop/desktop. What is the exact version (info provided only for Linux)? You must agree that, in light of your description, this info is crucial...
[29 Mar 2007 19:01]
Klaus Halfmann
We Cross Checked The Desktop/Laptop against the
Databases and found that it does _not_ depend on
the server (5.0.x latest GPL)
We use JDK 5.0_R11
(I may not be accurate here as I'm actually on
vacation and not in the office)
I would guess this is a problem in the JDK.
I'd suggest
a) you reproduce this on the same processor.
b) point me to the exact location in the driver
where the binary differnce would be. I can debug
than and return the results.
c) Provide some sample-code, how the driver converts
the BigDecimal to BCD (which I guess it does somewhere)
I must confess this is one of the most obscure things,
I've been stubling over for years ;-)
[30 Mar 2007 0:32]
Mark Matthews
There's no magic, server-side prepared statements use a String to represent the DECIMAL data type, so we use the BigDecimal(String) constructor to go from our internal representation to BigDecimal, and BigDecimal.toString() to go from a BigDecimal instance to our internal representation (which is a string). I do see perhaps one item I do want to check out that we're not using StringUtils.consistentToString(BigDecimal) with ServerPreparedStatements, which exists because Sun changed the output of BigDecimal.toString() between JDK-1.4 and JDK-5, but I don't think that is causing this issue, given that you're using JDK-5 and it works on one platform, and not the other.
[30 Mar 2007 12:02]
Tonci Grgin
Klaus, I was unable to repeat. Please review my results and test case. Both tests done on MySQL server 5.0.38BK on WinXP Pro SP2 localhost (marked as DESKTOP in results). DESKTOP: Genuine Intel, family 15 model 2 Connected to 5.0.38-log java.vm.version : 1.5.0_11-b03 java.vm.vendor : Sun Microsystems Inc. java.runtime.version : 1.5.0_11-b03 os.name : Windows XP os.version : null sun.management.compiler : HotSpot Client Compiler Time: 0,75 OK (1 test) LAPTOP: Genuine Intel, family 6 model 13 .Loading JDBC driver 'com.mysql.jdbc.Driver' Done. Done. Connected to 5.0.38-log java.vm.version : 1.5.0_07-b03 java.vm.vendor : Sun Microsystems Inc. java.runtime.version : 1.5.0_07-b03 os.name : Windows XP os.version : null sun.management.compiler : HotSpot Client Compiler Time: 0,719 OK (1 test)
[30 Mar 2007 12:03]
Tonci Grgin
Test case on latest c/J 5.0 sources
Attachment: TestBug27174.java (text/x-java), 3.58 KiB.
[2 Apr 2007 9:19]
Klaus Halfmann
Yes, your testcase did not trigger the bug.
But
using the MysqlConnectionPoolDataSource broke it. 8-?
You should better try
props.put("useServerPrepStmts" , "true");
in your second test ;-)
But this did not trigger the bug. #-[
We are about to investigate further ...
[2 Apr 2007 9:59]
Tonci Grgin
My mistake, sorry.
Putting "props.put("useServerPrepStmts" , "true");" into test case at appropriate place changed nothig. Outcome is still correct.
If you discover any important info, please feel free to reopen the report.
[2 Apr 2007 10:03]
Klaus Halfmann
Please try using the MysqlConnectionPoolDataSource, as in my original Testcase. (Not Connection with Properties) this triggered the bug. Perhaps the pooling of the pooling of the Connection/PreparedStatement is the Problem ...
[22 Jun 2007 7:39]
Tonci Grgin
As new info is provided I'll retest.
[3 Jan 2011 9:13]
Klaus Halfmann
As I cannot remember what Laptop this originally was I consider you leave the Test as Regression-Test and wait if it will ever fail again. Perhaps it was silently fixed by Sun/Oracle or Intel meanwhile. So I will close this bug.

Description: Trying top update a Table using a DECIMAL(24) by using a BigDecimal fails fore _some_ processors - SetBigdecimal / setObject makes No difference Both Computers Running on Windows XP SP 2 #1 / Desktop OK NUMBER_OF_PROCESSORS=2 PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 15 Model 4 Stepping 7, GenuineIntel PROCESSOR_LEVEL=15 PROCESSOR_REVISION=0407 #1 / Laptop throws "Failed to update ..." NUMBER_OF_PROCESSORS=2 PROCESSOR_ARCHITECTURE=x86 PROCESSOR_IDENTIFIER=x86 Family 6 Model 14 Stepping 8, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=0e08 How to repeat: public class TestBrokenConnector { /* CREATE TABLE XXXX ( USER DECIMAL(24) ZEROFILL NOT NULL, APP_SET BIGINT UNSIGNED NOT NULL DEFAULT 0, -- Bitset of APP_ID MODULE CHAR(16) BINARY NOT NULL, -- KEY is reserved with MySQL INSTANCE SMALLINT UNSIGNED NOT NULL DEFAULT 0, ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, T TIMESTAMP NOT NULL, VAL TEXT NOT NULL, -- Thats 2^16 ... CONSTRAINT PRIMARY KEY (USER, APP_SET,MODULE, INSTANCE), CONSTRAINT UNIQUE INDEX ID_IDX (ID) ) ENGINE=InnoDB DELAY_KEY_WRITE = 1 MIN_ROWS=100000 DEFAULT CHARACTER SET latin1 DEFAULT COLLATE latin1_bin; */ public static void main(String[] args) throws SQLException { System.out.println("java.vm.version : " + System.getProperty("java.vm.version")); System.out.println("java.vm.vendor : " + System.getProperty("java.vm.vendor")); System.out.println("java.runtime.version : " + System.getProperty("java.runtime.version")); System.out.println("os.name : " + System.getProperty("os.name")); System.out.println("os.version : " + System.getProperty("os.version ")); System.out.println("sun.management.compiler : " + System.getProperty("sun.management.compiler")); MysqlConnectionPoolDataSource myDs = new MysqlConnectionPoolDataSource(); myDs.setServerName ("localhost"); myDs.setDatabaseName("xxx"); myDs.setPassword ("xxx"); myDs.setUser ("xxx"); myDs.setUseServerPreparedStmts (false); myDs.setCachePreparedStatements(true); myDs.setDontTrackOpenResources (true); myDs.setUseUnicode(false); String UPDATE_XXXX = "UPDATE XXXX SET VAL=? " + "\nWHERE USER=?" + "\n AND 0 != APP_SET & 1 << ?" + "\n AND MODULE=? AND INSTANCE=?"; Connection con = myDs.getConnection(); Statement stm = con.createStatement(); stm.executeUpdate("DELETE FROM XXXX "); String insert = "INSERT INTO XXXX " + "\n(USER, APP_SET, MODULE, INSTANCE, VAL)" + "\nVALUES " + "\n(823006865215726505000002, 1 << 13, 'email_0', 2, 'inital value')"; stm.executeUpdate(insert); PreparedStatement pstm = con.prepareStatement(UPDATE_XXXX, Statement.NO_GENERATED_KEYS); pstm.setString (1, "some new Value"); pstm.setBigDecimal(2, new BigDecimal("823006865215726505000002")); pstm.setInt (3, 13); pstm.setString (4, "email_0"); pstm.setShort (5, (short) 2); int count = pstm.executeUpdate(); if (1 != count) { throw new SQLException("Failed to update, count=" + count + ", stmt=" + pstm); } pstm.close(); con.close(); myDs.setUseServerPreparedStmts (true); con = myDs.getConnection(); pstm = con.prepareStatement(UPDATE_XXXX, Statement.NO_GENERATED_KEYS); pstm.setString (1, "some other Value"); pstm.setBigDecimal(2, new BigDecimal("823006865215726505000002")); pstm.setInt (3, 13); pstm.setString (4, "email_0"); pstm.setShort (5, (short) 2); count = pstm.executeUpdate(); if (1 != count) { throw new SQLException("Failed to update, count=" + count + ", stmt=" + pstm); } pstm.close(); con.close(); } } Suggested fix: Check Sign-Exapnasion for Serverside Prepared Statemens. We will invetigate further using Linux, as this is our traget Plattform, expect me to update this report about tomorrow.