ExpressionNode handleFunctionExpression(FunctionExpression expression) {
List<ExpressionNode> operands = expression.getOperands();
ExpressionNode result = resolve(expression, operands, registry.getScalarsResolver(), true);
TValidatedScalar overload = expression.getResolved();
TPreptimeContext context = expression.getPreptimeContext();
final List<TPreptimeValue> operandValues = new ArrayList<>(operands.size());
for (ExpressionNode operand : operands) {
TPreptimeValue preptimeValue = operand.getPreptimeValue();
operandValues.add(preptimeValue);
}
overload.finishPreptimePhase(context);
// Put the preptime value, possibly including nullness, into the expression. The constant folder
// will use it.
LazyList<TPreptimeValue> lazyInputs = new LazyListBase<TPreptimeValue>() {
@Override
public TPreptimeValue get(int i) {
return operandValues.get(i);
}
@Override
public int size() {
return operandValues.size();
}
};
TPreptimeValue constantTpv = overload.evaluateConstant(context, overload.filterInputs(lazyInputs));
if (constantTpv != null) {
TPreptimeValue oldTpv = expression.getPreptimeValue();
assert oldTpv.type().equals(constantTpv.type())
: oldTpv.type() + " != " + constantTpv.type();
expression.setPreptimeValue(constantTpv);
}
SparseArray<Object> values = context.getValues();
if ((values != null) && !values.isEmpty())
expression.setPreptimeValues(values);
return result;
}