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 dj...@apache.org on 2006/02/28 04:55:31 UTC
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/
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;