}
}
int count = signature.length;
ClassInspector classInspector = getClassFactory().getClassInspector();
String[] parmTypeNames = getObjectSignature();
String[] primParmTypeNames = null;
boolean[] isParam = getIsParam();
boolean hasDynamicResultSets = (routineInfo != null) && (count != 0) && (count != methodParms.length);
/*
** Find the matching method that is public.
*/
try
{
/* First try with built-in types and mappings */
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.
if (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
{
// 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 always map to the primitive type. We can not use the getPrimitiveSignature()
// as it (incorrectly but historically always has) maps a DECIMAL to a double.
TypeId returnTypeId = TypeId.getBuiltInTypeId(returnType.getJDBCTypeId());
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;
default:
requiredType = 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;
}
setJavaTypeName( typeName );
methodParameterTypes = classInspector.getParameterTypes(method);
for (int i = 0; i < methodParameterTypes.length; i++)
{
String methodParameter = methodParameterTypes[i];
if (routineInfo != null) {
if (i < routineInfo.getParameterCount()) {
int parameterMode = routineInfo.getParameterModes()[i];
switch (parameterMode) {
case JDBC30Translation.PARAMETER_MODE_IN:
break;
case JDBC30Translation.PARAMETER_MODE_IN_OUT:
// we need to see if the type of the array is
// primitive, not the array itself.
methodParameter = methodParameter.substring(0, methodParameter.length() - 2);
break;
case JDBC30Translation.PARAMETER_MODE_OUT:
// value is not obtained *from* parameter.
continue;
}
}
}
if (classInspector.primitiveType(methodParameter))
methodParms[i].castToPrimitive(true);
}
/* Set type info for any null parameters */
if ( someParametersAreNull() )