public ValueHolder visitFunctionHolderExpression(FunctionHolderExpression holderExpr, Integer inIndex) {
if (! (holderExpr.getHolder() instanceof DrillSimpleFuncHolder)) {
throw new UnsupportedOperationException("Only Drill simple UDF can be used in interpreter mode!");
}
DrillSimpleFuncHolder holder = (DrillSimpleFuncHolder) holderExpr.getHolder();
ValueHolder [] args = new ValueHolder [holderExpr.args.size()];
for (int i = 0; i < holderExpr.args.size(); i++) {
args[i] = holderExpr.args.get(i).accept(this, inIndex);
// In case function use "NULL_IF_NULL" policy.
if (holder.getNullHandling() == FunctionTemplate.NullHandling.NULL_IF_NULL) {
// Case 1: parameter is non-nullable, argument is nullable.
if (holder.getParameters()[i].getType().getMode() == TypeProtos.DataMode.REQUIRED && TypeHelper.getValueHolderType(args[i]).getMode() == TypeProtos.DataMode.OPTIONAL) {
// Case 1.1 : argument is null, return null value holder directly.
if (TypeHelper.isNull(args[i])) {
return TypeHelper.createValueHolder(holderExpr.getMajorType());
} else {
// Case 1.2: argument is nullable but not null value, deNullify it.
args[i] = TypeHelper.deNullify(args[i]);
}
} else if (holder.getParameters()[i].getType().getMode() == TypeProtos.DataMode.OPTIONAL && TypeHelper.getValueHolderType(args[i]).getMode() == TypeProtos.DataMode.REQUIRED) {
// Case 2: parameter is nullable, argument is non-nullable. Nullify it.
args[i] = TypeHelper.nullify(args[i]);
}
}
}
try {
DrillSimpleFuncInterpreter interpreter = ((DrillFuncHolderExpr) holderExpr).getInterpreter();
Preconditions.checkArgument(interpreter != null, "interpreter could not be null when use interpreted model to evaluate function " + holder.getRegisteredNames()[0]);
interpreter.doSetup(args, incoming);
ValueHolder out = interpreter.doEval(args);
if (TypeHelper.getValueHolderType(out).getMode() == TypeProtos.DataMode.OPTIONAL &&