Search in sources :

Example 1 with SpecializeContext

use of com.facebook.presto.metadata.SqlScalarFunctionBuilder.SpecializeContext in project presto by prestodb.

the class PolymorphicScalarFunction method specialize.

@Override
public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) {
    List<TypeSignature> resolvedParameterTypeSignatures = applyBoundVariables(getSignature().getArgumentTypes(), boundVariables);
    List<Type> resolvedParameterTypes = resolveTypes(resolvedParameterTypeSignatures, typeManager);
    TypeSignature resolvedReturnTypeSignature = applyBoundVariables(getSignature().getReturnType(), boundVariables);
    Type resolvedReturnType = typeManager.getType(resolvedReturnTypeSignature);
    SpecializeContext context = new SpecializeContext(boundVariables, resolvedParameterTypes, resolvedReturnType, typeManager, functionRegistry);
    Optional<Method> matchingMethod = Optional.empty();
    Optional<MethodsGroup> matchingMethodsGroup = Optional.empty();
    for (MethodsGroup candidateMethodsGroup : methodsGroups) {
        for (Method candidateMethod : candidateMethodsGroup.getMethods()) {
            if (matchesParameterAndReturnTypes(candidateMethod, resolvedParameterTypes, resolvedReturnType) && predicateIsTrue(candidateMethodsGroup, context)) {
                if (matchingMethod.isPresent()) {
                    if (onlyFirstMatchedMethodHasPredicate(matchingMethodsGroup.get(), candidateMethodsGroup)) {
                        continue;
                    }
                    throw new IllegalStateException("two matching methods (" + matchingMethod.get().getName() + " and " + candidateMethod.getName() + ") for parameter types " + resolvedParameterTypeSignatures);
                }
                matchingMethod = Optional.of(candidateMethod);
                matchingMethodsGroup = Optional.of(candidateMethodsGroup);
            }
        }
    }
    checkState(matchingMethod.isPresent(), "no matching method for parameter types %s", resolvedParameterTypes);
    List<Object> extraParameters = computeExtraParameters(matchingMethodsGroup.get(), context);
    MethodHandle matchingMethodHandle = applyExtraParameters(matchingMethod.get(), extraParameters);
    return new ScalarFunctionImplementation(nullableResult, nullableArguments, nullFlags, matchingMethodHandle, deterministic);
}
Also used : ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) MethodsGroup(com.facebook.presto.metadata.SqlScalarFunctionBuilder.MethodsGroup) Method(java.lang.reflect.Method) SpecializeContext(com.facebook.presto.metadata.SqlScalarFunctionBuilder.SpecializeContext) TypeSignature(com.facebook.presto.spi.type.TypeSignature) Type(com.facebook.presto.spi.type.Type) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

MethodsGroup (com.facebook.presto.metadata.SqlScalarFunctionBuilder.MethodsGroup)1 SpecializeContext (com.facebook.presto.metadata.SqlScalarFunctionBuilder.SpecializeContext)1 ScalarFunctionImplementation (com.facebook.presto.operator.scalar.ScalarFunctionImplementation)1 Type (com.facebook.presto.spi.type.Type)1 TypeSignature (com.facebook.presto.spi.type.TypeSignature)1 MethodHandle (java.lang.invoke.MethodHandle)1 Method (java.lang.reflect.Method)1