Return-Path: Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: (qmail 40257 invoked from network); 28 Feb 2006 03:55:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 28 Feb 2006 03:55:55 -0000 Received: (qmail 38639 invoked by uid 500); 28 Feb 2006 03:55:54 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 38598 invoked by uid 500); 28 Feb 2006 03:55:54 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 38586 invoked by uid 99); 28 Feb 2006 03:55:54 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Feb 2006 19:55:54 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Mon, 27 Feb 2006 19:55:53 -0800 Received: (qmail 40191 invoked by uid 65534); 28 Feb 2006 03:55:33 -0000 Message-ID: <20060228035533.40190.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r381553 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/tests/lang/ Date: Tue, 28 Feb 2006 03:55:31 -0000 To: derby-commits@db.apache.org From: djd@apache.org X-Mailer: svnmailer-1.0.7 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: djd Date: Mon Feb 27 19:55:29 2006 New Revision: 381553 URL: http://svn.apache.org/viewcvs?rev=381553&view=rev Log: DERBY-479 Fix linkage error when passing the value of a RETURNS NULL ON NULL INPUT function to another function. Fixed by only removing SQLToJava/JavaToSQL nodes for the function's return value when the function is a CALLED ON NULL INPUT function. Fix contributed by Mamta Satoor - msatoor@gmail.com Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/functions.out db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/functions.sql Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/MethodCallNode.java?rev=381553&r1=381552&r2=381553&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 Feb 27 19:55:29 2006 @@ -200,32 +200,18 @@ qt = (QueryTreeNode) parameterList.elementAt(index); - - /* - ** If the parameter is a SQL ValueNode, there are two - ** possibilities. Either it is a JavaValueNode with - ** a JavaToSQLValueNode on top of it, or it is a plain - ** SQL ValueNode. In the former case, just get rid of - ** the JavaToSQLValueNode. In the latter case, put a - ** SQLToJavaValueNode on top of it. In general, we - ** want to avoid converting the same value back and forth - ** between the SQL and Java domains. + ** Since we need the parameter to be in Java domain format, put a + ** SQLToJavaValueNode on top of the parameter node if it is a + ** SQLValueNode. But if the parameter is already in Java domain + ** format, then we don't need to do anything. */ if ( ! (qt instanceof JavaValueNode)) { - if (qt instanceof JavaToSQLValueNode) - { - qt = ((JavaToSQLValueNode) qt).getJavaValueNode(); - } - else - { - qt = (SQLToJavaValueNode) getNodeFactory(). - getNode( - C_NodeTypes.SQL_TO_JAVA_VALUE_NODE, - qt, - getContextManager()); - } + qt = (SQLToJavaValueNode) getNodeFactory().getNode( + C_NodeTypes.SQL_TO_JAVA_VALUE_NODE, + qt, + getContextManager()); } methodParms[index] = (JavaValueNode) qt; @@ -545,9 +531,7 @@ // In any other case the expression type must be assignable // to the parameter type. if (classInspector.primitiveType(parameterType)) { - mb.cast(parameterType); - } else { // for a prodcedure Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java?rev=381553&r1=381552&r2=381553&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/StaticMethodCallNode.java Mon Feb 27 19:55:29 2006 @@ -240,6 +240,9 @@ // return type, then we need to push a CAST node. if (routineInfo != null) { + if (methodParms != null) + optimizeDomainValueConversion(); + TypeDescriptor returnType = routineInfo.getReturnType(); if (returnType != null) { @@ -283,6 +286,47 @@ getCompilerContext().addRequiredRoutinePriv(ad); return this; + } + + /** + * If this SQL function has parameters which are SQLToJavaValueNode over + * JavaToSQLValueNode and the java value node underneath is a SQL function + * defined with CALLED ON NULL INPUT, then we can get rid of the wrapper + * nodes over the java value node for such parameters. This is because + * SQL functions defined with CALLED ON NULL INPUT need access to only + * java domain values. + * This can't be done for parameters which are wrappers over SQL function + * defined with RETURN NULL ON NULL INPUT because such functions need + * access to both sql domain value and java domain value. - Derby479 + */ + private void optimizeDomainValueConversion() throws StandardException { + int count = methodParms.length; + for (int parm = 0; parm < count; parm++) + { + if (methodParms[parm] instanceof SQLToJavaValueNode && + ((SQLToJavaValueNode)methodParms[parm]).getSQLValueNode() instanceof + JavaToSQLValueNode) + { + //If we are here, then it means that the parameter is + //SQLToJavaValueNode on top of JavaToSQLValueNode + JavaValueNode paramIsJavaValueNode = + ((JavaToSQLValueNode)((SQLToJavaValueNode)methodParms[parm]).getSQLValueNode()).getJavaValueNode(); + if (paramIsJavaValueNode instanceof StaticMethodCallNode) + { + //If we are here, then it means that the parameter has + //a MethodCallNode underneath it. + StaticMethodCallNode paramIsMethodCallNode = (StaticMethodCallNode)paramIsJavaValueNode; + //If the MethodCallNode parameter is defined as + //CALLED ON NULL INPUT, then we can remove the wrappers + //for the param and just set the parameter to the + //java value node. + if (paramIsMethodCallNode.routineInfo != null && + paramIsMethodCallNode.routineInfo.calledOnNullInput()) + methodParms[parm] = + ((JavaToSQLValueNode)((SQLToJavaValueNode)methodParms[parm]).getSQLValueNode()).getJavaValueNode(); + } + } + } } /** Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/functions.out URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/functions.out?rev=381553&r1=381552&r2=381553&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/functions.out (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/functions.out Mon Feb 27 19:55:29 2006 @@ -549,18 +549,39 @@ CALLED ON NULL INPUT LANGUAGE JAVA PARAMETER STYLE JAVA; 0 rows inserted/updated/deleted -ij> -- DERBY-479; --- VALUES CAST( RN_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); -VALUES CAST( CALL_COS(CALL_RADIANS(90.0)) AS DECIMAL(3,2)); +ij> -- Test cases for DERBY-479 +VALUES CAST( RN_COS(RN_RADIANS(null)) AS DECIMAL(3,2)); +1 +------ +NULL +ij> VALUES CAST( RN_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); +1 +------ +0.00 +ij> VALUES CAST( CALL_COS(CALL_RADIANS(90.0)) AS DECIMAL(3,2)); +1 +------ +0.00 +ij> VALUES CAST( CALL_COS(CALL_RADIANS(null)) AS DECIMAL(3,2)); +1 +------ +ERROR 39004: A NULL value cannot be passed to a method which takes a parameter of primitive type 'double'. +ij> VALUES CAST( CALL_COS(RN_RADIANS(null)) AS DECIMAL(3,2)); +1 +------ +ERROR 39004: A NULL value cannot be passed to a method which takes a parameter of primitive type 'double'. +ij> VALUES CAST( CALL_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); 1 ------ 0.00 -ij> -- DERBY-479; --- VALUES CAST( CALL_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); -VALUES CAST( RN_COS(CALL_RADIANS(90.0)) AS DECIMAL(3,2)); +ij> VALUES CAST( RN_COS(CALL_RADIANS(90.0)) AS DECIMAL(3,2)); 1 ------ 0.00 +ij> VALUES CAST( RN_COS(CALL_RADIANS(null)) AS DECIMAL(3,2)); +1 +------ +ERROR 39004: A NULL value cannot be passed to a method which takes a parameter of primitive type 'double'. ij> DROP FUNCTION RN_COS; 0 rows inserted/updated/deleted ij> DROP FUNCTION RN_RADIANS; Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/functions.sql URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/functions.sql?rev=381553&r1=381552&r2=381553&view=diff ============================================================================== --- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/functions.sql (original) +++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/functions.sql Mon Feb 27 19:55:29 2006 @@ -247,12 +247,15 @@ CALLED ON NULL INPUT LANGUAGE JAVA PARAMETER STYLE JAVA; --- DERBY-479; --- VALUES CAST( RN_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); +-- Test cases for DERBY-479 +VALUES CAST( RN_COS(RN_RADIANS(null)) AS DECIMAL(3,2)); +VALUES CAST( RN_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); VALUES CAST( CALL_COS(CALL_RADIANS(90.0)) AS DECIMAL(3,2)); --- DERBY-479; --- VALUES CAST( CALL_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); +VALUES CAST( CALL_COS(CALL_RADIANS(null)) AS DECIMAL(3,2)); +VALUES CAST( CALL_COS(RN_RADIANS(null)) AS DECIMAL(3,2)); +VALUES CAST( CALL_COS(RN_RADIANS(90.0)) AS DECIMAL(3,2)); VALUES CAST( RN_COS(CALL_RADIANS(90.0)) AS DECIMAL(3,2)); +VALUES CAST( RN_COS(CALL_RADIANS(null)) AS DECIMAL(3,2)); DROP FUNCTION RN_COS; DROP FUNCTION RN_RADIANS;