Search in sources :

Example 1 with ArgumentProperty

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty in project presto by prestodb.

the class TestFunctionInvokerProvider method testFunctionInvokerProvider.

@Test
public void testFunctionInvokerProvider() {
    assertTrue(checkChoice(ImmutableList.of(new ArgumentProperty(VALUE_TYPE, Optional.of(USE_BOXED_TYPE), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(USE_BOXED_TYPE), Optional.empty())), true, false, Optional.of(new InvocationConvention(ImmutableList.of(BOXED_NULLABLE, BOXED_NULLABLE), InvocationReturnConvention.NULLABLE_RETURN, false))));
    assertTrue(checkChoice(ImmutableList.of(new ArgumentProperty(VALUE_TYPE, Optional.of(RETURN_NULL_ON_NULL), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty())), false, false, Optional.of(new InvocationConvention(ImmutableList.of(NEVER_NULL, BLOCK_POSITION, BLOCK_POSITION), InvocationReturnConvention.FAIL_ON_NULL, false))));
    assertTrue(checkChoice(ImmutableList.of(new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(USE_NULL_FLAG), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty())), false, false, Optional.of(new InvocationConvention(ImmutableList.of(BLOCK_POSITION, NULL_FLAG, BLOCK_POSITION), InvocationReturnConvention.FAIL_ON_NULL, false))));
    assertFalse(checkChoice(ImmutableList.of(new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(USE_BOXED_TYPE), Optional.empty())), false, false, Optional.of(new InvocationConvention(ImmutableList.of(BLOCK_POSITION, BOXED_NULLABLE), InvocationReturnConvention.NULLABLE_RETURN, false))));
    assertFalse(checkChoice(ImmutableList.of(new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(BLOCK_AND_POSITION), Optional.empty())), false, false, Optional.of(new InvocationConvention(ImmutableList.of(BLOCK_POSITION, NULL_FLAG), InvocationReturnConvention.NULLABLE_RETURN, false))));
    assertFalse(checkChoice(ImmutableList.of(new ArgumentProperty(VALUE_TYPE, Optional.of(USE_NULL_FLAG), Optional.empty()), new ArgumentProperty(VALUE_TYPE, Optional.of(USE_BOXED_TYPE), Optional.empty())), true, false, Optional.of(new InvocationConvention(ImmutableList.of(BLOCK_POSITION, BOXED_NULLABLE), InvocationReturnConvention.FAIL_ON_NULL, false))));
}
Also used : ArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty) InvocationConvention(com.facebook.presto.spi.function.InvocationConvention) Test(org.testng.annotations.Test)

Example 2 with ArgumentProperty

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty in project presto by prestodb.

the class ParametricScalarImplementation method javaMethodType.

private static MethodType javaMethodType(ParametricScalarImplementationChoice choice, Signature signature, TypeManager typeManager) {
    // 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.hasSqlFunctionProperties()) {
        methodHandleParameterTypes.add(SqlFunctionProperties.class);
    }
    List<ArgumentProperty> argumentProperties = choice.getArgumentProperties();
    for (int i = 0; i < argumentProperties.size(); i++) {
        ArgumentProperty argumentProperty = argumentProperties.get(i);
        switch(argumentProperty.getArgumentType()) {
            case VALUE_TYPE:
                Type signatureType = typeManager.getType(signature.getArgumentTypes().get(i));
                switch(argumentProperty.getNullConvention()) {
                    case RETURN_NULL_ON_NULL:
                        methodHandleParameterTypes.add(signatureType.getJavaType());
                        break;
                    case USE_NULL_FLAG:
                        methodHandleParameterTypes.add(signatureType.getJavaType());
                        methodHandleParameterTypes.add(boolean.class);
                        break;
                    case USE_BOXED_TYPE:
                        methodHandleParameterTypes.add(Primitives.wrap(signatureType.getJavaType()));
                        break;
                    case BLOCK_AND_POSITION:
                        methodHandleParameterTypes.add(Block.class);
                        methodHandleParameterTypes.add(int.class);
                        break;
                    default:
                        throw new UnsupportedOperationException("unknown NullConvention");
                }
                break;
            case FUNCTION_TYPE:
                methodHandleParameterTypes.add(argumentProperty.getLambdaInterface());
                break;
            default:
                throw new UnsupportedOperationException("unknown ArgumentType");
        }
    }
    Class<?> methodHandleReturnType = typeManager.getType(signature.getReturnType()).getJavaType();
    if (choice.isNullable()) {
        methodHandleReturnType = Primitives.wrap(methodHandleReturnType);
    }
    return MethodType.methodType(methodHandleReturnType, methodHandleParameterTypes.build());
}
Also used : ArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty) ArgumentProperty.valueTypeArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty.valueTypeArgumentProperty) ArgumentProperty.functionTypeArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty.functionTypeArgumentProperty) SqlType(com.facebook.presto.spi.function.SqlType) Type(com.facebook.presto.common.type.Type) FunctionType(com.facebook.presto.common.type.FunctionType) MethodType(java.lang.invoke.MethodType) ImmutableList(com.google.common.collect.ImmutableList) LongVariableConstraint(com.facebook.presto.spi.function.LongVariableConstraint)

Example 3 with ArgumentProperty

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty in project presto by prestodb.

the class InterpretedFunctionInvoker method invoke.

/**
 * Arguments must be the native container type for the corresponding SQL types.
 * <p>
 * Returns a value in the native container type corresponding to the declared SQL return type
 */
