db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1059984 - in /db/derby/code/branches/10.7: ./ java/client/org/apache/derby/client/am/ java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Mon, 17 Jan 2011 16:53:10 GMT
Author: kahatlen
Date: Mon Jan 17 16:53:10 2011
New Revision: 1059984

URL: http://svn.apache.org/viewvc?rev=1059984&view=rev
Log:
DERBY-4964: Client driver fails to convert string to boolean with setObject(col, str, Types.BIT)

Merged revision 1059888 from trunk.

Modified:
    db/derby/code/branches/10.7/   (props changed)
    db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/CrossConverters.java
    db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/Types.java
    db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
    db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java

Propchange: db/derby/code/branches/10.7/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jan 17 16:53:10 2011
@@ -1 +1 @@
-/db/derby/code/trunk:1035603,1036769,1038514,1038813,1039084,1039268,1040658,1041338,1043227,1043389,1044096,1051026,1053724,1055169
+/db/derby/code/trunk:1035603,1036769,1038514,1038813,1039084,1039268,1040658,1041338,1043227,1043389,1044096,1051026,1053724,1055169,1059888

Modified: db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/CrossConverters.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/CrossConverters.java?rev=1059984&r1=1059983&r2=1059984&view=diff
==============================================================================
--- db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/CrossConverters.java
(original)
+++ db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/CrossConverters.java
Mon Jan 17 16:53:10 2011
@@ -25,6 +25,7 @@ import java.sql.Date;
 import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Calendar;
+import java.util.Locale;
 import org.apache.derby.shared.common.reference.SQLState;
 
 // All currently supported derby types are mapped to one of the following jdbc types:
