}
}
int count = signature.length;
ClassInspector classInspector = getClassFactory().getClassInspector();
String[] parmTypeNames;
String[] primParmTypeNames = null;
boolean[] isParam = getIsParam();
boolean hasDynamicResultSets = (routineInfo != null) && (count != 0) && (count != methodParms.length);
/*
** Find the matching method that is public.
*/
int signatureOffset = methodName.indexOf('(');
// support Java signatures by checking if the method name contains a '('
if (signatureOffset != -1) {
parmTypeNames = parseValidateSignature(methodName, signatureOffset, hasDynamicResultSets);
methodName = methodName.substring(0, signatureOffset);
// If the signature is specified then Derby resolves to exactly
// that method. Setting this flag to false disables the method
// resolution from automatically optionally repeating the last
// parameter as needed.
hasDynamicResultSets = false;
}
else
{
parmTypeNames = getObjectSignature();
}
try
{
method = classInspector.findPublicMethod(javaClassName,
methodName,
parmTypeNames,
null,
isParam,
staticMethod,
hasDynamicResultSets);
// DB2 LUW does not support Java object types for SMALLINT, INTEGER, BIGINT, REAL, DOUBLE
// and these are the only types that can map to a primitive or an object type according
// to SQL part 13. So we never have a second chance match.
// Also if the DDL specified a signature, then no alternate resolution
if (signatureOffset == -1 && routineInfo == null) {
/* If no match, then retry with combinations of object and
* primitive types.
*/
if (method == null)
{
primParmTypeNames = getPrimitiveSignature(false);
method = classInspector.findPublicMethod(javaClassName,
methodName,
parmTypeNames,
primParmTypeNames,
isParam,
staticMethod,
hasDynamicResultSets);
}
}
}
catch (ClassNotFoundException e)
{
/*
** If one of the classes couldn't be found, just act like the
** method couldn't be found. The error lists all the class names,
** which should give the user enough info to diagnose the problem.
*/
method = null;
}
/* Throw exception if no matching signature found */
if (method == null)
{
throwNoMethodFound(javaClassName, parmTypeNames, primParmTypeNames);
}
String typeName = classInspector.getType(method);
actualMethodReturnType = typeName;
if (routineInfo == null) {
/* void methods are only okay for CALL Statements */
if (typeName.equals("void"))
{
if (!forCallStatement)
throw StandardException.newException(SQLState.LANG_VOID_METHOD_CALL);
}
}
else
{
String promoteName = null;
TypeDescriptor returnType = routineInfo.getReturnType();
String requiredType;
if (returnType == null)
{
// must have a void method for a procedure call.
requiredType = "void";
}
else
{
TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
if (
returnType.isRowMultiSet() &&
( routineInfo.getParameterStyle() == RoutineAliasInfo.PS_DERBY_JDBC_RESULT_SET )
)
{
requiredType = "java.sql.ResultSet";
}
else
{
requiredType = returnTypeId.getCorrespondingJavaTypeName();
if (!requiredType.equals(typeName)) {
switch (returnType.getJDBCTypeId()) {
case java.sql.Types.SMALLINT:
case java.sql.Types.INTEGER:
case java.sql.Types.BIGINT:
case java.sql.Types.REAL:
case java.sql.Types.DOUBLE:
TypeCompiler tc = getTypeCompiler(returnTypeId);
requiredType = tc.getCorrespondingPrimitiveTypeName();
if (!routineInfo.calledOnNullInput() && routineInfo.getParameterCount() != 0)
{
promoteName = returnTypeId.getCorrespondingJavaTypeName();
}
break;
}
}
}
}
if (!requiredType.equals(typeName))
{
throwNoMethodFound(requiredType + " " + javaClassName, parmTypeNames, primParmTypeNames);
}
// for a returns null on null input with a primitive
// type we need to promote to an object so we can return null.
if (promoteName != null)
typeName = promoteName;
//propogate collation type from RoutineAliasInfo to
// MethodCallNode DERBY-2972
if (routineInfo.getReturnType() != null)
setCollationType(routineInfo.getReturnType().getCollationType());
}
setJavaTypeName( typeName );
methodParameterTypes = classInspector.getParameterTypes(method);
for (int i = 0; i < methodParameterTypes.length; i++)
{
String methodParameter = methodParameterTypes[i];