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 2008/05/19 15:12:01 UTC

svn commit: r657819 - in /db/derby/code/trunk/java: engine/org/apache/derby/catalog/ engine/org/apache/derby/catalog/types/ engine/org/apache/derby/iapi/services/loader/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/impl/sql/comp...

Author: rhillegas
Date: Mon May 19 06:12:01 2008
New Revision: 657819

URL: http://svn.apache.org/viewvc?rev=657819&view=rev
Log:
DERBY-3652: Allow mixing of primitive and wrapper types when matching SQL routine signatures to java methods.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignatures.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignaturesTest.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/IndexDescriptor.java
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/IndexDescriptorImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryComparisonOperatorNode.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/IndexDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/IndexDescriptor.java?rev=657819&r1=657818&r2=657819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/IndexDescriptor.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/IndexDescriptor.java Mon May 19 06:12:01 2008
@@ -57,14 +57,6 @@
      * Returns the postion of a column.
      * <p>
 	 * Returns the position of a column within the key (1-based).
-	 * 0 means that the column is not in the key.
-	 */
-	public Integer getKeyColumnPosition(Integer heapColumnPosition);
-
-	/**
-     * Returns the postion of a column.
-     * <p>
-	 * Returns the position of a column within the key (1-based).
 	 * 0 means that the column is not in the key.  Same as the above
 	 * method, but it uses int instead of Integer.
 	 */

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/IndexDescriptorImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/IndexDescriptorImpl.java?rev=657819&r1=657818&r2=657819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/IndexDescriptorImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/types/IndexDescriptorImpl.java Mon May 19 06:12:01 2008
@@ -131,12 +131,6 @@
 	}
 
 	/** @see IndexDescriptor#getKeyColumnPosition */
-	public Integer getKeyColumnPosition(Integer heapColumnPosition)
-	{
-		return new Integer(getKeyColumnPosition(heapColumnPosition.intValue()));
-	}
-
-	/** @see IndexDescriptor#getKeyColumnPosition */
 	public int getKeyColumnPosition(int heapColumnPosition)
 	{
 		/* Return 0 if column is not in the key */

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java?rev=657819&r1=657818&r2=657819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/services/loader/ClassInspector.java Mon May 19 06:12:01 2008
@@ -535,7 +535,14 @@
 	 *  types, second pass try to match any combination of "object" and
 	 *  "primitive" types.  Find the closest match among all the qualified
 	 *  candidates.  If there's a tie, it's ambiguous.
-	 *
+     *
+     *  The preceding paragraph is a bit misleading. As of release 10.4, the
+     *  second pass did not consider arbitrary combinations of primitive and
+     *  wrapper types. This is because the first pass removed from consideration
+     *  candidates which would be allowed under ANSI rules. As a fix for bug
+     *  DERBY-3652, we now allow primitive and wrapper type matches during
+     *  the first pass. The ANSI rules are documented in DERBY-3652.
+     *
 	 *  @param receiverClass 	the class who holds the methods
 	 *  @param methodName		the name of method
 	 *	@param paramClasses		object type classes of input parameters
@@ -657,10 +664,15 @@
 				  }
 				}
 
