You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2010/06/03 18:10:16 UTC

svn commit: r951047 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/types/SQLBoolean.java engine/org/apache/derby/impl/sql/compile/BooleanTypeCompiler.java testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java

Author: rhillegas
Date: Thu Jun  3 16:10:15 2010
New Revision: 951047

URL: http://svn.apache.org/viewvc?rev=951047&view=rev
Log:
DERBY-4684: Fix implicit casts to BOOLEAN.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBoolean.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BooleanTypeCompiler.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBoolean.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBoolean.java?rev=951047&r1=951046&r2=951047&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBoolean.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/SQLBoolean.java Thu Jun  3 16:10:15 2010
@@ -30,6 +30,7 @@ import org.apache.derby.iapi.services.io
 import org.apache.derby.iapi.services.io.StoredFormatIds;
 
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.SQLState;
 
 import org.apache.derby.iapi.types.DataValueDescriptor;
 import org.apache.derby.iapi.types.TypeId;
@@ -628,7 +629,14 @@ public final class SQLBoolean
 	}
 	protected void setFrom(DataValueDescriptor theValue) throws StandardException {
 
-		setValue(theValue.getBoolean());
+        if ( theValue instanceof SQLChar ) { setValue( theValue.getString() ); }
+		else if ( theValue instanceof SQLBoolean ){ setValue(theValue.getBoolean()); }
+        else
+        {
+            throw StandardException.newException
+                ( SQLState.LANG_DATA_TYPE_SET_MISMATCH, theValue.getTypeName(), getTypeName() );
+
+        }
 	}
 
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BooleanTypeCompiler.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BooleanTypeCompiler.java?rev=951047&r1=951046&r2=951047&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BooleanTypeCompiler.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/BooleanTypeCompiler.java Thu Jun  3 16:10:15 2010
@@ -68,10 +68,8 @@ public class BooleanTypeCompiler extends
 	/** @see TypeCompiler#storable */
 	public boolean storable(TypeId otherType, ClassFactory cf)
 	{
-		/* Are the types the same or is other type a string or number type? */
-		if (otherType.isBooleanTypeId() ||
-				otherType.isStringTypeId() ||
-				otherType.isNumericTypeId())
+		/* Are the types the same or is other type a string */
+		if ( otherType.isBooleanTypeId() || otherType.isStringTypeId() )
 		{
 			return true;
 		}

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java?rev=951047&r1=951046&r2=951047&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/BooleanValuesTest.java Thu Jun  3 16:10:15 2010
@@ -50,6 +50,8 @@ public class BooleanValuesTest  extends 
 
     private static final String ILLEGAL_GET = "22005";
     private static final String ILLEGAL_XML_SELECTION = "42Z71";
+    private static final String BAD_CAST = "22018";
+    private static final String NOT_UNION_COMPATIBLE = "42X61";
 
     ///////////////////////////////////////////////////////////////////////////////////
     //
@@ -319,6 +321,7 @@ public class BooleanValuesTest  extends 
      * <ul>
      * <li>Add a new column to ALL_TYPES and corresponding rows (see setUp())</li>
      * <li>Add the new datatype to one of the tests below</li>
+     * <li>Add a new bad implicit cast to test_06_implicitCasts()</li>
      * </ul>
      */
     public void test_01_datatypeCount() throws Exception
@@ -387,6 +390,7 @@ public class BooleanValuesTest  extends 
         vet_getBooleanIsIllegal( conn, "TIMESTAMP_COL" );
         vet_getBooleanIsIllegal( conn, "VARCHAR_FOR_BIT_DATA_COL" );
     }
