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 2014/03/17 18:37:58 UTC

svn commit: r1578479 - in /db/derby/code/trunk/java: engine/org/apache/derby/iapi/types/ engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/tests/lang/ testing/org/apache/derbyTesting/junit/

Author: rhillegas
Date: Mon Mar 17 17:37:58 2014
New Revision: 1578479

URL: http://svn.apache.org/r1578479
Log:
DERBY-6511: Convert primitives to wrapper types as appropriate when chaining functions; tests passed cleanly on derby-6511-01-aa-fixPrimitiveToWrapper.diff.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/JSQLType.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RoutineTest.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/JSQLType.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/JSQLType.java?rev=1578479&r1=1578478&r2=1578479&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/JSQLType.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/types/JSQLType.java Mon Mar 17 17:37:58 2014
@@ -327,7 +327,7 @@ public final class JSQLType implements F
 	  *
 	  *	@return	name of the java wrapper class corresponding to the primitive
 	  */
-	private	static String	getWrapperClassName
+	public	static String	getWrapperClassName
 	(
 		byte	primitive
     )
@@ -345,7 +345,7 @@ public final class JSQLType implements F
 	  *	@return	BOOLEAN, INT, ... etc if the name is that of a primitive.
 	  *			NOT_PRIMITIVE otherwise
 	  */
-	private	static byte	getPrimitiveID
+	public	static byte	getPrimitiveID
 	(
 		String	name
     )

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java?rev=1578479&r1=1578478&r2=1578479&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java Mon Mar 17 17:37:58 2014
@@ -33,6 +33,7 @@ import org.apache.derby.catalog.types.Ty
 import org.apache.derby.catalog.types.UserDefinedTypeIdImpl;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.SQLState;
+import org.apache.derby.iapi.services.classfile.VMOpcode;
 import org.apache.derby.iapi.services.compiler.LocalField;
 import org.apache.derby.iapi.services.compiler.MethodBuilder;
 import org.apache.derby.iapi.services.context.ContextManager;
@@ -578,11 +579,38 @@ abstract class MethodCallNode extends Ja
 
         if (!parameterType.equals(argumentType))
         {
+            //
+            // This handles the conversion from primitive to wrapper type. See DERBY-6511.
+            // If the parameter type is the wrapper form of the primitive argument type,
+            // then call the "valueOf" static method of the wrapper type in order to convert
+            // the argument into a wrapper object. So, for instance, this converts a primitive "int"
+            // into a "java.lang.Integer".
+            //
+            if (
+                ClassInspector.primitiveType( argumentType ) &&
+                parameterType.equals( JSQLType.getWrapperClassName( JSQLType.getPrimitiveID( argumentType ) ) )
+                )
+            {
+                // short must be converted to int
+                if ( "short".equals( argumentType ) )
+                {
+                    mb.cast( "int" );
+                }
+                
+                mb.callMethod
+                    (
+                     VMOpcode.INVOKESTATIC,
+                     parameterType,
+                     "valueOf",
+                     parameterType,
+                     1
+                     );
+            }
             // since we reached here through method resolution
             // casts are only required for primitive types.
             // In any other case the expression type must be assignable
             // to the parameter type.
-            if (ClassInspector.primitiveType(parameterType))
+            else if (ClassInspector.primitiveType(parameterType))
             {
                 mb.cast(parameterType);
             } else

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java?rev=1578479&r1=1578478&r2=1578479&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/GeneratedColumnsHelper.java Mon Mar 17 17:37:58 2014
@@ -272,58 +272,6 @@ public class GeneratedColumnsHelper exte
     }
         
     /**
-     * Assert that the statement returns the correct results.
-     */
-    protected void assertResults( Connection conn, String query, String[][] rows, boolean trimResults )
-        throws Exception
-    {
-        PreparedStatement   ps = chattyPrepare( conn, query );
-        ResultSet                   rs = ps.executeQuery();
-
-        assertResults( rs, rows, trimResults );
-
-        rs.close();
-        ps.close();
-    }
-        
-    /**
-     * Assert that the ResultSet returns the desired rows.
-     */
-    protected void assertResults( ResultSet rs, String[][] rows, boolean trimResults )
-        throws Exception
-    {
-        int     rowCount = rows.length;
-
-        for ( int i = 0; i < rowCount; i++ )
-        {
-            String[]    row = rows[ i ];
-            int             columnCount = row.length;
-
-            assertTrue( rs.next() );
-
-            for ( int j = 0; j < columnCount; j++ )
-            {
-                String  expectedValue =  row[ j ];
-                //println( "(row, column ) ( " + i + ", " +  j + " ) should be " + expectedValue );
-                String  actualValue = null;
-                int         column = j+1;
-
-                actualValue = rs.getString( column );
-                if ( rs.wasNull() ) { actualValue = null; }
-
-                if ( (actualValue != null) && trimResults ) { actualValue = actualValue.trim(); }
-                
-                assertEquals( (expectedValue == null), rs.wasNull() );
-                
-                if ( expectedValue == null )    { assertNull( actualValue ); }
-                else { assertEquals(expectedValue, actualValue); }
-            }
-        }
-
-        assertFalse( rs.next() );
-    }
-
-    /**
      * Test that a privilege can't be revoked if an object depends on it.
      */
     protected void verifyRevokePrivilege

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RoutineTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RoutineTest.java?rev=1578479&r1=1578478&r2=1578479&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RoutineTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RoutineTest.java Mon Mar 17 17:37:58 2014
@@ -23,6 +23,7 @@ package org.apache.derbyTesting.function
 
 import java.io.UnsupportedEncodingException;
 import java.sql.CallableStatement;
