Search in sources :

Example 6 with InvocationArgumentConvention

use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.

the class TestScalarFunctionAdapter method toCallArgumentTypes.

private static List<Class<?>> toCallArgumentTypes(InvocationConvention callingConvention, List<Type> argumentTypes) {
    List<Class<?>> expectedArguments = new ArrayList<>();
    for (int i = 0; i < callingConvention.getArgumentConventions().size(); i++) {
        Type argumentType = argumentTypes.get(i);
        InvocationArgumentConvention argumentConvention = callingConvention.getArgumentConvention(i);
        Class<?> javaType = argumentType.getJavaType();
        if (argumentType.equals(CHAR_TYPE) || argumentType.equals(TIMESTAMP_TYPE)) {
            javaType = Object.class;
        }
        switch(argumentConvention) {
            case NEVER_NULL:
                expectedArguments.add(javaType);
                break;
            case BOXED_NULLABLE:
                expectedArguments.add(Primitives.wrap(javaType));
                break;
            case NULL_FLAG:
                expectedArguments.add(javaType);
                expectedArguments.add(boolean.class);
                break;
            case BLOCK_POSITION:
                expectedArguments.add(Block.class);
                expectedArguments.add(int.class);
                break;
            default:
                throw new IllegalArgumentException("Unsupported argument convention: " + argumentConvention);
        }
    }
    return expectedArguments;
}
Also used : CharType.createCharType(io.trino.spi.type.CharType.createCharType) TimestampType.createTimestampType(io.trino.spi.type.TimestampType.createTimestampType) ArrayType(io.trino.spi.type.ArrayType) Type(io.trino.spi.type.Type) TimestampType(io.trino.spi.type.TimestampType) MethodType.methodType(java.lang.invoke.MethodType.methodType) MethodType(java.lang.invoke.MethodType) CharType(io.trino.spi.type.CharType) InvocationArgumentConvention(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention) ArrayList(java.util.ArrayList)

Example 7 with InvocationArgumentConvention

use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.

the class ParametricScalarImplementation method javaMethodType.

private static MethodType javaMethodType(ParametricScalarImplementationChoice choice, BoundSignature signature) {
    // This method accomplishes two purposes:
    // * Assert that the method signature is as expected.
    // This catches errors that would otherwise surface during bytecode generation and class loading.
    // * Adapt the method signature when necessary (for example, when the parameter type or return type is declared as Object).
    ImmutableList.Builder<Class<?>> methodHandleParameterTypes = ImmutableList.builder();
    if (choice.getConstructor().isPresent()) {
        methodHandleParameterTypes.add(Object.class);
    }
    if (choice.hasConnectorSession()) {
        methodHandleParameterTypes.add(ConnectorSession.class);
    }
    List<InvocationArgumentConvention> argumentConventions = choice.getArgumentConventions();
    int lambdaArgumentIndex = 0;
    for (int i = 0; i < argumentConventions.size(); i++) {
        InvocationArgumentConvention argumentConvention = argumentConventions.get(i);
        Type signatureType = signature.getArgumentTypes().get(i);
        switch(argumentConvention) {
            case NEVER_NULL:
                methodHandleParameterTypes.add(signatureType.getJavaType());
                break;
            case NULL_FLAG:
                methodHandleParameterTypes.add(signatureType.getJavaType());
                methodHandleParameterTypes.add(boolean.class);
                break;
            case BOXED_NULLABLE:
                methodHandleParameterTypes.add(Primitives.wrap(signatureType.getJavaType()));
                break;
            case BLOCK_POSITION:
                methodHandleParameterTypes.add(Block.class);
                methodHandleParameterTypes.add(int.class);
                break;
            case FUNCTION:
                methodHandleParameterTypes.add(choice.getLambdaInterfaces().get(lambdaArgumentIndex));
                lambdaArgumentIndex++;
                break;
            default:
                throw new UnsupportedOperationException("unknown argument convention: " + argumentConvention);
        }
    }
    Class<?> methodHandleReturnType = signature.getReturnType().getJavaType();
    if (choice.getReturnConvention().isNullable()) {
        methodHandleReturnType = Primitives.wrap(methodHandleReturnType);
    }
    return MethodType.methodType(methodHandleReturnType, methodHandleParameterTypes.build());
}
Also used : FunctionType(io.trino.type.FunctionType) Type(io.trino.spi.type.Type) SqlType(io.trino.spi.function.SqlType) MethodType(java.lang.invoke.MethodType) InvocationArgumentConvention(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) LongVariableConstraint(io.trino.metadata.LongVariableConstraint)

Example 8 with InvocationArgumentConvention

use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.

the class ParametricScalarImplementation method matches.

