Search in sources :

Example 1 with ScalarImplementationChoice

use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation.ScalarImplementationChoice in project trino by trinodb.

the class ParametricScalarImplementation method specialize.

public Optional<ScalarFunctionImplementation> specialize(FunctionBinding functionBinding, FunctionDependencies functionDependencies) {
    List<ScalarImplementationChoice> implementationChoices = new ArrayList<>();
    for (Map.Entry<String, Class<?>> entry : specializedTypeParameters.entrySet()) {
        if (!entry.getValue().isAssignableFrom(functionBinding.getTypeVariable(entry.getKey()).getJavaType())) {
            return Optional.empty();
        }
    }
    BoundSignature boundSignature = functionBinding.getBoundSignature();
    if (returnNativeContainerType != Object.class && returnNativeContainerType != boundSignature.getReturnType().getJavaType()) {
        return Optional.empty();
    }
    for (int i = 0; i < boundSignature.getArgumentTypes().size(); i++) {
        if (boundSignature.getArgumentTypes().get(i) instanceof FunctionType) {
            if (argumentNativeContainerTypes.get(i).isPresent()) {
                return Optional.empty();
            }
        } else {
            if (argumentNativeContainerTypes.get(i).isEmpty()) {
                return Optional.empty();
            }
            Class<?> argumentType = boundSignature.getArgumentTypes().get(i).getJavaType();
            Class<?> argumentNativeContainerType = argumentNativeContainerTypes.get(i).get();
            if (argumentNativeContainerType != Object.class && argumentNativeContainerType != argumentType) {
                return Optional.empty();
            }
        }
    }
    for (ParametricScalarImplementationChoice choice : choices) {
        MethodHandle boundMethodHandle = bindDependencies(choice.getMethodHandle(), choice.getDependencies(), functionBinding, functionDependencies);
        Optional<MethodHandle> boundConstructor = choice.getConstructor().map(constructor -> {
            MethodHandle result = bindDependencies(constructor, choice.getConstructorDependencies(), functionBinding, functionDependencies);
            checkCondition(result.type().parameterList().isEmpty(), FUNCTION_IMPLEMENTATION_ERROR, "All parameters of a constructor in a function definition class must be Dependencies. Signature: %s", boundSignature);
            return result;
        });
        implementationChoices.add(new ScalarImplementationChoice(choice.getReturnConvention(), choice.getArgumentConventions(), choice.getLambdaInterfaces(), boundMethodHandle.asType(javaMethodType(choice, boundSignature)), boundConstructor));
    }
    return Optional.of(new ChoicesScalarFunctionImplementation(boundSignature, implementationChoices));
}
Also used : FunctionType(io.trino.type.FunctionType) ArrayList(java.util.ArrayList) ScalarImplementationChoice(io.trino.operator.scalar.ChoicesScalarFunctionImplementation.ScalarImplementationChoice) BoundSignature(io.trino.metadata.BoundSignature) LongVariableConstraint(io.trino.metadata.LongVariableConstraint) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ChoicesScalarFunctionImplementation(io.trino.operator.scalar.ChoicesScalarFunctionImplementation) MethodHandle(java.lang.invoke.MethodHandle) Reflection.constructorMethodHandle(io.trino.util.Reflection.constructorMethodHandle)

Example 2 with ScalarImplementationChoice

use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation.ScalarImplementationChoice in project trino by trinodb.

the class PolymorphicScalarFunction method getScalarFunctionImplementationChoice.

private ScalarImplementationChoice getScalarFunctionImplementationChoice(FunctionBinding functionBinding, PolymorphicScalarFunctionChoice choice) {
    SpecializeContext context = new SpecializeContext(functionBinding);
    Optional<MethodAndNativeContainerTypes> matchingMethod = Optional.empty();
    Optional<MethodsGroup> matchingMethodsGroup = Optional.empty();
    for (MethodsGroup candidateMethodsGroup : choice.getMethodsGroups()) {
        for (MethodAndNativeContainerTypes candidateMethod : candidateMethodsGroup.getMethods()) {
            if (matchesParameterAndReturnTypes(candidateMethod, functionBinding.getBoundSignature(), choice.getArgumentConventions(), choice.getReturnConvention())) {
                if (matchingMethod.isPresent()) {
                    throw new IllegalStateException("two matching methods (" + matchingMethod.get().getMethod().getName() + " and " + candidateMethod.getMethod().getName() + ") for parameter types " + functionBinding.getBoundSignature().getArgumentTypes());
                }
                matchingMethod = Optional.of(candidateMethod);
                matchingMethodsGroup = Optional.of(candidateMethodsGroup);
            }
        }
    }
    checkState(matchingMethod.isPresent(), "no matching method for parameter types %s", functionBinding.getBoundSignature());
    List<Object> extraParameters = computeExtraParameters(matchingMethodsGroup.get(), context);
    MethodHandle methodHandle = applyExtraParameters(matchingMethod.get().getMethod(), extraParameters, choice.getArgumentConventions());
    return new ScalarImplementationChoice(choice.getReturnConvention(), choice.getArgumentConventions(), ImmutableList.of(), methodHandle, Optional.empty());
}
Also used : SpecializeContext(io.trino.metadata.PolymorphicScalarFunctionBuilder.SpecializeContext) MethodAndNativeContainerTypes(io.trino.metadata.PolymorphicScalarFunctionBuilder.MethodAndNativeContainerTypes) MethodsGroup(io.trino.metadata.PolymorphicScalarFunctionBuilder.MethodsGroup) ScalarImplementationChoice(io.trino.operator.scalar.ChoicesScalarFunctionImplementation.ScalarImplementationChoice) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

ScalarImplementationChoice (io.trino.operator.scalar.ChoicesScalarFunctionImplementation.ScalarImplementationChoice)2 MethodHandle (java.lang.invoke.MethodHandle)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 BoundSignature (io.trino.metadata.BoundSignature)1 LongVariableConstraint (io.trino.metadata.LongVariableConstraint)1 MethodAndNativeContainerTypes (io.trino.metadata.PolymorphicScalarFunctionBuilder.MethodAndNativeContainerTypes)1 MethodsGroup (io.trino.metadata.PolymorphicScalarFunctionBuilder.MethodsGroup)1 SpecializeContext (io.trino.metadata.PolymorphicScalarFunctionBuilder.SpecializeContext)1 ChoicesScalarFunctionImplementation (io.trino.operator.scalar.ChoicesScalarFunctionImplementation)1 FunctionType (io.trino.type.FunctionType)1 Reflection.constructorMethodHandle (io.trino.util.Reflection.constructorMethodHandle)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1