+    
     /**
      * <p>
      * Regression tests for outliers. If this behavior changes,
@@ -408,6 +412,7 @@ public class BooleanValuesTest  extends 
                  );
         }
     }
+
     /**
      * <p>
      * Test that ResultSet.getBoolean() returns  the correct value. Expects to
@@ -488,6 +493,124 @@ public class BooleanValuesTest  extends 
 
     }
     
+    /**
+     * <p>
+     * Test that values are implicitly cast to boolean according to the rules in the SQL Standard,
+     * part 2, section 6.12 (<cast specification>), general rule 20. Other than booleans themselves,
+     * the only legal casts are from string types to boolean. The following transformations are applied
+     * to the strings:
+     * </p>
+     *
+     * <ul>
+     * <li>Trim whitespace off the string</li>
+     * <li>Then apply the rules in section 5.3 (<literal>). This means that the trimmed string must be 'TRUE', 'FALSE', or 'UNKNOWN', regardless of case.</li>
+     * <li>Otherwise, raise an exception.</li>
+     * </ul>
+     *
+     * <p>
+     * See <a href="https://issues.apache.org/jira/browse/DERBY-4658">DERBY-4658</a>.
+     * </p>
+     */
+    public void test_06_implicitCasts() throws Exception
+    {
+        Connection conn = getConnection();
+
+        vetGoodImplicitCastFromString( conn, "'true'", Boolean.TRUE );
+        vetGoodImplicitCastFromString( conn, "'false'", Boolean.FALSE );
+        vetGoodImplicitCastFromString( conn, "'TRUE'", Boolean.TRUE );
+        vetGoodImplicitCastFromString( conn, "'FALSE'", Boolean.FALSE );
+        vetGoodImplicitCastFromString( conn, "' true '", Boolean.TRUE );
+        vetGoodImplicitCastFromString( conn, "' false '", Boolean.FALSE );
+
+        vetGoodImplicitCastFromString( conn, "cast (null as char( 10 ) )", null );
+        vetGoodImplicitCastFromString( conn, "cast (null as clob )", null );
+        vetGoodImplicitCastFromString( conn, "cast (null as long varchar )", null );
+        vetGoodImplicitCastFromString( conn, "cast (null as varchar( 10 ) )", null );
+
+        vetGoodImplicitCastFromString( conn, "cast ('true' as char( 10 ) )", Boolean.TRUE );
+        vetGoodImplicitCastFromString( conn, "cast ('true' as clob )", Boolean.TRUE );
+        vetGoodImplicitCastFromString( conn, "cast ('true' as long varchar)", Boolean.TRUE );
+        vetGoodImplicitCastFromString( conn, "cast ('true' as varchar( 10 ) )", Boolean.TRUE );
+
+        vetGoodImplicitCastFromString( conn, "cast ('false' as char( 10 ) )", Boolean.FALSE );
+        vetGoodImplicitCastFromString( conn, "cast ('false' as clob )", Boolean.FALSE );
+        vetGoodImplicitCastFromString( conn, "cast ('false' as long varchar)", Boolean.FALSE );
+        vetGoodImplicitCastFromString( conn, "cast ('false' as varchar( 10 ) )", Boolean.FALSE );
+        
+        expectExecutionError( conn, BAD_CAST, makeImplicitCast( "'neither'" ) );
+
+        expectExecutionError( conn, BAD_CAST, makeImplicitCast( "cast ('neither' as char(10))" ) );
+        expectExecutionError( conn, BAD_CAST, makeImplicitCast( "cast ('neither' as clob)" ) );
+        expectExecutionError( conn, BAD_CAST, makeImplicitCast( "cast ('neither' as long varchar)" ) );
+        expectExecutionError( conn, BAD_CAST, makeImplicitCast( "cast ('neither' as varchar(10))" ) );
+
+        vetBadImplicitCasts( conn, "bigint_col" );
+        vetBadImplicitCasts( conn, "blob_col" );
+        // char type ok
+        vetBadImplicitCasts( conn, "char_for_bit_data_col" );
+        // clob type ok
+        vetBadImplicitCasts( conn, "date_col" );
+        vetBadImplicitCasts( conn, "decimal_col" );
+        vetBadImplicitCasts( conn, "real_col" );
+        vetBadImplicitCasts( conn, "double_col" );
+        vetBadImplicitCasts( conn, "int_col" );
+        // long varchar type ok
+        vetBadImplicitCasts( conn, "long_varchar_for_bit_data_col" );
+        vetBadImplicitCasts( conn, "numeric_col" );
+        vetBadImplicitCasts( conn, "smallint_col" );
+        vetBadImplicitCasts( conn, "time_col" );
+        vetBadImplicitCasts( conn, "timestamp_col" );
+        // varchar type ok
+        vetBadImplicitCasts( conn, "varchar_for_bit_data_col" );
+        if ( _supportsXML ) { vetBadImplicitCasts( conn, "xml_col" ); }
+    }
+    private void vetGoodImplicitCastFromString( Connection conn, String text, Boolean booleanValue ) throws Exception
+    {
+        String expectedValue = null;
+        if ( booleanValue != null ) { expectedValue = booleanValue.toString(); }
+
+        assertResults
+            (
+             conn,
+             makeImplicitCast( text ),
+             new String[][]
+             {
+                 { expectedValue },
+             },
+             false
+             );
+    }
+    private String makeImplicitCast( String text )
+    {
+        return
+            "select isindex from sys.sysconglomerates where conglomeratename = 'foo'\n" +
+            "union\n" +
+            "values ( " + text + " )\n";
+    }
+    private void vetBadImplicitCasts( Connection conn, String columnName ) throws Exception
+    {
+        vetBadImplicitCastToBoolean( conn, columnName );
+        vetBadImplicitCastFromBoolean( conn, columnName );
+    }
+    private void vetBadImplicitCastToBoolean( Connection conn, String columnName ) throws Exception
+    {
+        String query =
+            "select isindex from sys.sysconglomerates where conglomeratename = 'foo'\n" +
+            "union\n" +
+            "select " + columnName + " from all_types\n";
+        
+        expectCompilationError( NOT_UNION_COMPATIBLE, query );
+    }
+    private void vetBadImplicitCastFromBoolean( Connection conn, String columnName ) throws Exception
+    {
+        String query =
+            "select " + columnName + " from all_types\n" +
+            "union\n" +
+            "select isindex from sys.sysconglomerates\n";
+        
+        expectCompilationError( NOT_UNION_COMPATIBLE, query );
+    }
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // SQL ROUTINES