private static boolean matches(List<Boolean> argumentNullability, List<InvocationArgumentConvention> argumentConventions) {
    if (argumentNullability.size() != argumentConventions.size()) {
        return false;
    }
    for (int i = 0; i < argumentNullability.size(); i++) {
        boolean expectedNullable = argumentNullability.get(i);
        InvocationArgumentConvention argumentConvention = argumentConventions.get(i);
        if (argumentConvention == FUNCTION) {
            // functions are never null
            if (expectedNullable) {
                return false;
            }
        } else {
            // block and position can be nullable or not
            if (argumentConvention != BLOCK_POSITION) {
                if (expectedNullable != argumentConvention.isNullable()) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : InvocationArgumentConvention(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention) LongVariableConstraint(io.trino.metadata.LongVariableConstraint)

Example 9 with InvocationArgumentConvention

use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.

the class ScalarFunctionAdapter method canAdapt.

/**
 * Can the actual calling convention of a method be converted to the expected calling convention?
 */
public boolean canAdapt(InvocationConvention actualConvention, InvocationConvention expectedConvention) {
    requireNonNull(actualConvention, "actualConvention is null");
    requireNonNull(expectedConvention, "expectedConvention is null");
    if (actualConvention.getArgumentConventions().size() != expectedConvention.getArgumentConventions().size()) {
        throw new IllegalArgumentException("Actual and expected conventions have different number of arguments");
    }
    if (actualConvention.supportsSession() && !expectedConvention.supportsSession()) {
        return false;
    }
    if (actualConvention.supportsInstanceFactor() && !expectedConvention.supportsInstanceFactor()) {
        return false;
    }
    if (!canAdaptReturn(actualConvention.getReturnConvention(), expectedConvention.getReturnConvention())) {
        return false;
    }
    for (int argumentIndex = 0; argumentIndex < actualConvention.getArgumentConventions().size(); argumentIndex++) {
        InvocationArgumentConvention actualArgumentConvention = actualConvention.getArgumentConvention(argumentIndex);
        InvocationArgumentConvention expectedArgumentConvention = expectedConvention.getArgumentConvention(argumentIndex);
        if (!canAdaptParameter(actualArgumentConvention, expectedArgumentConvention, expectedConvention.getReturnConvention())) {
            return false;
        }
    }
    return true;
}
Also used : InvocationArgumentConvention(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention)

Example 10 with InvocationArgumentConvention

use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.

the class ScalarFunctionAdapter method adapt.

/**
 * Adapt the method handle from the actual calling convention of a method be converted to the expected calling convention?
 */
public MethodHandle adapt(MethodHandle methodHandle, List<Type> actualArgumentTypes, InvocationConvention actualConvention, InvocationConvention expectedConvention) {
    requireNonNull(methodHandle, "methodHandle is null");
    requireNonNull(actualConvention, "actualConvention is null");
    requireNonNull(expectedConvention, "expectedConvention is null");
    if (actualConvention.getArgumentConventions().size() != expectedConvention.getArgumentConventions().size()) {
        throw new IllegalArgumentException("Actual and expected conventions have different number of arguments");
    }
    if (actualConvention.supportsSession() && !expectedConvention.supportsSession()) {
        throw new IllegalArgumentException("Session method can not be adapted to no session");
    }
    if (!(expectedConvention.supportsInstanceFactor() || !actualConvention.supportsInstanceFactor())) {
        throw new IllegalArgumentException("Instance method can not be adapted to no instance");
    }
    // adapt return first, since return-null-on-null parameter convention must know if the return type is nullable
    methodHandle = adaptReturn(methodHandle, actualConvention.getReturnConvention(), expectedConvention.getReturnConvention());
    // adapt parameters one at a time
    int parameterIndex = 0;
    if (actualConvention.supportsInstanceFactor()) {
        parameterIndex++;
    }
    if (actualConvention.supportsSession()) {
        parameterIndex++;
    }
    for (int argumentIndex = 0; argumentIndex < actualConvention.getArgumentConventions().size(); argumentIndex++) {
        Type argumentType = actualArgumentTypes.get(argumentIndex);
        InvocationArgumentConvention actualArgumentConvention = actualConvention.getArgumentConvention(argumentIndex);
        InvocationArgumentConvention expectedArgumentConvention = expectedConvention.getArgumentConvention(argumentIndex);
        methodHandle = adaptParameter(methodHandle, parameterIndex, argumentType, actualArgumentConvention, expectedArgumentConvention, expectedConvention.getReturnConvention());
        parameterIndex++;
        if (expectedArgumentConvention == NULL_FLAG || expectedArgumentConvention == BLOCK_POSITION) {
            parameterIndex++;
        }
    }
    return methodHandle;
}
Also used : Type(io.trino.spi.type.Type) MethodType.methodType(java.lang.invoke.MethodType.methodType) MethodType(java.lang.invoke.MethodType) InvocationArgumentConvention(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention)

Aggregations

InvocationArgumentConvention (io.trino.spi.function.InvocationConvention.InvocationArgumentConvention)14 Type (io.trino.spi.type.Type)8 MethodType (java.lang.invoke.MethodType)7 MethodHandle (java.lang.invoke.MethodHandle)4 MethodType.methodType (java.lang.invoke.MethodType.methodType)4 ArrayList (java.util.ArrayList)4 ConnectorSession (io.trino.spi.connector.ConnectorSession)3 ArrayType (io.trino.spi.type.ArrayType)3 ImmutableList (com.google.common.collect.ImmutableList)2 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)2 LongVariableConstraint (io.trino.metadata.LongVariableConstraint)2 TrinoException (io.trino.spi.TrinoException)2 InvocationConvention (io.trino.spi.function.InvocationConvention)2 InvocationReturnConvention (io.trino.spi.function.InvocationConvention.InvocationReturnConvention)2 CharType (io.trino.spi.type.CharType)2 CharType.createCharType (io.trino.spi.type.CharType.createCharType)2 TimestampType (io.trino.spi.type.TimestampType)2 TimestampType.createTimestampType (io.trino.spi.type.TimestampType.createTimestampType)2 List (java.util.List)2 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)1