From: Date: March 8 2007 3:28am Subject: Connector/J commit: r6340 - branches/branch_5_0/connector-j branches/branch_5_0/connector-j/src/com/mysql/jdbc branches/branch_5_0/connector-j/src/testsuite/regression trunk/connector-j trunk/connector-j/src/com/mysql/jdbc trunk/connector-j/src/testsuite/regression List-Archive: http://lists.mysql.com/commits/21447 X-Bug: 26173 Message-Id: <200703080228.l282SRKG026427@bk-internal.mysql.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modified: branches/branch_5_0/connector-j/CHANGES branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java trunk/connector-j/CHANGES trunk/connector-j/src/com/mysql/jdbc/MysqlIO.java trunk/connector-j/src/testsuite/regression/ResultSetRegressionTest.java Log: Fixed BUG#26173 - When useCursorFetch=true, sometimes server would return new, more exact metadata during the execution of the server-side prepared statement that enables this functionality, which the driver ignored (using the original metadata returned during prepare()), causing corrupt reading of data due to type mismatch when the actual rows were returned. Also fixed up an error message when non-parseable BigDecimals are involved. Modified: branches/branch_5_0/connector-j/CHANGES =================================================================== --- branches/branch_5_0/connector-j/CHANGES 2007-03-06 23:55:30 UTC (rev 6339) +++ branches/branch_5_0/connector-j/CHANGES 2007-03-08 02:28:23 UTC (rev 6340) @@ -14,6 +14,12 @@ stored procedure parameters declaration causes NumberFormatException to be thrown when calling stored procedure on JDK-1.5 or newer, as the Number classes in JDK-1.5+ are whitespace intolerant. + + - Fixed BUG#26173 - When useCursorFetch=true, sometimes server would return + new, more exact metadata during the execution of the server-side prepared + statement that enables this functionality, which the driver ignored (using + the original metadata returned during prepare()), causing corrupt reading + of data due to type mismatch when the actual rows were returned. 03-01-07 - Version 5.0.5 Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java =================================================================== --- branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-03-06 23:55:30 UTC (rev 6339) +++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-03-08 02:28:23 UTC (rev 6340) @@ -413,12 +413,12 @@ RowData rows = new CursorRowProvider( this, prepStmt, - ((com.mysql.jdbc.ResultSetMetaData) prepStmt.getMetaData()).fields); + fields); ResultSet rs = buildResultSetWithRows( callingStatement, catalog, - ((com.mysql.jdbc.ResultSetMetaData) prepStmt.getMetaData()).fields, + fields, rows, resultSetType, resultSetConcurrency, isBinaryEncoded); if (usingCursor) { Modified: branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java =================================================================== --- branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java 2007-03-06 23:55:30 UTC (rev 6339) +++ branches/branch_5_0/connector-j/src/com/mysql/jdbc/ResultSet.java 2007-03-08 02:28:23 UTC (rev 6340) @@ -3613,13 +3613,9 @@ } catch (NumberFormatException ex) { throw SQLError.createSQLException( Messages - .getString("ResultSet.Bad_format_for_BigDecimal____86") //$NON-NLS-1$ - + stringVal - + Messages - .getString("ResultSet.___in_column__87") - + columnIndex + "(" //$NON-NLS-1$ - + this.fields[columnIndex - 1] + ").", - SQLError.SQL_STATE_ILLEGAL_ARGUMENT); + .getString("ResultSet.Bad_format_for_BigDecimal", + new Object[] {stringVal, new Integer(columnIndex)}), + SQLError.SQL_STATE_ILLEGAL_ARGUMENT); } return val.toString(); Modified: branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java =================================================================== --- branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java 2007-03-06 23:55:30 UTC (rev 6339) +++ branches/branch_5_0/connector-j/src/testsuite/regression/ResultSetRegressionTest.java 2007-03-08 02:28:23 UTC (rev 6340) @@ -3966,4 +3966,49 @@ } } + /** + * Tests fix for BUG#26173 - fetching rows via cursor retrieves + * corrupted data. + * + * @throws Exception if the test fails. + */ + public void testBug26173() throws Exception { + if (!versionMeetsMinimum(5, 0)) { + return; + } + + createTable("testBug26173", + "(fkey int, fdate date, fprice decimal(15, 2), fdiscount decimal(5,3))"); + this.stmt.executeUpdate("insert into testBug26173 values (1, '2007-02-23', 99.9, 0.02)"); + + Connection fetchConn = null; + Statement stmtRead = null; + + Properties props = new Properties(); + props.setProperty("useServerPrepStmts", "true"); + props.setProperty("useCursorFetch", "true"); + + try { + + fetchConn = getConnectionWithProps(props); + stmtRead = fetchConn.createStatement(); + stmtRead.setFetchSize(1000); + + this.rs = stmtRead.executeQuery("select extract(year from fdate) as fyear, fprice * (1 - fdiscount) as fvalue from testBug26173"); + + assertTrue(this.rs.next()); + assertEquals(2007, this.rs.getInt(1)); + assertEquals("97.90200", this.rs.getString(1)); + } finally { + if (stmtRead != null) { + stmtRead.close(); + } + + if (fetchConn != null) { + fetchConn.close(); + } + + closeMemberJDBCResources(); + } + } } Modified: trunk/connector-j/CHANGES =================================================================== --- trunk/connector-j/CHANGES 2007-03-06 23:55:30 UTC (rev 6339) +++ trunk/connector-j/CHANGES 2007-03-08 02:28:23 UTC (rev 6340) @@ -18,7 +18,13 @@ stored procedure parameters declaration causes NumberFormatException to be thrown when calling stored procedure on JDK-1.5 or newer, as the Number classes in JDK-1.5+ are whitespace intolerant. - + + - Fixed BUG#26173 - When useCursorFetch=true, sometimes server would return + new, more exact metadata during the execution of the server-side prepared + statement that enables this functionality, which the driver ignored (using + the original metadata returned during prepare()), causing corrupt reading + of data due to type mismatch when the actual rows were returned. + 03-01-07 - Version 5.0.5 - Fixed BUG#23645 - Some collations/character sets reported as "unknown" Modified: trunk/connector-j/src/com/mysql/jdbc/MysqlIO.java =================================================================== --- trunk/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-03-06 23:55:30 UTC (rev 6339) +++ trunk/connector-j/src/com/mysql/jdbc/MysqlIO.java 2007-03-08 02:28:23 UTC (rev 6340) @@ -410,12 +410,12 @@ RowData rows = new CursorRowProvider( this, prepStmt, - ((com.mysql.jdbc.ResultSetMetaData) prepStmt.getMetaData()).fields); + fields); ResultSet rs = buildResultSetWithRows( callingStatement, catalog, - ((com.mysql.jdbc.ResultSetMetaData) prepStmt.getMetaData()).fields, + fields, rows, resultSetType, resultSetConcurrency, isBinaryEncoded); if (usingCursor) { Modified: trunk/connector-j/src/testsuite/regression/ResultSetRegressionTest.java =================================================================== --- trunk/connector-j/src/testsuite/regression/ResultSetRegressionTest.java 2007-03-06 23:55:30 UTC (rev 6339) +++ trunk/connector-j/src/testsuite/regression/ResultSetRegressionTest.java 2007-03-08 02:28:23 UTC (rev 6340) @@ -3966,4 +3966,49 @@ } } + /** + * Tests fix for BUG#26173 - fetching rows via cursor retrieves + * corrupted data. + * + * @throws Exception if the test fails. + */ + public void testBug26173() throws Exception { + if (!versionMeetsMinimum(5, 0)) { + return; + } + + createTable("testBug26173", + "(fkey int, fdate date, fprice decimal(15, 2), fdiscount decimal(5,3))"); + this.stmt.executeUpdate("insert into testBug26173 values (1, '2007-02-23', 99.9, 0.02)"); + + Connection fetchConn = null; + Statement stmtRead = null; + + Properties props = new Properties(); + props.setProperty("useServerPrepStmts", "true"); + props.setProperty("useCursorFetch", "true"); + + try { + + fetchConn = getConnectionWithProps(props); + stmtRead = fetchConn.createStatement(); + stmtRead.setFetchSize(1000); + + this.rs = stmtRead.executeQuery("select extract(year from fdate) as fyear, fprice * (1 - fdiscount) as fvalue from testBug26173"); + + assertTrue(this.rs.next()); + assertEquals(2007, this.rs.getInt(1)); + assertEquals("97.90200", this.rs.getString(1)); + } finally { + if (stmtRead != null) { + stmtRead.close(); + } + + if (fetchConn != null) { + fetchConn.close(); + } + + closeMemberJDBCResources(); + } + } }