Hi Thomas,

The following patch for subversion revision 1121 fixes a scale problem
with JavaFunction.java.  Namely, the getScale() method always returns
0.  This is not appropriate for functions which return the DECIMAL
data type.  Please consider accepting it into the main code base.

--- BEGIN PATCH ---

--- JavaFunction.java.orig      2008-12-09 12:58:15.000000000 -0500
+++ JavaFunction.java   2008-12-09 13:05:24.000000000 -0500
@@ -14,6 +14,7 @@
 import org.h2.table.ColumnResolver;
 import org.h2.table.TableFilter;
 import org.h2.value.Value;
+import org.h2.value.ValueDecimal;
 import org.h2.value.ValueNull;
 import org.h2.value.ValueResultSet;

@@ -64,7 +65,7 @@
     }

     public int getScale() {
-        return 0;
+        return (getType() == Value.DECIMAL ?
ValueDecimal.DEFAULT_SCALE : 0);
     }

     public long getPrecision() {

--- END PATCH ---

Below is a test case which illustrates the problem.  When dealing with
the substitution parameter of unknown type in the prepared statement,
H2 casts the parameter to DECIMAL to match the type of the function on
the left side of the equals operator, but it uses a scale of 0 in the
unpatched code.  This causes the substitution parameter's value to be
rounded, which makes the comparison fail (or succeed) in cases where
it shouldn't.

The test case should always always print a result of "1.6", but with
the unpatched version it prints "2.0".

Thanks,
Eric Faulhaber

--- BEGIN TEST CASE ---


import java.math.*;
import java.sql.*;

public class JavaFunctionScaleTest
{
   public static BigDecimal noOp(BigDecimal dec)
   {
      return dec;
   }

   public static void main(String[] args)
   {
      try
      {
         Class.forName("org.h2.Driver");
         Connection conn = DriverManager.getConnection
("jdbc:h2:mem:_temp");
         String[] ddl = new String[]
         {
            "create temporary table tt1 (a numeric)",
            "create alias no_op for \"JavaFunctionScaleTest.noOp\"",
            "insert into tt1 (a) values(1.6)",
            "insert into tt1 (a) values(2.0)",
         };
         Statement stmt = conn.createStatement();
         for (int i = 0; i < ddl.length; i++)
         {
            stmt.execute(ddl[i]);
         }

         String query = "select a from tt1 where no_op(a) = ?";
         PreparedStatement ps = conn.prepareStatement(query);
         BigDecimal parm = new BigDecimal("1.6");
         ps.setBigDecimal(1, parm);
         ResultSet rs = ps.executeQuery();

         System.out.println("Results:");
         while (rs.next())
         {
            BigDecimal dec = rs.getBigDecimal("a");
            System.out.println("   " + dec);
         }
      }
      catch (Exception exc)
      {
         exc.printStackTrace();
      }
   }
}

--- END TEST CASE ---
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/h2-database?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to