private Object invoke(JavaScalarFunctionImplementation function, SqlFunctionProperties properties, List<Object> arguments) {
    ScalarFunctionImplementationChoice choice = getAllScalarFunctionImplementationChoices(function).get(0);
    MethodHandle method = choice.getMethodHandle();
    // handle function on instance method, to allow use of fields
    method = bindInstanceFactory(method, function);
    if (method.type().parameterCount() > 0 && method.type().parameterType(0) == SqlFunctionProperties.class) {
        method = method.bindTo(properties);
    }
    List<Object> actualArguments = new ArrayList<>();
    for (int i = 0; i < arguments.size(); i++) {
        Object argument = arguments.get(i);
        ArgumentProperty argumentProperty = choice.getArgumentProperty(i);
        if (argumentProperty.getArgumentType() == VALUE_TYPE) {
            if (choice.getArgumentProperty(i).getNullConvention() == RETURN_NULL_ON_NULL) {
                if (argument == null) {
                    return null;
                }
                actualArguments.add(argument);
            } else if (choice.getArgumentProperty(i).getNullConvention() == USE_NULL_FLAG) {
                boolean isNull = argument == null;
                if (isNull) {
                    argument = Defaults.defaultValue(method.type().parameterType(actualArguments.size()));
                }
                actualArguments.add(argument);
                actualArguments.add(isNull);
            } else {
                actualArguments.add(argument);
            }
        } else {
            argument = asInterfaceInstance(argumentProperty.getLambdaInterface(), (MethodHandle) argument);
            actualArguments.add(argument);
        }
    }
    try {
        return method.invokeWithArguments(actualArguments);
    } catch (Throwable throwable) {
        throw propagate(throwable);
    }
}
Also used : ArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty) ScalarFunctionImplementationChoice(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice) SqlFunctionProperties(com.facebook.presto.common.function.SqlFunctionProperties) ArrayList(java.util.ArrayList) MethodHandle(java.lang.invoke.MethodHandle)

Example 4 with ArgumentProperty

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty in project presto by prestodb.

the class ZipFunction method specialize.

@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
    List<Type> types = this.typeParameters.stream().map(boundVariables::getTypeVariable).collect(toImmutableList());
    List<ArgumentProperty> argumentProperties = nCopies(types.size(), valueTypeArgumentProperty(RETURN_NULL_ON_NULL));
    List<Class<?>> javaArgumentTypes = nCopies(types.size(), Block.class);
    MethodHandle methodHandle = METHOD_HANDLE.bindTo(types).asVarargsCollector(Block[].class).asType(methodType(Block.class, javaArgumentTypes));
    return new BuiltInScalarFunctionImplementation(false, argumentProperties, methodHandle);
}
Also used : ArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty) ArgumentProperty.valueTypeArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty.valueTypeArgumentProperty) Type(com.facebook.presto.common.type.Type) MethodType.methodType(java.lang.invoke.MethodType.methodType) RowType(com.facebook.presto.common.type.RowType) Block(com.facebook.presto.common.block.Block) MethodHandle(java.lang.invoke.MethodHandle)

Example 5 with ArgumentProperty

use of com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty in project presto by prestodb.

the class TryCastFunction method specialize.

@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
    Type fromType = boundVariables.getTypeVariable("F");
    Type toType = boundVariables.getTypeVariable("T");
    Class<?> returnType = Primitives.wrap(toType.getJavaType());
    List<ArgumentProperty> argumentProperties;
    MethodHandle tryCastHandle;
    // the resulting method needs to return a boxed type
    FunctionHandle functionHandle = functionAndTypeManager.lookupCast(CAST, fromType.getTypeSignature(), toType.getTypeSignature());
    ScalarFunctionImplementationChoice implementation = getAllScalarFunctionImplementationChoices(functionAndTypeManager.getJavaScalarFunctionImplementation(functionHandle)).get(0);
    argumentProperties = ImmutableList.of(implementation.getArgumentProperty(0));
    MethodHandle coercion = implementation.getMethodHandle();
    coercion = coercion.asType(methodType(returnType, coercion.type()));
    MethodHandle exceptionHandler = dropArguments(constant(returnType, null), 0, RuntimeException.class);
    tryCastHandle = catchException(coercion, RuntimeException.class, exceptionHandler);
    return new BuiltInScalarFunctionImplementation(true, argumentProperties, tryCastHandle);
}
Also used : ArgumentProperty(com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty) MethodType.methodType(java.lang.invoke.MethodType.methodType) Type(com.facebook.presto.common.type.Type) FunctionHandle(com.facebook.presto.spi.function.FunctionHandle) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

ArgumentProperty (com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty)8 Type (com.facebook.presto.common.type.Type)5 MethodHandle (java.lang.invoke.MethodHandle)4 SqlFunctionProperties (com.facebook.presto.common.function.SqlFunctionProperties)3 ScalarFunctionImplementationChoice (com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice)3 ArgumentProperty.valueTypeArgumentProperty (com.facebook.presto.operator.scalar.ScalarFunctionImplementationChoice.ArgumentProperty.valueTypeArgumentProperty)3 MethodType (java.lang.invoke.MethodType)3 ArrayList (java.util.ArrayList)3 Block (com.facebook.presto.common.block.Block)2 FunctionAndTypeManager (com.facebook.presto.metadata.FunctionAndTypeManager)2 FunctionHandle (com.facebook.presto.spi.function.FunctionHandle)2 String.format (java.lang.String.format)2 MethodType.methodType (java.lang.invoke.MethodType.methodType)2 List (java.util.List)2 Optional (java.util.Optional)2 UsedByGeneratedCode (com.facebook.presto.annotation.UsedByGeneratedCode)1 Binding (com.facebook.presto.bytecode.Binding)1 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)1 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)1 Variable (com.facebook.presto.bytecode.Variable)1