+1. I suspect the change to TestRelative is for some other purpose, but that looks right too. Not sure if Shreyas was going to checkin that part, though.

Satheesh

Kathey Marsden wrote:
This is a patch for Derby-250 to eliminate the conversion error when a
BigDecimal with more than
31 digits is  passed to setObject  with a targetSqlType.
public void setObject(int parameterIndex,
                      Object x,
                      int targetSqlType)
               throws SQLException
or
public void setObject(int parameterIndex,
                      Object x,
                      int targetSqlType,
                      int scale)
               throws SQLException

The approach of the patch is to have setObject calls with a
targetSqlType  to always convert before sending to the value to the
server for all types.

Taking this approach exposed other issues with  the client's conversion
mechanism for Date, Time and Timestamp,
which were customized valueOf  methods to support ISO format.   Since
the extended format is not needed for Derby, I replaced these with the
standard <Date|Time|TimeStamp>.valueOf calls.

The patch also fixes issues with scale getting set properly when
specified for these calls.

I'll commit this afternoon if there are no objections.

Thanks

Kathey


  

Index: java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/testRelative.java =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/testRelative.java (revision 165209) +++ java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/testRelative.java (working copy) @@ -8,32 +8,34 @@ public class testRelative { - static final String EXPECTED_SQL_STATE = "24000"; - static Connection con; - static ResultSet rs; - static PreparedStatement stmt = null; - static PreparedStatement pStmt = null; - static Statement stmt1 = null; - static String returnValue = null; - + static final String NO_CURRENT_ROW_SQL_STATE = "24000"; + public static void main(String[] args) { - test1(args); + System.out.println("Test testRelative starting"); + Connection con = null; + try { + // use the ij utility to read the property file and + // make the initial connection. + ij.getPropertyArg(args); + con = ij.startJBMS(); + test1(con); + } catch (Exception e) + { + unexpectedException(e); + } } - public static void test1(String []args) { - System.out.println("Test testRelative starting"); - - try - { - // use the ij utility to read the property file and - // make the initial connection. - ij.getPropertyArg(args); - con = ij.startJBMS(); - - con.setAutoCommit(false); - - stmt = con.prepareStatement("create table testRelative(name varchar(10), i int)"); - stmt.executeUpdate(); + public static void test1(Connection con) { + ResultSet rs = null; + PreparedStatement pStmt = null; + Statement stmt1 = null; + String returnValue = null; + + try + { + con.setAutoCommit(false); + pStmt = con.prepareStatement("create table testRelative(name varchar(10), i int)"); + pStmt.executeUpdate(); con.commit(); pStmt = con.prepareStatement("insert into testRelative values (?,?)"); @@ -89,7 +91,7 @@ System.out.println("Value="+returnValue); } catch(SQLException sqle) { - dumpSQLExceptions(sqle); + expectedException(sqle, NO_CURRENT_ROW_SQL_STATE); } catch(Throwable e) { System.out.println("FAIL -- unexpected exception: "+e.getMessage()); e.printStackTrace(System.out); @@ -98,28 +100,42 @@ } /** - * This is to print the expected Exception's details. We are here because we got an Exception - * when we expected one, but checking to see that we got the right one. - **/ - static private void dumpSQLExceptions (SQLException se) { - if( se.getSQLState() != null && (se.getSQLState().equals(EXPECTED_SQL_STATE))) { + * Print the expected Exception's details if the SQLException SQLState + * matches the expected SQLState. Otherwise fail + * + * @param se SQLException that was thrown by the test + * @param expectedSQLState The SQLState that we expect. + * + **/ + static private void expectedException (SQLException se, String expectedSQLState) { + if( se.getSQLState() != null && (se.getSQLState().equals(expectedSQLState))) { System.out.println("PASS -- expected exception"); while (se != null) { System.out.println("SQLSTATE("+se.getSQLState()+"): "+se.getMessage()); se = se.getNextException(); } } else { - System.out.println("FAIL--Unexpected SQLException: "+se.getMessage()); + System.out.println("FAIL--Unexpected SQLException: " + + "SQLSTATE(" +se.getSQLState() + ")" + + se.getMessage()); se.printStackTrace(System.out); } - } + } /** * We are here because we got an exception when did not expect one. * Hence printing the message and stack trace here. **/ static private void unexpectedSQLException(SQLException se) { - System.out.println("FAIL -- Unexpected Exception: "+ se.getMessage()); + System.out.println("FAIL -- Unexpected Exception: "+ + "SQLSTATE(" +se.getSQLState() +")" + + se.getMessage()); se.printStackTrace(System.out); } + + static private void unexpectedException(Exception e) { + System.out.println("FAIL -- Unexpected Exception: "+ + e.getMessage()); + } + } Index: java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java (revision 165209) +++ java/testing/org/apache/derbyTesting/functionTests/tests/derbynet/prepStmt.java (working copy) @@ -296,7 +296,8 @@ test4975(conn); test5130(conn); test5172(conn); - + testBigDecimalSetObject(conn); + testBigDecimalSetObjectWithScale(conn); conn.close(); System.out.println("prepStmt Test Ends"); } @@ -414,7 +415,7 @@ rBigDecimalVal = (BigDecimal) rs.getObject(1); logMsg("Returned BigDecimal Value after Updation: " + rBigDecimalVal); - logMsg("Value returned from ctssql.stmt: " + minBigDecimalVal); + logMsg("Value returned from stmt: " + minBigDecimalVal); if(rBigDecimalVal.compareTo(minBigDecimalVal) == 0) { @@ -528,7 +529,128 @@ ps.close(); } + private static void testBigDecimalSetObject(Connection conn) throws SQLException + { + setupTestBigDecimalTabs(conn); + testBigDecimalToDoubleConversion(conn); + } + + + private static void setupTestBigDecimalTabs(Connection conn) throws SQLException + { + String sql; + Statement stmt = conn.createStatement(); + try { + stmt.executeUpdate("DROP TABLE doubletab"); + } + catch (SQLException se) + { + //System.out.println("Table doubletab not dropped. " + se.getMessage()); + + } + + sql = "CREATE TABLE doubletab (d1 DOUBLE , d2 DOUBLE)"; + + System.out.println(sql); + stmt.executeUpdate(sql); + + + // Insert little and big values + sql = "INSERT INTO doubletab VALUES(1.0E-130,1.0E125)"; + System.out.println(sql); + stmt.executeUpdate(sql); + conn.commit(); + + } + + private static void testBigDecimalToDoubleConversion(Connection conn) throws SQLException + { + System.out.println("\n\ntestBigDecimalToDoubleConversion()."); + System.out.println(" Check that values are preserved when BigDecimal \n values which have more than 31 digits are converted \n to Double with setObject"); + Statement stmt = conn.createStatement(); + String sql ="SELECT d1, d2 FROM doubletab"; + System.out.println(sql); + ResultSet rs = stmt.executeQuery(sql); + rs.next(); + String d1String = rs.getString(1); + String d2String = rs.getString(2); + // make BigDecimals from the Strings + BigDecimal bd1FromString = new BigDecimal(d1String); + BigDecimal bd2FromString = new BigDecimal(d2String); + System.out.println("rs.getString(1)=" + bd1FromString); + System.out.println("rs.getString(2)=" + bd2FromString); + // prepare a statement which updates the values in the table + sql = "UPDATE doubletab SET d1 = ?, d2 = ?"; + System.out.println("conn.prepareStatement(" + sql + ")"); + PreparedStatement ps = conn.prepareStatement(sql); + ps = conn.prepareStatement(sql); + // setObject using the BigDecimal values + System.out.println("ps.setObject(1," + bd1FromString + ",java.sql.Types.DOUBLE)"); + System.out.println("ps.setObject(2," + bd2FromString + ",java.sql.Types.DOUBLE)"); + ps.setObject(1,bd1FromString,java.sql.Types.DOUBLE); + ps.setObject(2,bd2FromString,java.sql.Types.DOUBLE); + ps.executeUpdate(); + // check that the values did not change + sql = "SELECT d1, d2 FROM doubletab"; + System.out.println(sql); + rs = stmt.executeQuery(sql); + rs.next(); + System.out.println("values should match"); + System.out.println("new d1:" + rs.getObject(1).toString() + + " old d1:" + d1String); + System.out.println("new d2:" + rs.getObject(2).toString() + + " old d2:" + d2String); + + rs.close(); + ps.close(); + stmt.close(); + conn.commit(); + } + + static void testBigDecimalSetObjectWithScale(Connection conn) throws Exception + { + Statement stmt = conn.createStatement(); + String sql = null; + + System.out.println("\n\ntestBigDecimalSetObjectWithScale(). \nPass scale parameter of setObject"); + + try { + stmt.executeUpdate("DROP TABLE numtab"); + } + catch (SQLException se) + { + //System.out.println("Table numtab not dropped. " + se.getMessage()); + } + sql = "CREATE TABLE numtab (num NUMERIC(10,6))"; + System.out.println(sql); + stmt.executeUpdate(sql); + + // make a big decimal from string + BigDecimal bdFromString = new BigDecimal("2.33333333"); + + // prepare a statement which updates the third column of the table with + // the DOUBLE columns + sql = "INSERT INTO numtab VALUES(?)"; + System.out.println("conn.prepareStatement(" + sql + ")"); + PreparedStatement ps = conn.prepareStatement(sql); + // setObject using the big decimal value + System.out.println("ps.setObject(1," + bdFromString + ",java.sql.Types.DECIMAL,2)"); + ps.setObject(1,bdFromString,java.sql.Types.DECIMAL,2); + ps.executeUpdate(); + // check the value + sql = "SELECT num FROM numtab"; + ResultSet rs = stmt.executeQuery(sql); + rs.next(); + System.out.println("num is:" + rs.getObject(1).toString()); + + rs.close(); + ps.close(); + stmt.close(); + + conn.commit(); + } + private static String bytesToString(byte[] ba) { String s = null; @@ -539,4 +661,7 @@ s += (Integer.toHexString(ba[i] & 0x00ff)); return s; } + + } + Index: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out (revision 165209) +++ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNet/jdk15/prepStmt.out (working copy) @@ -58,8 +58,30 @@ Prepared Statement String: update Numeric_Tab set NULL_VAL=? Select NULL_VAL from Numeric_Tab Returned BigDecimal Value after Updation: 1E-15 -Value returned from ctssql.stmt: 1E-15 +Value returned from stmt: 1E-15 setObject Method sets the designated parameter with the Object Negative test setString with Invalid Timestamp:20 SQLState: 22007 message: The syntax of the string representation of a datetime value is incorrect. +CREATE TABLE doubletab (d1 DOUBLE , d2 DOUBLE) +INSERT INTO doubletab VALUES(1.0E-130,1.0E125) +testBigDecimalToDoubleConversion(). + Check that values are preserved when BigDecimal + values which have more than 31 digits are converted + to Double with setObject +SELECT d1, d2 FROM doubletab +rs.getString(1)=1.0E-130 +rs.getString(2)=1.0E+125 +conn.prepareStatement(UPDATE doubletab SET d1 = ?, d2 = ?) +ps.setObject(1,1.0E-130,java.sql.Types.DOUBLE) +ps.setObject(2,1.0E+125,java.sql.Types.DOUBLE) +SELECT d1, d2 FROM doubletab +values should match +new d1:1.0E-130 old d1:1.0E-130 +new d2:1.0E125 old d2:1.0E125 +testBigDecimalSetObjectWithScale(). +Pass scale parameter of setObject +CREATE TABLE numtab (num NUMERIC(10,6)) +conn.prepareStatement(INSERT INTO numtab VALUES(?)) +ps.setObject(1,2.33333333,java.sql.Types.DECIMAL,2) +num is:2.330000 prepStmt Test Ends Index: java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out (revision 165209) +++ java/testing/org/apache/derbyTesting/functionTests/master/prepStmt.out (working copy) @@ -58,8 +58,30 @@ Prepared Statement String: update Numeric_Tab set NULL_VAL=? Select NULL_VAL from Numeric_Tab Returned BigDecimal Value after Updation: 0.000000000000001 -Value returned from ctssql.stmt: 0.000000000000001 +Value returned from stmt: 0.000000000000001 setObject Method sets the designated parameter with the Object Negative test setString with Invalid Timestamp:20 SQLState: 22007 message: The syntax of the string representation of a datetime value is incorrect. +CREATE TABLE doubletab (d1 DOUBLE , d2 DOUBLE) +INSERT INTO doubletab VALUES(1.0E-130,1.0E125) +testBigDecimalToDoubleConversion(). + Check that values are preserved when BigDecimal + values which have more than 31 digits are converted + to Double with setObject +SELECT d1, d2 FROM doubletab +rs.getString(1)=0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010 +rs.getString(2)=100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +conn.prepareStatement(UPDATE doubletab SET d1 = ?, d2 = ?) +ps.setObject(1,0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010,java.sql.Types.DOUBLE) +ps.setObject(2,100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,java.sql.Types.DOUBLE) +SELECT d1, d2 FROM doubletab +values should match +new d1:1.0E-130 old d1:1.0E-130 +new d2:1.0E125 old d2:1.0E125 +testBigDecimalSetObjectWithScale(). +Pass scale parameter of setObject +CREATE TABLE numtab (num NUMERIC(10,6)) +conn.prepareStatement(INSERT INTO numtab VALUES(?)) +ps.setObject(1,2.33333333,java.sql.Types.DECIMAL,2) +num is:2.330000 prepStmt Test Ends Index: java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out =================================================================== --- java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out (revision 165209) +++ java/testing/org/apache/derbyTesting/functionTests/master/DerbyNetClient/jdk15/prepStmt.out (working copy) @@ -58,8 +58,30 @@ Prepared Statement String: update Numeric_Tab set NULL_VAL=? Select NULL_VAL from Numeric_Tab Returned BigDecimal Value after Updation: 1E-15 -Value returned from ctssql.stmt: 1E-15 +Value returned from stmt: 1E-15 setObject Method sets the designated parameter with the Object Negative test setString with Invalid Timestamp:20 SQLState: 22007 message: The syntax of the string representation of a datetime value is incorrect. +CREATE TABLE doubletab (d1 DOUBLE , d2 DOUBLE) +INSERT INTO doubletab VALUES(1.0E-130,1.0E125) +testBigDecimalToDoubleConversion(). + Check that values are preserved when BigDecimal + values which have more than 31 digits are converted + to Double with setObject +SELECT d1, d2 FROM doubletab +rs.getString(1)=1.0E-130 +rs.getString(2)=1.0E+125 +conn.prepareStatement(UPDATE doubletab SET d1 = ?, d2 = ?) +ps.setObject(1,1.0E-130,java.sql.Types.DOUBLE) +ps.setObject(2,1.0E+125,java.sql.Types.DOUBLE) +SELECT d1, d2 FROM doubletab +values should match +new d1:1.0E-130 old d1:1.0E-130 +new d2:1.0E125 old d2:1.0E125 +testBigDecimalSetObjectWithScale(). +Pass scale parameter of setObject +CREATE TABLE numtab (num NUMERIC(10,6)) +conn.prepareStatement(INSERT INTO numtab VALUES(?)) +ps.setObject(1,2.33333333,java.sql.Types.DECIMAL,2) +num is:2.330000 prepStmt Test Ends Index: java/client/org/apache/derby/client/am/CrossConverters.java =================================================================== --- java/client/org/apache/derby/client/am/CrossConverters.java (revision 165209) +++ java/client/org/apache/derby/client/am/CrossConverters.java (working copy) @@ -562,7 +562,32 @@ + " is invalid for requested conversion."); } } + // ------ method to convert to targetJdbcType------ + /** + * Convert the input targetJdbcType to the correct JdbcType used by + * CrossConverters. + * @param jdbcType + */ + public static int getInputJdbcType(int jdbcType) + { + switch (jdbcType) + { + case java.sql.Types.BIT: + case java.sql.Types.BOOLEAN: + case java.sql.Types.TINYINT: + case java.sql.Types.SMALLINT: + return java.sql.Types.INTEGER; + case java.sql.Types.NUMERIC: + return java.sql.Types.DECIMAL; + case java.sql.Types.FLOAT: + return java.sql.Types.DOUBLE; + default: + return jdbcType; + } + + } + // -- methods in support of setObject(String)/getString() on BINARY columns--- @@ -1177,7 +1202,6 @@ final java.sql.Date getDateFromString (String source) throws SqlException { try { - // We override the JRE's Date.valueOf() in order to support a more Extended ISO format as requested by Toronto team return date_valueOf (source); } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException @@ -1202,7 +1226,6 @@ final java.sql.Time getTimeFromString (String source) throws SqlException { try { - // We override the JRE's Time.valueOf() in order to support a more Extended ISO format as requested by Toronto team return time_valueOf (source); } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException @@ -1222,7 +1245,6 @@ final java.sql.Timestamp getTimestampFromString (String source) throws SqlException { try { - // We override the JRE's Timestamp.valueOf() in order to support a more Extended ISO format as requested by Toronto team return timestamp_valueOf (source); } catch (java.lang.IllegalArgumentException e) { // subsumes NumberFormatException @@ -1243,220 +1265,32 @@ return new java.sql.Timestamp (source.getTime()); } - //-------------- Customized versions of java.lang parse methods -------------- - // Converts a string in JDBC date "extended" ISO format to a Date value. - // yyyy-mm-dd with trailing blanks allowed. final java.sql.Date date_valueOf (String s) throws java.lang.IllegalArgumentException { String formatError = "JDBC Date format must be yyyy-mm-dd"; if (s == null) throw new java.lang.IllegalArgumentException (formatError); - - int year = 1000*getDigit (s, 0); - year += 100*getDigit (s, 1); - year += 10*getDigit (s, 2); - year += 1*getDigit (s, 3); - - char hyphen = s.charAt (4); - if (hyphen != '-') throw new java.lang.IllegalArgumentException (formatError); - - int month =0; - int day = 0; - int pos =0; - - hyphen = s.charAt (6); - if(hyphen == '-') { //single digit month - month = getDigit (s, 5); - pos = 7; - } - else { //double digit month - month = 10 * getDigit (s, 5); - month += 1*getDigit (s, 6); - pos = 8; - hyphen = s.charAt (7); - if (hyphen != '-') throw new java.lang.IllegalArgumentException (formatError); - } - - if(s.length() == (pos + 1) || Character.digit(s.charAt(pos +1), 10) == -1) { //single digit day - day = getDigit (s, pos); - pos ++; - } - else { //double digit day - day = 10 * getDigit (s, pos); - day += 1* getDigit (s, pos + 1); - pos = pos + 2; - } - skipPadding (s, pos, s.length()); - return new java.sql.Date (year-1900, month-1, day); + s = s.trim(); + return java.sql.Date.valueOf(s); } - // Customized versions of java.util.Date/Time/Timestamp valueOf methods - // We override the JRE's Date/Time/Timestamp.valueOf() methods in order to support a - // more Extended ISO format as requested by Toronto team. - // Also allows for space-padding of CHAR fields. - private final int getDigit (String s, int index) throws java.lang.IllegalArgumentException - { - String formatError = "Date/Time must be JDBC format"; - int digit = -1 ; - if (s != null && s.length() >= 10) - digit = Character.digit (s.charAt (index), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - return digit; - } - // Converts a string in JDBC time "extended" ISO format to a Time value. - // hh:mm:ss or hh.mm.ss with trailing blanks allowed. final java.sql.Time time_valueOf (String s) throws java.lang.IllegalArgumentException, NumberFormatException { - String formatError = "JDBC Time format must be hh:mm:ss"; if (s == null) throw new java.lang.IllegalArgumentException(); + s = s.trim(); + return java.sql.Time.valueOf(s); + } - int hour = 10*getDigit (s, 0); - hour += 1*getDigit (s, 1); - char colon = s.charAt(2); - if (colon != ':' && colon != '.') throw new java.lang.IllegalArgumentException (formatError); - int minute = 10*getDigit (s, 3); - minute += 1*getDigit (s, 4); - - colon = s.charAt(5); - if (colon != ':' && colon != '.') throw new java.lang.IllegalArgumentException (formatError); - - int second = 10*getDigit (s, 6); - second += 1*getDigit (s, 7); - - skipPadding (s, 8, s.length()); - return new java.sql.Time (hour, minute, second); - } - - // Converts a string in JDBC date "extended" ISO format to a Timestamp value. - // yyyy-mm-dd hh:mm:ss[.[n[n[n[n[n[n[n[n[n]]]]]]]] or yyyy-mm-dd-hh.mm.ss[.[n[n[n[n[n[n[n[n[n]]]]]]]] with trailing blanks allowed. final java.sql.Timestamp timestamp_valueOf (String s) throws java.lang.IllegalArgumentException, NumberFormatException { String formatError = "JDBC Timestamp format must be yyyy-mm-dd hh:mm:ss.fffffffff"; if (s == null) throw new java.lang.IllegalArgumentException(); - - int year = 1000*getDigit (s, 0); - year += 100*getDigit (s, 1); - year += 10*getDigit (s, 2); - year += 1*getDigit (s, 3); - - char hyphen = s.charAt (4); - if (hyphen != '-') throw new java.lang.IllegalArgumentException (formatError); - - int month = 10*getDigit (s, 5); - month += 1*getDigit (s, 6); - - hyphen = s.charAt (7); - if (hyphen != '-') throw new java.lang.IllegalArgumentException (formatError); - - int day = 10*getDigit (s, 8); - day += 1*getDigit (s, 9); - - char space = s.charAt (10); - if (space != ' ' && space != '-') throw new java.lang.IllegalArgumentException (formatError); - - int hour = 10*getDigit (s, 11); - hour += 1*getDigit (s, 12); - - char colon = s.charAt (13); - if (colon != ':' && colon != '.') throw new java.lang.IllegalArgumentException (formatError); - - int minute = 10*getDigit (s, 14); - minute += 1*getDigit (s, 15); - - colon = s.charAt(16); - if (colon != ':' && colon != '.') throw new java.lang.IllegalArgumentException (formatError); - - int second = 10*getDigit (s, 17); - second += 1*getDigit (s, 18); - - if (s.trim().length() == 19) return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, 0); - - char period = s.charAt (19); - if (period != '.') throw new java.lang.IllegalArgumentException (formatError); - if (s.length() == 20 || s.charAt(20) == ' ') { - skipPadding (s, 20, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, 0); - } - - // We can put the following into a while loop later.... - - int digit = Character.digit (s.charAt(20), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - int nanos = 100000000*digit; - if (s.length() == 21 || s.charAt(21) == ' ') { - skipPadding (s, 21, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(21), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 10000000*digit; - if (s.length() == 22 || s.charAt(22) == ' ') { - skipPadding (s, 22, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(22), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 1000000*digit; - if (s.length() == 23 || s.charAt(23) == ' ') { - skipPadding (s, 23, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(23), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 100000*digit; - if (s.length() == 24 || s.charAt(24) == ' ') { - skipPadding (s, 24, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(24), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 10000*digit; - if (s.length() == 25 || s.charAt(25) == ' ') { - skipPadding (s, 25, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(25), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 1000*digit; - if (s.length() == 26 || s.charAt(26) == ' ') { - skipPadding (s, 26, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(26), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 100*digit; - if (s.length() == 27 || s.charAt(27) == ' ') { - skipPadding (s, 27, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(27), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 10*digit; - if (s.length() == 28 || s.charAt(28) == ' ') { - skipPadding (s, 28, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - digit = Character.digit (s.charAt(28), 10); - if (digit == -1) throw new java.lang.IllegalArgumentException (formatError); - nanos += 1*digit; - if (s.length() == 29 || s.charAt(29) == ' ') { - skipPadding (s, 29, s.length()); - return new java.sql.Timestamp (year-1900, month-1, day, hour, minute, second, nanos); - } - - throw new java.lang.IllegalArgumentException (formatError); + s = s.trim(); + return java.sql.Timestamp.valueOf(s); } private final byte parseByte (String s) throws NumberFormatException Index: java/client/org/apache/derby/client/am/PreparedStatement.java =================================================================== --- java/client/org/apache/derby/client/am/PreparedStatement.java (revision 165209) +++ java/client/org/apache/derby/client/am/PreparedStatement.java (working copy) @@ -763,6 +763,28 @@ checkForValidScale (scale); if (x == null) { setNull (parameterIndex, targetJdbcType); return; } + // JDBC Spec specifies that conversion should occur on the client if + // the targetJdbcType is specified. + + int inputParameterType = CrossConverters.getInputJdbcType(targetJdbcType); + parameterMetaData_.clientParamtertype_[parameterIndex -1] = + inputParameterType; + x = agent_.crossConverters_.setObject (inputParameterType, x); + + // Set to round down on setScale like embedded does in SQLDecimal + try { + if (targetJdbcType == java.sql.Types.DECIMAL || + targetJdbcType == java.sql.Types.NUMERIC) + x = ((java.math.BigDecimal) x).setScale(scale, + java.math.BigDecimal.ROUND_DOWN); + } + catch (ArithmeticException ae) + { + // Any problems with scale should have already been caught by + // checkForvalidScale + throw new SqlException (agent_.logWriter_, + ae.getMessage()); + } setObject(parameterIndex, x); } @@ -1606,4 +1628,6 @@ connection_.CommitAndRollbackListeners_.remove(this); } + + }

Reply via email to