-
-				// can the required signature be converted to those of this method
+                //
+                // According to the ANSI rules, primitives and their
+                // corresponding wrapper types are equally good for resolving
+                // numeric arguments of user-coded functions and procedures. See
+                // DERBY-3652 for a description of the ANSI rules.
+                //
+				// can the required signature be converted to those of this method?
 				if (!signatureConvertableFromTo(paramClasses, primParamClasses,
-							currentMethodParameters, isParam, false)) {
+							currentMethodParameters, isParam, true)) {
 
 					if (SanityManager.DEBUG) {
 					  if (SanityManager.DEBUG_ON("MethodResolutionInfo")) {

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java?rev=657819&r1=657818&r2=657819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/IndexRowGenerator.java Mon May 19 06:12:01 2008
@@ -289,12 +289,6 @@
 	}
 
 	/** @see IndexDescriptor#getKeyColumnPosition */
-	public Integer getKeyColumnPosition(Integer heapColumnPosition)
-	{
-		return id.getKeyColumnPosition(heapColumnPosition);
-	}
-
-	/** @see IndexDescriptor#getKeyColumnPosition */
 	public int getKeyColumnPosition(int heapColumnPosition)
 	{
 		return id.getKeyColumnPosition(heapColumnPosition);

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryComparisonOperatorNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryComparisonOperatorNode.java?rev=657819&r1=657818&r2=657819&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryComparisonOperatorNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnaryComparisonOperatorNode.java Mon May 19 06:12:01 2008
@@ -409,7 +409,7 @@
 		if (bestCD.isIndex())
 		{
 			columnPosition = bestCD.getIndexDescriptor().
-			  getKeyColumnPosition(new Integer(columnPosition)).intValue();
+			  getKeyColumnPosition(columnPosition);
 
 			if (SanityManager.DEBUG)
 			{

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignatures.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignatures.java?rev=657819&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignatures.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignatures.java Mon May 19 06:12:01 2008
@@ -0,0 +1,253 @@
+/*
+
+Derby - Class org.apache.derbyTesting.functionTests.tests.lang.AnsiSignatures
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*/
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+
+/**
+ * <p>
+ * These are methods for testing ANSI routine resolution. The resolution rules
+ * are described in DERBY-3652.
+ * </p>
+ */
+public  class   AnsiSignatures
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////
+    //
+    // This block of methods is used to test whether Derby matches
+    // primitives and wrapper objects according to the ANSI rules.
+    // The ANSI rules are described in DERBY-3652.
+    //
+    ///////////////////////////////////////////////////////////////////
+
+    //
+    // SMALLINT
+    //
+    
+    // legal resolutions
+    public  static  short   smallint_short_short( short a ) { return a; }
+    public  static  short   smallint_short_Integer( Integer a ) { return a.shortValue(); }
+    public  static  Integer smallint_Integer_short( short a ) { return new Integer( a ); }
+    public  static  Integer smallint_Integer_Integer( Integer a ) { return a; }
+    
+    // outside the spec. these should not resolve.
+    public  static  short   smallint_bad_short_Short( Short a ) { return a.shortValue(); }
+    public  static  Short   smallint_bad_Short_short( short a ) { return new Short( a ); }
+    public  static  Short   smallint_bad_Short_Short( Short a ) { return a; }
+
+    
+    // illegal ambiguity
+    public  static  short   smallint_amb_short_short( short a ) { return a; }
+    public  static  short   smallint_amb_short_short( Integer a ) { return a.shortValue(); }
+    public  static  Integer smallint_amb_Integer_short( short a ) { return new Integer( a ); }
+    public  static  Integer smallint_amb_Integer_short( Integer a ) { return a; }
+    
+    // unresolvable
+    public  static  short   smallint_unres_short( byte a ) { return (short) a; }
+    public  static  short   smallint_unres_short( int a ) { return (short) a; }
+    public  static  short   smallint_unres_short( long a ) { return (short) a; }
+    public  static  short   smallint_unres_short( float a ) { return (short) a; }
+    public  static  short   smallint_unres_short( double a ) { return (short) a; }
+    public  static  short   smallint_unres_short( Byte a ) { return a.shortValue(); }
+    public  static  short   smallint_unres_short( Short a ) { return a.shortValue(); }
+    public  static  short   smallint_unres_short( Long a ) { return a.shortValue(); }
+    public  static  short   smallint_unres_short( Float a ) { return a.shortValue(); }
+    public  static  short   smallint_unres_short( Double a ) { return a.shortValue(); }
+
+    public  static  Short   smallint_unres_Short( byte a ) { return new Short( (short) a ); }
+    public  static  Short   smallint_unres_Short( short a ) { return new Short( (short) a ); }
+    public  static  Short   smallint_unres_Short( int a ) { return new Short( (short) a ); }
+    public  static  Short   smallint_unres_Short( long a ) { return new Short( (short) a ); }
+    public  static  Short   smallint_unres_Short( float a ) { return new Short( (short) a ); }
+    public  static  Short   smallint_unres_Short( double a ) { return new Short( (short) a ); }
+    public  static  Short   smallint_unres_Short( Byte a ) { return new Short( a.shortValue() ); }
+    public  static  Short   smallint_unres_Short( Short a ) { return new Short( a.shortValue() ); }
+    public  static  Short   smallint_unres_Short( Integer a ) { return new Short( a.shortValue() ); }
+    public  static  Short   smallint_unres_Short( Long a ) { return new Short( a.shortValue() ); }
+    public  static  Short   smallint_unres_Short( Float a ) { return new Short( a.shortValue() ); }
+    public  static  Short   smallint_unres_Short( Double a ) { return new Short( a.shortValue() ); }
+
+
+
+    //
+    // INTEGER
+    //
+    
+    // legal resolutions
+    public  static  int   integer_int_int( int a ) { return a; }
+    public  static  int   integer_int_Integer( Integer a ) { return a.intValue(); }
+    public  static  Integer integer_Integer_int( int a ) { return new Integer( a ); }
+    public  static  Integer integer_Integer_Integer( Integer a ) { return a; }
+    
+    // illegal ambiguity
+    public  static  int   integer_amb_int_int( int a ) { return a; }
+    public  static  int   integer_amb_int_int( Integer a ) { return a.intValue(); }
+    public  static  Integer integer_amb_Integer_int( int a ) { return new Integer( a ); }
+    public  static  Integer integer_amb_Integer_int( Integer a ) { return a; }
+    
+    // unresolvable
+    public  static  int   integer_unres_int( byte a ) { return (int) a; }
+    public  static  int   integer_unres_int( short a ) { return (int) a; }
+    public  static  int   integer_unres_int( long a ) { return (int) a; }
+    public  static  int   integer_unres_int( float a ) { return (int) a; }
+    public  static  int   integer_unres_int( double a ) { return (int) a; }
+    public  static  int   integer_unres_int( Byte a ) { return a.intValue(); }
+    public  static  int   integer_unres_int( Short a ) { return a.intValue(); }
+    public  static  int   integer_unres_int( Long a ) { return a.intValue(); }
+    public  static  int   integer_unres_int( Float a ) { return a.intValue(); }
+    public  static  int   integer_unres_int( Double a ) { return a.intValue(); }
+
+    public  static  Integer   integer_unres_Integer( byte a ) { return new Integer( (int) a ); }
+    public  static  Integer   integer_unres_Integer( short a ) { return new Integer( (int) a ); }
+    public  static  Integer   integer_unres_Integer( long a ) { return new Integer( (int) a ); }
+    public  static  Integer   integer_unres_Integer( float a ) { return new Integer( (int) a ); }
+    public  static  Integer   integer_unres_Integer( double a ) { return new Integer( (int) a ); }
+    public  static  Integer   integer_unres_Integer( Byte a ) { return new Integer( a.intValue() ); }
+    public  static  Integer   integer_unres_Integer( Short a ) { return new Integer( a.intValue() ); }
+    public  static  Integer   integer_unres_Integer( Long a ) { return new Integer( a.intValue() ); }
+    public  static  Integer   integer_unres_Integer( Float a ) { return new Integer( a.intValue() ); }
+    public  static  Integer   integer_unres_Integer( Double a ) { return new Integer( a.intValue() ); }
+
+    //
+    // BIGINT
+    //
+    
+    // legal resolutions
+    public  static  long   bigint_long_long( long a ) { return a; }
+    public  static  long   bigint_long_Long( Long a ) { return a.longValue(); }
+    public  static  Long bigint_Long_long( long a ) { return new Long( a ); }
+    public  static  Long bigint_Long_Long( Long a ) { return a; }
+    
+    // illegal ambiguity
+    public  static  long   bigint_amb_long_long( long a ) { return a; }
+    public  static  long   bigint_amb_long_long( Long a ) { return a.longValue(); }
+    public  static  Long bigint_amb_Long_long( long a ) { return new Long( a ); }
+    public  static  Long bigint_amb_Long_long( Long a ) { return a; }
+    
+    // unresolvable
+    public  static  long   bigint_unres_long( byte a ) { return (long) a; }
+    public  static  long   bigint_unres_long( short a ) { return (long) a; }
+    public  static  long   bigint_unres_long( int a ) { return (long) a; }
+    public  static  long   bigint_unres_long( float a ) { return (long) a; }
+    public  static  long   bigint_unres_long( double a ) { return (long) a; }
+    public  static  long   bigint_unres_long( Byte a ) { return a.longValue(); }
+    public  static  long   bigint_unres_long( Short a ) { return a.longValue(); }
+    public  static  long   bigint_unres_long( Integer a ) { return a.longValue(); }
+    public  static  long   bigint_unres_long( Float a ) { return a.longValue(); }
+    public  static  long   bigint_unres_long( Double a ) { return a.longValue(); }
+
+    public  static  Long   bigint_unres_Long( byte a ) { return new Long( (long) a ); }
+    public  static  Long   bigint_unres_Long( short a ) { return new Long( (long) a ); }
+    public  static  Long   bigint_unres_Long( int a ) { return new Long( (long) a ); }
+    public  static  Long   bigint_unres_Long( float a ) { return new Long( (long) a ); }
+    public  static  Long   bigint_unres_Long( double a ) { return new Long( (long) a ); }
+    public  static  Long   bigint_unres_Long( Byte a ) { return new Long( a.longValue() ); }
+    public  static  Long   bigint_unres_Long( Short a ) { return new Long( a.longValue() ); }
+    public  static  Long   bigint_unres_Long( Integer a ) { return new Long( a.longValue() ); }
+    public  static  Long   bigint_unres_Long( Float a ) { return new Long( a.longValue() ); }
+    public  static  Long   bigint_unres_Long( Double a ) { return new Long( a.longValue() ); }
+    
+    //
+    // REAL
+    //
+    
+    // legal resolutions
+    public  static  float   real_float_float( float a ) { return a; }
+    public  static  float   real_float_Float( Float a ) { return a.floatValue(); }
+    public  static  Float real_Float_float( float a ) { return new Float( a ); }
+    public  static  Float real_Float_Float( Float a ) { return a; }
+    
+    // illegal ambiguity
+    public  static  float   real_amb_float_float( float a ) { return a; }
+    public  static  float   real_amb_float_float( Float a ) { return a.floatValue(); }
+    public  static  Float real_amb_Float_float( float a ) { return new Float( a ); }
+    public  static  Float real_amb_Float_float( Float a ) { return a; }
+    
+    // unresolvable
+    public  static  float   real_unres_float( byte a ) { return (float) a; }
+    public  static  float   real_unres_float( short a ) { return (float) a; }
+    public  static  float   real_unres_float( int a ) { return (float) a; }
+    public  static  float   real_unres_float( long a ) { return (float) a; }
+    public  static  float   real_unres_float( double a ) { return (float) a; }
+    public  static  float   real_unres_float( Byte a ) { return a.floatValue(); }
+    public  static  float   real_unres_float( Short a ) { return a.floatValue(); }
+    public  static  float   real_unres_float( Integer a ) { return a.floatValue(); }
+    public  static  float   real_unres_float( Long a ) { return a.floatValue(); }
+    public  static  float   real_unres_float( Double a ) { return a.floatValue(); }
+
+    public  static  Float   real_unres_Float( byte a ) { return new Float( (float) a ); }
+    public  static  Float   real_unres_Float( short a ) { return new Float( (float) a ); }
+    public  static  Float   real_unres_Float( int a ) { return new Float( (float) a ); }
+    public  static  Float   real_unres_Float( long a ) { return new Float( (float) a ); }
+    public  static  Float   real_unres_Float( double a ) { return new Float( (float) a ); }
+    public  static  Float   real_unres_Float( Byte a ) { return new Float( a.floatValue() ); }
+    public  static  Float   real_unres_Float( Short a ) { return new Float( a.floatValue() ); }
+    public  static  Float   real_unres_Float( Integer a ) { return new Float( a.floatValue() ); }
+    public  static  Float   real_unres_Float( Long a ) { return new Float( a.floatValue() ); }
+    public  static  Float   real_unres_Float( Double a ) { return new Float( a.floatValue() ); }
+
+    //
+    // DOUBLE
+    //
+    
+    // legal resolutions
+    public  static  double   double_double_double( double a ) { return a; }
+    public  static  double   double_double_Double( Double a ) { return a.doubleValue(); }
+    public  static  Double double_Double_double( double a ) { return new Double( a ); }
+    public  static  Double double_Double_Double( Double a ) { return a; }
+    
+    // illegal ambiguity
+    public  static  double   double_amb_double_double( double a ) { return a; }
+    public  static  double   double_amb_double_double( Double a ) { return a.doubleValue(); }
+    public  static  Double double_amb_Double_double( double a ) { return new Double( a ); }
+    public  static  Double double_amb_Double_double( Double a ) { return a; }
+    
+    // unresolvable
+    public  static  double   double_unres_double( byte a ) { return (double) a; }
+    public  static  double   double_unres_double( short a ) { return (double) a; }
+    public  static  double   double_unres_double( int a ) { return (double) a; }
+    public  static  double   double_unres_double( long a ) { return (double) a; }
+    public  static  double   double_unres_double( float a ) { return (double) a; }
+    public  static  double   double_unres_double( Byte a ) { return a.doubleValue(); }
+    public  static  double   double_unres_double( Short a ) { return a.doubleValue(); }
+    public  static  double   double_unres_double( Integer a ) { return a.doubleValue(); }
+    public  static  double   double_unres_double( Long a ) { return a.doubleValue(); }
+    public  static  double   double_unres_double( Float a ) { return a.doubleValue(); }
+ 
+    public  static  Double   double_unres_Double( byte a ) { return new Double( (double) a ); }
+    public  static  Double   double_unres_Double( short a ) { return new Double( (double) a ); }
+    public  static  Double   double_unres_Double( int a ) { return new Double( (double) a ); }
+    public  static  Double   double_unres_Double( long a ) { return new Double( (double) a ); }
+    public  static  Double   double_unres_Double( float a ) { return new Double( (double) a ); }
+    public  static  Double   double_unres_Double( Byte a ) { return new Double( a.doubleValue() ); }
+    public  static  Double   double_unres_Double( Short a ) { return new Double( a.doubleValue() ); }
+    public  static  Double   double_unres_Double( Integer a ) { return new Double( a.doubleValue() ); }
+    public  static  Double   double_unres_Double( Long a ) { return new Double( a.doubleValue() ); }
+    public  static  Double   double_unres_Double( Float a ) { return new Double( a.doubleValue() ); }
+ 
+    
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignatures.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignaturesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignaturesTest.java?rev=657819&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignaturesTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignaturesTest.java Mon May 19 06:12:01 2008
@@ -0,0 +1,514 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.AnsiSignaturesTest
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.DriverManager;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+
+/**
+ * <p>
+ * Test that Derby resolves routines according to the ANSI method
+ * resolution rules. Those rules are summarized in DERBY-3652.
+ * </p>
+ */
+public class AnsiSignaturesTest extends BaseJDBCTestCase
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  static  final   String  MISSING_METHOD_SQLSTATE = "XJ001";
+    public  static  final   String  TRIED_ALL_COMBINATIONS = "42X50";
+    public  static  final   String  AMBIGUOUS = "42X73";
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Create a new instance.
+     */
+
+    public AnsiSignaturesTest(String name)
+    {
+        super(name);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // JUnit BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Construct top level suite in this JUnit test
+     */
+    public static Test suite()
+    {
+        TestSuite suite = (TestSuite) TestConfiguration.embeddedSuite(AnsiSignaturesTest.class);
+
+        return new CleanDatabaseTestSetup( suite );
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // SUCCESSFUL RESOLUTIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  void    test_smallint_short_short()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "smallint_short_short", "smallint", new String[] { "smallint" }, "3", "3" );
+    }
+    public  void    test_smallint_short_Integer()
+        throws Exception
+    {
+        // FIXME declareAndRunFunction
+        // FIXME ( "smallint_short_Integer", "smallint", new String[] { "smallint" }, "3", "3" );
+    }
+    public  void    test_smallint_Integer_short()
+        throws Exception
+    {
+        // FIXME declareAndRunFunction
+        // FIXME ( "smallint_Integer_short", "smallint", new String[] { "smallint" }, "3", "3" );
+    }
+    public  void    test_smallint_Integer_Integer()
+        throws Exception
+    {
+        // FIXME declareAndRunFunction
+        // FIXME ( "smallint_Integer_Integer", "smallint", new String[] { "smallint" }, "3", "3" );
+    }
+
+    public  void    test_integer_int_int()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "integer_int_int", "int", new String[] { "int" }, "3", "3" );
+    }
+    public  void    test_integer_int_Integer()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "integer_int_Integer", "int", new String[] { "int" }, "3", "3" );
+    }
+    public  void    test_integer_Integer_int()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "integer_Integer_int", "int", new String[] { "int" }, "3", "3" );
+    }
+    public  void    test_integer_Integer_Integer()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "integer_Integer_Integer", "int", new String[] { "int" }, "3", "3" );
+    }
+
+    public  void    test_bigint_long_long()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "bigint_long_long", "bigint", new String[] { "bigint" }, "3", "3" );
+    }
+    public  void    test_bigint_long_Long()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "bigint_long_Long", "bigint", new String[] { "bigint" }, "3", "3" );
+    }
+    public  void    test_bigint_Long_long()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "bigint_Long_long", "bigint", new String[] { "bigint" }, "3", "3" );
+    }
+    public  void    test_bigint_Long_Long()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "bigint_Long_Long", "bigint", new String[] { "bigint" }, "3", "3" );
+    }
+
+    public  void    test_real_float_float()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "real_float_float", "real", new String[] { "real" }, "3.0", "3.0" );
+    }
+    public  void    test_real_float_Float()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "real_float_Float", "real", new String[] { "real" }, "3.0", "3.0" );
+    }
+    public  void    test_real_Float_float()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "real_Float_float", "real", new String[] { "real" }, "3.0", "3.0" );
+    }
+    public  void    test_real_Float_Float()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "real_Float_Float", "real", new String[] { "real" }, "3.0", "3.0" );
+    }
+
+    public  void    test_double_double_double()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "double_double_double", "double", new String[] { "double" }, "3.0", "3.0" );
+    }
+    public  void    test_double_double_Double()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "double_double_Double", "double", new String[] { "double" }, "3.0", "3.0" );
+    }
+    public  void    test_double_Double_double()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "double_Double_double", "double", new String[] { "double" }, "3.0", "3.0" );
+    }
+    public  void    test_double_Double_Double()
+        throws Exception
+    {
+        declareAndRunFunction
+            ( "double_Double_Double", "double", new String[] { "double" }, "3.0", "3.0" );
+    }
+
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // SHOULD NOT RESOLVE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  void    test_smallint_bad_short_Short()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "smallint_bad_short_Short", "smallint", new String[] { "smallint" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+    public  void    test_smallint_bad_Short_short()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "smallint_bad_Short_short", "smallint", new String[] { "smallint" }, "3", "3", TRIED_ALL_COMBINATIONS );
+    }
+    public  void    test_smallint_bad_Short_Short()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "smallint_bad_Short_Short", "smallint", new String[] { "smallint" }, "3", "3", TRIED_ALL_COMBINATIONS );
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // AMBIGUOUS METHODS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  void    test_smallint_amb_short_short()
+        throws Exception
+    {
+        // FIXME declareAndFailFunction
+        // FIXME ( "smallint_amb_short_short", "smallint", new String[] { "smallint" }, "3", "3", AMBIGUOUS );
+    }
+    public  void    test_smallint_amb_Integer_short()
+        throws Exception
+    {
+        // FIXME declareAndFailFunction
+        // FIXME ( "smallint_amb_Integer_short", "smallint", new String[] { "smallint" }, "3", "3", AMBIGUOUS );
+    }
+
+    public  void    test_integer_amb_int_int()
+        throws Exception
+    {
+        declareAndFailFunction
+             ( "integer_amb_int_int", "int", new String[] { "int" }, "3", "3", AMBIGUOUS );
+    }
+    public  void    test_integer_amb_Integer_int()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "integer_amb_Integer_int", "int", new String[] { "int" }, "3", "3", AMBIGUOUS );
+    }
+
+    public  void    test_bigint_amb_long_long()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "bigint_amb_long_long", "bigint", new String[] { "bigint" }, "3", "3", AMBIGUOUS );
+    }
+    public  void    test_bigint_amb_Long_long()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "bigint_amb_Long_long", "bigint", new String[] { "bigint" }, "3", "3", AMBIGUOUS );
+    }
+
+    public  void    test_real_amb_float_float()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "real_amb_float_float", "real", new String[] { "real" }, "3.0", "3.0", AMBIGUOUS );
+    }
+    public  void    test_real_amb_Float_float()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "real_amb_Float_float", "real", new String[] { "real" }, "3.0", "3.0", AMBIGUOUS );
+    }
+
+    public  void    test_double_amb_double_double()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "double_amb_double_double", "double", new String[] { "double" }, "3.0", "3.0", AMBIGUOUS );
+    }
+    public  void    test_double_amb_Double_double()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "double_amb_Double_double", "double", new String[] { "double" }, "3.0", "3.0", AMBIGUOUS );
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // UNRESOLVABLE METHODS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  void    test_smallint_unres_short()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "smallint_unres_short", "smallint", new String[] { "smallint" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+    public  void    test_smallint_unres_Short()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "smallint_unres_Short", "smallint", new String[] { "smallint" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+
+    public  void    test_integer_unres_int()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "integer_unres_int", "int", new String[] { "int" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+    public  void    test_integer_unres_Integer()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "integer_unres_Integer", "int", new String[] { "int" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+    
+    public  void    test_bigint_unres_long()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "bigint_unres_long", "bigint", new String[] { "bigint" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+    public  void    test_bigint_unres_Long()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "bigint_unres_Long", "bigint", new String[] { "bigint" }, "3", "3", MISSING_METHOD_SQLSTATE );
+    }
+        
+    public  void    test_real_unres_float()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "real_unres_float", "real", new String[] { "real" }, "3.0", "3.0", MISSING_METHOD_SQLSTATE );
+    }
+    public  void    test_real_unres_Float()
+        throws Exception
+    {
+        //FIXME declareAndFailFunction
+        //FIXME ( "real_unres_Float", "real", new String[] { "real" }, "3.0", "3.0", MISSING_METHOD_SQLSTATE );
+    }
+        
+    public  void    test_double_unres_double()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "double_unres_double", "double", new String[] { "double" }, "3.0", "3.0", TRIED_ALL_COMBINATIONS );
+    }
+    public  void    test_double_unres_Double()
+        throws Exception
+    {
+        declareAndFailFunction
+            ( "double_unres_Double", "double", new String[] { "double" }, "3.0", "3.0", TRIED_ALL_COMBINATIONS );
+    }
+
+        
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Declare and run a function.
+     * </p>
+     */
+    private void declareAndRunFunction( String name, String returnType, String[] argTypes, String args, String result )
+        throws Exception
+    {
+        Connection  conn = getConnection();
+
+        declareFunction( conn, name, returnType, argTypes );
+        runFunction( conn, name, args, result, null );
+    }
+    
+    /**
+     * <p>
+     * Declare and run a function and expect the function to fail.
+     * </p>
+     */
+    private void declareAndFailFunction( String name, String returnType, String[] argTypes, String args, String result, String sqlstate )
+        throws Exception
+    {
+        Connection  conn = getConnection();
+
+        declareFunction( conn, name, returnType, argTypes );
+        runFunction( conn, name, args, result, sqlstate );
+    }
+    
+    /**
+     * <p>
+     * Run a function. If sqlstate is not null, then we expect the run to fail.
+     * </p>
+     */
+    private void runFunction( Connection conn, String name, String args, String result, String sqlstate )
+        throws Exception
+    {
+        StringBuffer    buffer = new StringBuffer();
+
+        buffer.append( "values ( " + doubleQuote( name ) + "( " + args + " ) )" );
+
+        String          query = buffer.toString();
+
+        println( query );
+
+        PreparedStatement   ps = null;
+        ResultSet               rs = null;
+
+        try {
+            ps = conn.prepareStatement( query );
+            rs = ps.executeQuery();
+
+            rs.next();
+
+            assertEquals( rs.getString( 1 ), result );
+
+            if ( sqlstate != null )
+            {
+                fail( "Should have failed with sqlstate: " + sqlstate );
+            }
+        }
+        catch (SQLException se)
+        {
+            assertSQLState( sqlstate, se );
+        }
+        finally
+        {
+            if ( rs != null ) { rs.close(); }
+            if ( ps != null ) { ps.close(); }
+        }
+    }
+    
+    /**
+     * <p>
+     * Declare a function with the given name, return type, and argument type.
+     * </p>
+     */
+    private void declareFunction( Connection conn, String name, String returnType, String[] argTypes )
+        throws Exception
+    {
+        StringBuffer    buffer = new StringBuffer();
+        int                 count = argTypes.length;
+
+        buffer.append( "create function " + doubleQuote( name ) );
+        buffer.append( "\n(" );
+        for ( int i = 0; i < count; i++ )
+        {
+            if ( i > 0 ) { buffer.append( "," ); }
+            buffer.append( "\n\ta_" + i + " " + argTypes[ i ] );
+        }
+        buffer.append( "\n)\n" );
+        buffer.append( "returns " + returnType );
+        buffer.append( "\nlanguage java\nparameter style java\nno sql\n" );
+        buffer.append( "external name '" + AnsiSignatures.class.getName() + "." + name + "'" );
+
+        String  ddl = buffer.toString();
+
+        println( ddl );
+
+        PreparedStatement ps = conn.prepareStatement( ddl );
+
+        ps.execute();
+        ps.close();
+
+        conn.commit();
+    }
+
+    private String  doubleQuote( String raw )
+    {
+        return '"' + raw + '"';
+    }
+    
+}
\ No newline at end of file

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/AnsiSignaturesTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=657819&r1=657818&r2=657819&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Mon May 19 06:12:01 2008
@@ -131,6 +131,7 @@
         suite.addTest(UniqueConstraintSetNullTest.suite());
         suite.addTest(ViewsTest.suite());
         suite.addTest(DeadlockModeTest.suite());
+        suite.addTest(AnsiSignaturesTest.suite());
         
         // Add the XML tests, which exist as a separate suite
         // so that users can "run all XML tests" easily.