db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Satheesh Bandaram <sathe...@Sourcery.Org>
Subject Re: [PATCH] Derby-250 With client setObject( parameterIndex, x, java.sql.DOUBLE) throws conversion exception if the object passed is a BigDecimal with more than 31 digits
Date Fri, 29 Apr 2005 17:13:48 GMT
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
+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.<br>
<br>
Satheesh<br>
<br>
Kathey Marsden wrote:<br>
<blockquote cite="mid42722F24.9050706@sbcglobal.net" type="cite">
  <pre wrap="">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 &lt;Date|Time|TimeStamp&gt;.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


  </pre>
  <pre wrap="">
<hr size="4" width="90%">
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 &amp;&amp; (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 &amp;&amp; (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] &amp; 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 <a class="moz-txt-link-freetext" href="Timestamp:20">Timestamp:20</a>
 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 <a class="moz-txt-link-freetext" href="Timestamp:20">Timestamp:20</a>
 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 <a class="moz-txt-link-freetext" href="Timestamp:20">Timestamp:20</a>
 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  &amp;&amp; s.length() &gt;= 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 != ':' &amp;&amp; colon != '.') throw new java.lang.IllegalArgumentException
(formatError);
 
-    int minute = 10*getDigit (s, 3);
-    minute += 1*getDigit (s, 4);
-
-    colon = s.charAt(5);
-    if (colon != ':' &amp;&amp; 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 != ' ' &amp;&amp; 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 != ':' &amp;&amp; colon != '.') throw new java.lang.IllegalArgumentException
(formatError);
-
-    int minute = 10*getDigit (s, 14);
-    minute += 1*getDigit (s, 15);
-
-    colon = s.charAt(16);
-    if (colon != ':' &amp;&amp; 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);
   }
 
+	
+
 }
  </pre>
</blockquote>
</body>
</html>


Mime
View raw message