return -1;
}
}
for (int i = 0; i < holder.getParamCount(); i++) {
MajorType argType = call.args.get(i).getMajorType();
MajorType parmType = holder.getParmMajorType(i);
//@Param FieldReader will match any type
if (holder.isFieldReader(i)) {
// if (Types.isComplex(call.args.get(i).getMajorType()) ||Types.isRepeated(call.args.get(i).getMajorType()) )
continue;
// else
// return -1;
}
if (!TypeCastRules.isCastableWithNullHandling(argType, parmType, holder.getNullHandling())) {
return -1;
}
Integer parmVal = ResolverTypePrecedence.precedenceMap.get(parmType
.getMinorType());
Integer argVal = ResolverTypePrecedence.precedenceMap.get(argType
.getMinorType());
if (parmVal == null) {
throw new RuntimeException(String.format(
"Precedence for type %s is not defined", parmType.getMinorType()
.name()));
}
if (argVal == null) {
throw new RuntimeException(String.format(
"Precedence for type %s is not defined", argType.getMinorType()
.name()));
}
if (parmVal - argVal < 0) {
/* Precedence rules does not allow to implicitly cast, however check
* if the seconday rules allow us to cast
*/
Set<MinorType> rules;
if ((rules = (ResolverTypePrecedence.secondaryImplicitCastRules.get(parmType.getMinorType()))) != null &&
rules.contains(argType.getMinorType()) != false) {
secondaryCast = true;
} else {
return -1;
}
}
// Check null vs non-null, using same logic as that in Types.softEqual()
// Only when the function uses NULL_IF_NULL, nullable and non-nullable are inter-changable.
// Otherwise, the function implementation is not a match.
if (argType.getMode() != parmType.getMode()) {
// TODO - this does not seem to do what it is intended to
// if (!((holder.getNullHandling() == NullHandling.NULL_IF_NULL) &&
// (argType.getMode() == DataMode.OPTIONAL ||
// argType.getMode() == DataMode.REQUIRED ||
// parmType.getMode() == DataMode.OPTIONAL ||
// parmType.getMode() == DataMode.REQUIRED )))
// return -1;
// if the function is designed to take optional with custom null handling, and a required
// is being passed, increase the cost to account for a null check
// this allows for a non-nullable implementation to be preferred
if (holder.getNullHandling() == NullHandling.INTERNAL) {
// a function that expects required output, but nullable was provided
if (parmType.getMode() == DataMode.REQUIRED && argType.getMode() == DataMode.OPTIONAL) {
return -1;
}
else if (parmType.getMode() == DataMode.OPTIONAL && argType.getMode() == DataMode.REQUIRED) {
cost+= DATAMODE_CAST_COST;
}
}
}