@@ -113,6 +114,10 @@ final class CrossConverters {
     // In support of PS.setShort()
     final Object setObject(int targetType, short source) throws SqlException {
         switch (targetType) {
+        case Types.BIT:
+        case Types.BOOLEAN:
+            return Boolean.valueOf(source != 0);
+
         case Types.SMALLINT:
             return new Short(source);
 
@@ -147,6 +152,10 @@ final class CrossConverters {
     // In support of PS.setInt()
     final Object setObject(int targetType, int source) throws SqlException {
         switch (targetType) {
+        case Types.BIT:
+        case Types.BOOLEAN:
+            return Boolean.valueOf(source != 0);
+
         case Types.SMALLINT:
             if (Configuration.rangeCheckCrossConverters &&
                     (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
@@ -237,6 +246,10 @@ final class CrossConverters {
     // In support of PS.setLong()
     final Object setObject(int targetType, long source) throws SqlException {
         switch (targetType) {
+        case Types.BIT:
+        case Types.BOOLEAN:
+            return Boolean.valueOf(source != 0);
+
         case Types.SMALLINT:
             if (Configuration.rangeCheckCrossConverters &&
                     (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
@@ -279,6 +292,10 @@ final class CrossConverters {
     // In support of PS.setFloat()
     final Object setObject(int targetType, float source) throws SqlException {
         switch (targetType) {
+        case Types.BIT:
+        case Types.BOOLEAN:
+            return Boolean.valueOf(source != 0);
+
         case Types.SMALLINT:
             if (Configuration.rangeCheckCrossConverters &&
                     (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
@@ -354,6 +371,10 @@ final class CrossConverters {
     // In support of PS.setDouble()
     final Object setObject(int targetType, double source) throws SqlException {
         switch (targetType) {
+        case Types.BIT:
+        case Types.BOOLEAN:
+            return Boolean.valueOf(source != 0);
+
         case Types.SMALLINT:
             if (Configuration.rangeCheckCrossConverters &&
                     (source > Short.MAX_VALUE || source < Short.MIN_VALUE)) {
@@ -417,6 +438,11 @@ final class CrossConverters {
     // In support of PS.setBigDecimal()
     final Object setObject(int targetType, java.math.BigDecimal source) throws SqlException
{
         switch (targetType) {
+        case Types.BIT:
+        case Types.BOOLEAN:
+            return Boolean.valueOf(
+                    java.math.BigDecimal.valueOf(0L).compareTo(source) != 0);
+
         case Types.SMALLINT:
             if (Configuration.rangeCheckCrossConverters &&
                     (source.compareTo(bdMaxShortValue__) == 1 || source.compareTo(bdMinShortValue__)
== -1)) {
@@ -543,6 +569,23 @@ final class CrossConverters {
     final Object setObject(int targetDriverType, String source) throws SqlException {
         try {
             switch (targetDriverType) {
+            case Types.BIT:
+            case Types.BOOLEAN:
+            {
+                String cleanSource = source.trim().toUpperCase(Locale.ENGLISH);
+                if (cleanSource.equals("UNKNOWN")) {
+                    return null;
+                } else if (cleanSource.equals("TRUE")) {
+                    return Boolean.TRUE;
+                } else if (cleanSource.equals("FALSE")) {
+                    return Boolean.FALSE;
+                } else {
+                    throw new SqlException(agent_.logWriter_,
+                        new ClientMessageId(SQLState.LANG_FORMAT_EXCEPTION),
+                        Types.getTypeString(targetDriverType));
+                }
+            }
+
             case Types.SMALLINT:
                 return Short.valueOf(source);
 
@@ -604,8 +647,6 @@ final class CrossConverters {
      */
     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;

Modified: db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/Types.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/Types.java?rev=1059984&r1=1059983&r2=1059984&view=diff
==============================================================================
--- db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/Types.java (original)
+++ db/derby/code/branches/10.7/java/client/org/apache/derby/client/am/Types.java Mon Jan
17 16:53:10 2011
@@ -29,8 +29,7 @@ import org.apache.derby.iapi.reference.J
 public class Types {
     // -------------------------------- Driver types -------------------------------------------------
 
-    // Not currently supported as a DERBY column type.  Mapped to SMALLINT.
-    // public final static int BIT        =  java.sql.Types.BIT;          // -7;
+    public final static int BIT        =  java.sql.Types.BIT;          // -7;
 
     // Not currently supported as a DERBY column type.  Mapped to SMALLINT.
     //public final static int TINYINT 	= java.sql.Types.TINYINT;       // -6;
@@ -90,6 +89,7 @@ public class Types {
             case BIGINT:        return "BIGINT";
             case BINARY:        return "BINARY";
             case BLOB:          return "BLOB";
+            case BIT:
             case BOOLEAN:       return "BOOLEAN";
             case CHAR:          return "CHAR";
             case CLOB:          return "CLOB";

Modified: db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java?rev=1059984&r1=1059983&r2=1059984&view=diff
==============================================================================
--- db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
(original)
+++ db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/jdbcapi/ParameterMappingTest.java
Mon Jan 17 16:53:10 2011
@@ -3123,52 +3123,81 @@ public class ParameterMappingTest extend
         }
     }
 
+    /**
+     * Do the {@code setObject()} tests for {@code setXXX()}. Test both for
+     * the two-argument {@code setObject(int,Object)} method and the
+     * three-argument {@code setObject(int,Object,int)} method.
+     */
     private static void setXXX_setObject(Statement s, PreparedStatement psi,
             PreparedStatement psq, int type, Object value, String className,
             int b5o) throws SQLException, java.io.IOException {
-        {
-            s.execute("DELETE FROM PM.TYPE_AS");
 
-            SQLException sqleResult = null;
-            boolean worked;
-            try {
-                // setObject(" + className + ")
+        // Test setObject(int, Object)
+        setXXX_setObject_doWork(
+                s, psi, psq, type, value, className, b5o, false, false);
+
+        // Test setObject(int, Object) with batch execution
+        setXXX_setObject_doWork(
+                s, psi, psq, type, value, className, b5o, false, true);
+
+        // Test setObject(int, Object, int)
+        setXXX_setObject_doWork(
+                s, psi, psq, type, value, className, b5o, true, false);
+
+        // Test setObject(int, Object, int) with batch execution
+        setXXX_setObject_doWork(
+                s, psi, psq, type, value, className, b5o, true, true);
+
+    }
+
+    /**
+     * Helper method that does all the work for setXXX_setObject().
+     *
+     * @param withTypeFlag if true, use the setObject() method that takes a
+     * type parameter; otherwise, use the two-argument type-less setObject()
+     * method
+     * @param batchExecution if true, do batch execution; otherwise, do
+     * normal execution
+     */
+    private static void setXXX_setObject_doWork(
+            Statement s, PreparedStatement psi, PreparedStatement psq,
+            int type, Object value, String className, int b5o,
+            boolean withTypeFlag, boolean batchExecution)
+        throws SQLException, IOException
+    {
+        int jdbcType = jdbcTypes[type];
+        String method = "setObject(" + className + ")";
+
+        s.execute("DELETE FROM PM.TYPE_AS");
+
+        SQLException sqleResult = null;
+        boolean worked;
+        try {
+            // Set the parameter value, either with or without explicit type
+            if (withTypeFlag) {
+                psi.setObject(1, value, jdbcType);
+            } else {
                 psi.setObject(1, value);
-                psi.executeUpdate();
-                getValidValue(psq, jdbcTypes[type], "setObject(" + className
-                        + ")");
-                worked = true;
-
-            } catch (SQLException sqle) {
-                sqleResult = sqle;
-                worked = false;
             }
-            judge_setObject(worked, sqleResult, b5o, type);
-        }
-        {
-            s.execute("DELETE FROM PM.TYPE_AS");
 
-            SQLException sqleResult = null;
-            boolean worked;
-            try {
-                // setObject(" + className + ") as batch
-                psi.setObject(1, value);
+            // Execute the statement, either single execution or batch
+            if (batchExecution) {
                 psi.addBatch();
                 psi.executeBatch();
-                getValidValue(psq, jdbcTypes[type], "setObject(" + className
-                        + ")");
-
-                worked = true;
-
-            } catch (SQLException sqle) {
-                sqleResult = sqle;
-                worked = false;
-            } catch (Throwable t) {
-                fail("FAIL " + t.getMessage());
-                return;
+            } else {
+                psi.executeUpdate();
             }
-            judge_setObject(worked, sqleResult, b5o, type);
+
+            // Check if we got a valid value back
+            getValidValue(psq, jdbcType, method);
+            worked = true;
+        } catch (SQLException sqle) {
+            sqleResult = sqle;
+            worked = false;
         }
+
+        // Check if the we got the correct response
+        judge_setObject(worked, sqleResult, b5o, type);
     }
 
     /**

Modified: db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java?rev=1059984&r1=1059983&r2=1059984&view=diff
==============================================================================
--- db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java
(original)
+++ db/derby/code/branches/10.7/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java
Mon Jan 17 16:53:10 2011
@@ -1655,6 +1655,101 @@ public class BooleanValuesTest  extends 
 
     }
 
+    /**
+     * Verify fix for DERBY-4964 - failure to convert string to boolean with
+     * the client driver.
+     */
+    public void test_4964() throws SQLException {
+        PreparedStatement ps = prepareStatement("values cast(? as boolean)");
+
+        // These should work
+        test_4964_minion(ps, null, null);
+        test_4964_minion(ps, "unknown", null);
+        test_4964_minion(ps, "UNKNOWN", null);
+        test_4964_minion(ps, "unKnoWn", null);
+        test_4964_minion(ps, "  unknown  ", null);
+        test_4964_minion(ps, "true", Boolean.TRUE);
+        test_4964_minion(ps, "TRUE", Boolean.TRUE);
+        test_4964_minion(ps, "TrUe", Boolean.TRUE);
+        test_4964_minion(ps, "  true  ", Boolean.TRUE);
+        test_4964_minion(ps, "false", Boolean.FALSE);
+        test_4964_minion(ps, "FALSE", Boolean.FALSE);
+        test_4964_minion(ps, "FaLsE", Boolean.FALSE);
+        test_4964_minion(ps, "FaLsE", Boolean.FALSE);
+        test_4964_minion(ps, "  false  ", Boolean.FALSE);
+
+        // These should fail
+        test_4964_minion(ps, "0", BAD_CAST);
+        test_4964_minion(ps, "1", BAD_CAST);
+        test_4964_minion(ps, "2", BAD_CAST);
+        test_4964_minion(ps, "null", BAD_CAST);
+        test_4964_minion(ps, "true true", BAD_CAST);
+        test_4964_minion(ps, "false false", BAD_CAST);
+    }
+
+    /**
+     * Set a boolean parameter using a string value and verify that we get
+     * the expected result.
+     *
+     * @param ps a prepared statement that takes a boolean parameter
+     * @param input input string for the parameter
+     * @param expectedValue the expected result; either the expected Boolean return
+     * value if the operation is expected to succeed, or the SQLState of the
+     * exception if it is expected to fail
+     */
+    private void test_4964_minion(
+            PreparedStatement ps, String input, Object expectedValue)
+        throws SQLException
+    {
+        // If the expected value is a string, it denotes the SQLState of an
+        // expected failure
+        boolean shouldFail = expectedValue instanceof String;
+
+        Object[][] rows = { { expectedValue } };
+
+        // test setString(int, String)
+        try {
+            ps.setString(1, input);
+            JDBC.assertFullResultSet(ps.executeQuery(), rows, false);
+            assertFalse(shouldFail);
+        } catch (SQLException sqle) {
+            if (shouldFail) {
+                assertSQLState((String) expectedValue, sqle);
+            } else {
+                throw sqle;
+            }
+        }
+
+        // test setObject(int, Object)
+        try {
+            ps.setObject(1, input);
+            JDBC.assertFullResultSet(ps.executeQuery(), rows, false);
+            assertFalse(shouldFail);
+        } catch (SQLException sqle) {
+            if (shouldFail) {
+                assertSQLState((String) expectedValue, sqle);
+            } else {
+                throw sqle;
+            }
+        }
+
+        // test setObject(int, Object, int) with various target types
+        int[] types = { Types.BIT, Types.BOOLEAN, Types.CHAR, Types.VARCHAR };
+        for (int i = 0; i < types.length; i++) {
+            try {
+                ps.setObject(1, input, types[i]);
+                JDBC.assertFullResultSet(ps.executeQuery(), rows, false);
+                assertFalse(shouldFail);
+            } catch (SQLException sqle) {
+                if (shouldFail) {
+                    assertSQLState((String) expectedValue, sqle);
+                } else {
+                    throw sqle;
+                }
+            }
+        }
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // SQL ROUTINES



Mime
View raw message