+import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -685,7 +686,87 @@ public class RoutineTest extends BaseJDB
         }
     }
 
+    /**
+     * DERBY-6511: Make sure that conversions between primitive and wrapper
+     * types work properly.
+     */
+    public void test_6511() throws Exception
+    {
+        Connection  conn = getConnection();
 
+        vet_6511( conn, "boolean", "booleanpToBoolean", "booleanToBooleanp", "true" );
+        vet_6511( conn, "int", "intToInteger", "integerToInt", "1" );
+        vet_6511( conn, "bigint", "longpToLong", "longToLongp", "1" );
+        vet_6511( conn, "smallint", "shortpToInteger", "integerToShortp", "1" );
+        vet_6511( conn, "double", "doublepToDouble", "doubleToDoublep", "1.0" );
+        vet_6511( conn, "real", "floatpToFloat", "floatToFloatp", "1.0" );
+    }
+    private void    vet_6511
+        (
+         Connection conn,
+         String sqlDatatype,
+         String primitiveToWrapperName,
+         String wrapperToPrimitiveName,
+         String dataValue
+         )
+        throws Exception
+    {
+        createFunction_6511( conn, sqlDatatype, primitiveToWrapperName );
+        createFunction_6511( conn, sqlDatatype, wrapperToPrimitiveName );
+
+        vetChaining_6511( conn, primitiveToWrapperName, primitiveToWrapperName, dataValue );
+        vetChaining_6511( conn, primitiveToWrapperName, wrapperToPrimitiveName, dataValue );
+        vetChaining_6511( conn, wrapperToPrimitiveName, primitiveToWrapperName, dataValue );
+        vetChaining_6511( conn, wrapperToPrimitiveName, wrapperToPrimitiveName, dataValue );
+
+        dropFunction_6511( conn, primitiveToWrapperName );
+        dropFunction_6511( conn, wrapperToPrimitiveName );
+    }
+    private void    createFunction_6511
+        (
+         Connection conn,
+         String sqlDatatype,
+         String functionName
+         )
+        throws Exception
+    {
+        goodStatement
+            (
+             conn,
+             "create function " + functionName + "( val " + sqlDatatype + " ) returns " + sqlDatatype + "\n" +
+             "language java parameter style java deterministic no sql\n" +
+             "external name '" + getClass().getName() + "." + functionName + "'"
+             );
+    }
+    private void    dropFunction_6511
+        (
+         Connection conn,
+         String functionName
+         )
+        throws Exception
+    {
+        goodStatement( conn, "drop function " + functionName );
+    }
+    private void    vetChaining_6511
+        (
+         Connection conn,
+         String innerFunctionName,
+         String outerFunctionName,
+         String dataValue
+         )
+        throws Exception
+    {
+        assertResults
+            (
+             conn,
+             "values " + outerFunctionName + "( " + innerFunctionName + "( " + dataValue + " ) )",
+             new String[][]
+             {
+                 { dataValue },
+             },
+             false
+             );
+    }
 
 
     /*
@@ -738,5 +819,67 @@ public class RoutineTest extends BaseJDB
 
     public static void p5749 (String s) {
     }
+
+    // functions for converting between primitive and wrapper types
+    public  static  Boolean booleanpToBoolean( boolean val )
+    {
+        return new Boolean( val );
+    }
+    public  static  boolean booleanToBooleanp( Boolean val ) throws Exception
+    {
+        if ( val == null )  { throw new Exception( "This method does not allow nulls!" ); }
+        else { return val.booleanValue(); }
+    }
+    
+    public  static  Integer intToInteger( int val )
+    {
+        return new Integer( val );
+    }
+    public  static  int     integerToInt( Integer val ) throws Exception
+    {
+        if ( val == null )  { throw new Exception( "This method does not allow nulls!" ); }
+        else { return val.intValue(); }
+    }
+    
+    public  static  Long    longpToLong( long val )
+    {
+        return new Long( val );
+    }
+    public  static  long     longToLongp( Long val ) throws Exception
+    {
+        if ( val == null )  { throw new Exception( "This method does not allow nulls!" ); }
+        else { return val.longValue(); }
+    }
+    
+    public  static  Integer    shortpToInteger( short val )
+    {
+        return new Integer( val );
+    }
+    public  static  short     integerToShortp( Integer val ) throws Exception
+    {
+        if ( val == null )  { throw new Exception( "This method does not allow nulls!" ); }
+        else { return val.shortValue(); }
+    }
+    
+    public  static  Float floatpToFloat( float val )
+    {
+        return new Float( val );
+    }
+    public  static  float     floatToFloatp( Float val ) throws Exception
+    {
+        if ( val == null )  { throw new Exception( "This method does not allow nulls!" ); }
+        else { return val.floatValue(); }
+    }
+    
+    public  static  Double doublepToDouble( double val )
+    {
+        return new Double( val );
+    }
+    public  static  double     doubleToDoublep( Double val ) throws Exception
+    {
+        if ( val == null )  { throw new Exception( "This method does not allow nulls!" ); }
+        else { return val.doubleValue(); }
+    }
+    
 }
 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java?rev=1578479&r1=1578478&r2=1578479&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/BaseJDBCTestCase.java Mon Mar 17 17:37:58 2014
@@ -1693,6 +1693,58 @@ public abstract class BaseJDBCTestCase
         assertEquals( expectedRowCount, actualRowCount );
     }
     
+    /**
+     * Assert that the statement returns the correct results.
+     */
+    protected void assertResults( Connection conn, String query, String[][] rows, boolean trimResults )
+        throws Exception
+    {
+        PreparedStatement   ps = chattyPrepare( conn, query );
+        ResultSet                   rs = ps.executeQuery();
+
+        assertResults( rs, rows, trimResults );
+
+        rs.close();
+        ps.close();
+    }
+        
+    /**
+     * Assert that the ResultSet returns the desired rows.
+     */
+    protected void assertResults( ResultSet rs, String[][] rows, boolean trimResults )
+        throws Exception
+    {
+        int     rowCount = rows.length;
+
+        for ( int i = 0; i < rowCount; i++ )
+        {
+            String[]    row = rows[ i ];
+            int             columnCount = row.length;
+
+            assertTrue( rs.next() );
+
+            for ( int j = 0; j < columnCount; j++ )
+            {
+                String  expectedValue =  row[ j ];
+                //println( "(row, column ) ( " + i + ", " +  j + " ) should be " + expectedValue );
+                String  actualValue = null;
+                int         column = j+1;
+
+                actualValue = rs.getString( column );
+                if ( rs.wasNull() ) { actualValue = null; }
+
+                if ( (actualValue != null) && trimResults ) { actualValue = actualValue.trim(); }
+                
+                assertEquals( (expectedValue == null), rs.wasNull() );
+                
+                if ( expectedValue == null )    { assertNull( actualValue ); }
+                else { assertEquals(expectedValue, actualValue); }
+            }
+        }
+
+        assertFalse( rs.next() );
+    }
+
 	protected	static	ResultSet	executeQuery( Statement stmt, String text )
 		throws SQLException
 	{