Search in sources :

Example 6 with InvocationConvention

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

the class RowType method getComparisonOperatorInvokers.

private static List<OperatorMethodHandle> getComparisonOperatorInvokers(BiFunction<Type, InvocationConvention, MethodHandle> comparisonOperatorFactory, List<Field> fields) {
    boolean orderable = fields.stream().allMatch(field -> field.getType().isOrderable());
    if (!orderable) {
        return emptyList();
    }
    // for large rows, use a generic loop with a megamorphic call site
    if (fields.size() > MEGAMORPHIC_FIELD_COUNT) {
        List<MethodHandle> comparisonOperators = fields.stream().map(field -> comparisonOperatorFactory.apply(field.getType(), simpleConvention(FAIL_ON_NULL, BLOCK_POSITION, BLOCK_POSITION))).collect(toUnmodifiableList());
        return singletonList(new OperatorMethodHandle(COMPARISON_CONVENTION, COMPARISON.bindTo(comparisonOperators)));
    }
    // (Block, Block):Boolean
    MethodHandle comparison = dropArguments(constant(long.class, 0), 0, Block.class, Block.class);
    for (int fieldId = 0; fieldId < fields.size(); fieldId++) {
        Field field = fields.get(fieldId);
        // (Block, Block, int, MethodHandle, Block, Block):Boolean
        comparison = collectArguments(CHAIN_COMPARISON, 0, comparison);
        // field comparison
        MethodHandle fieldComparisonOperator = comparisonOperatorFactory.apply(field.getType(), simpleConvention(FAIL_ON_NULL, BLOCK_POSITION, BLOCK_POSITION));
        // (Block, Block, Block, Block):Boolean
        comparison = insertArguments(comparison, 2, fieldId, fieldComparisonOperator);
        // (Block, Block):Boolean
        comparison = permuteArguments(comparison, methodType(long.class, Block.class, Block.class), 0, 1, 0, 1);
    }
    return singletonList(new OperatorMethodHandle(COMPARISON_CONVENTION, comparison));
}
Also used : MethodHandle(java.lang.invoke.MethodHandle) Arrays(java.util.Arrays) BLOCK_POSITION(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION) MethodHandles.dropArguments(java.lang.invoke.MethodHandles.dropArguments) ROW(io.trino.spi.type.StandardTypes.ROW) FAIL_ON_NULL(io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL) BiFunction(java.util.function.BiFunction) MethodHandles.insertArguments(java.lang.invoke.MethodHandles.insertArguments) InvocationConvention.simpleConvention(io.trino.spi.function.InvocationConvention.simpleConvention) Function(java.util.function.Function) MethodHandles.lookup(java.lang.invoke.MethodHandles.lookup) OperatorMethodHandle(io.trino.spi.function.OperatorMethodHandle) ArrayList(java.util.ArrayList) Collections.singletonList(java.util.Collections.singletonList) Collectors.toUnmodifiableList(java.util.stream.Collectors.toUnmodifiableList) Lookup(java.lang.invoke.MethodHandles.Lookup) Block(io.trino.spi.block.Block) Objects.requireNonNull(java.util.Objects.requireNonNull) NULL_HASH_CODE(io.trino.spi.type.TypeUtils.NULL_HASH_CODE) NULLABLE_RETURN(io.trino.spi.function.InvocationConvention.InvocationReturnConvention.NULLABLE_RETURN) MethodType.methodType(java.lang.invoke.MethodType.methodType) FALSE(java.lang.Boolean.FALSE) MethodHandles.constant(java.lang.invoke.MethodHandles.constant) BlockBuilderStatus(io.trino.spi.block.BlockBuilderStatus) Collections.emptyList(java.util.Collections.emptyList) BOXED_NULLABLE(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BOXED_NULLABLE) MethodHandles.permuteArguments(java.lang.invoke.MethodHandles.permuteArguments) TrinoException(io.trino.spi.TrinoException) ConnectorSession(io.trino.spi.connector.ConnectorSession) List(java.util.List) InvocationConvention(io.trino.spi.function.InvocationConvention) MethodHandles.collectArguments(java.lang.invoke.MethodHandles.collectArguments) StandardErrorCode(io.trino.spi.StandardErrorCode) Optional(java.util.Optional) BlockBuilder(io.trino.spi.block.BlockBuilder) RowBlockBuilder(io.trino.spi.block.RowBlockBuilder) Collections(java.util.Collections) TRUE(java.lang.Boolean.TRUE) NEVER_NULL(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.NEVER_NULL) OperatorMethodHandle(io.trino.spi.function.OperatorMethodHandle) MethodHandle(java.lang.invoke.MethodHandle) OperatorMethodHandle(io.trino.spi.function.OperatorMethodHandle)

Example 7 with InvocationConvention

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

the class RowToRowCast method getNullSafeCast.

private static MethodHandle getNullSafeCast(FunctionDependencies functionDependencies, Type fromElementType, Type toElementType) {
    MethodHandle castMethod = functionDependencies.getCastInvoker(fromElementType, toElementType, new InvocationConvention(ImmutableList.of(BLOCK_POSITION), NULLABLE_RETURN, true, false)).getMethodHandle();
    // normalize so cast always has a session
    if (!castMethod.type().parameterType(0).equals(ConnectorSession.class)) {
        castMethod = dropArguments(castMethod, 0, ConnectorSession.class);
    }
    // change return to Object
    castMethod = castMethod.asType(methodType(Object.class, ConnectorSession.class, Block.class, int.class));
    // if block is null, return null. otherwise execute the cast
    return guardWithTest(dropArguments(BLOCK_IS_NULL, 0, ConnectorSession.class), dropArguments(zero(Object.class), 0, castMethod.type().parameterList()), castMethod);
}
Also used : InvocationConvention(io.trino.spi.function.InvocationConvention) ConnectorSession(io.trino.spi.connector.ConnectorSession) MethodHandle(java.lang.invoke.MethodHandle)

Example 8 with InvocationConvention

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

the class AbstractMinMaxAggregationFunction method specialize.

@Override
public AggregationMetadata specialize(BoundSignature boundSignature, FunctionDependencies functionDependencies) {
    Type type = boundSignature.getArgumentTypes().get(0);
    InvocationConvention invocationConvention;
    if (type.getJavaType().isPrimitive()) {
        invocationConvention = simpleConvention(FAIL_ON_NULL, NEVER_NULL, NEVER_NULL);
    } else {
        invocationConvention = simpleConvention(FAIL_ON_NULL, BLOCK_POSITION, BLOCK_POSITION);
    }
    MethodHandle compareMethodHandle = getMinMaxCompare(functionDependencies, type, invocationConvention, min);
    MethodHandle inputFunction;
    MethodHandle combineFunction;
    MethodHandle outputFunction;
    AccumulatorStateDescriptor<?> accumulatorStateDescriptor;
    if (type.getJavaType() == long.class) {
        accumulatorStateDescriptor = new AccumulatorStateDescriptor<>(GenericLongState.class, new GenericLongStateSerializer(type), StateCompiler.generateStateFactory(GenericLongState.class));
        inputFunction = LONG_INPUT_FUNCTION.bindTo(compareMethodHandle);
        combineFunction = LONG_COMBINE_FUNCTION.bindTo(compareMethodHandle);
        outputFunction = LONG_OUTPUT_FUNCTION.bindTo(type);
    } else if (type.getJavaType() == double.class) {
        accumulatorStateDescriptor = new AccumulatorStateDescriptor<>(GenericDoubleState.class, new GenericDoubleStateSerializer(type), StateCompiler.generateStateFactory(GenericDoubleState.class));
        inputFunction = DOUBLE_INPUT_FUNCTION.bindTo(compareMethodHandle);
        combineFunction = DOUBLE_COMBINE_FUNCTION.bindTo(compareMethodHandle);
        outputFunction = DOUBLE_OUTPUT_FUNCTION.bindTo(type);
    } else if (type.getJavaType() == boolean.class) {
        accumulatorStateDescriptor = new AccumulatorStateDescriptor<>(GenericBooleanState.class, new GenericBooleanStateSerializer(type), StateCompiler.generateStateFactory(GenericBooleanState.class));
        inputFunction = BOOLEAN_INPUT_FUNCTION.bindTo(compareMethodHandle);
        combineFunction = BOOLEAN_COMBINE_FUNCTION.bindTo(compareMethodHandle);
        outputFunction = BOOLEAN_OUTPUT_FUNCTION.bindTo(type);
    } else {
        // native container type is Object
        accumulatorStateDescriptor = new AccumulatorStateDescriptor<>(BlockPositionState.class, new BlockPositionStateSerializer(type), StateCompiler.generateStateFactory(BlockPositionState.class));
        inputFunction = BLOCK_POSITION_INPUT_FUNCTION.bindTo(compareMethodHandle);
        combineFunction = BLOCK_POSITION_COMBINE_FUNCTION.bindTo(compareMethodHandle);
        outputFunction = BLOCK_POSITION_OUTPUT_FUNCTION.bindTo(type);
    }
    inputFunction = normalizeInputMethod(inputFunction, boundSignature, createInputParameterKinds(type));
    return new AggregationMetadata(inputFunction, Optional.empty(), Optional.of(combineFunction), outputFunction, ImmutableList.of(accumulatorStateDescriptor));
}
Also used : GenericLongState(io.trino.operator.aggregation.state.GenericLongState) AccumulatorStateDescriptor(io.trino.operator.aggregation.AggregationMetadata.AccumulatorStateDescriptor) GenericDoubleState(io.trino.operator.aggregation.state.GenericDoubleState) BlockPositionStateSerializer(io.trino.operator.aggregation.state.BlockPositionStateSerializer) GenericBooleanState(io.trino.operator.aggregation.state.GenericBooleanState) BlockPositionState(io.trino.operator.aggregation.state.BlockPositionState) Type(io.trino.spi.type.Type) GenericLongStateSerializer(io.trino.operator.aggregation.state.GenericLongStateSerializer) GenericDoubleStateSerializer(io.trino.operator.aggregation.state.GenericDoubleStateSerializer) InvocationConvention(io.trino.spi.function.InvocationConvention) GenericBooleanStateSerializer(io.trino.operator.aggregation.state.GenericBooleanStateSerializer) MethodHandle(java.lang.invoke.MethodHandle)

Example 9 with InvocationConvention

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

the class ArrayJoin method specializeArrayJoin.

private static ChoicesScalarFunctionImplementation specializeArrayJoin(BoundSignature boundSignature, FunctionDependencies functionDependencies, MethodHandle methodHandle) {
    List<InvocationArgumentConvention> argumentConventions = Collections.nCopies(boundSignature.getArity(), NEVER_NULL);
    Type type = ((ArrayType) boundSignature.getArgumentTypes().get(0)).getElementType();
    if (type instanceof UnknownType) {
        return new ChoicesScalarFunctionImplementation(boundSignature, FAIL_ON_NULL, argumentConventions, methodHandle.bindTo(null), Optional.of(STATE_FACTORY));
    } else {
        try {
            InvocationConvention convention = new InvocationConvention(ImmutableList.of(BLOCK_POSITION), NULLABLE_RETURN, true, false);
            MethodHandle cast = functionDependencies.getCastInvoker(type, VARCHAR, convention).getMethodHandle();
            // if the cast doesn't take a ConnectorSession, create an adapter that drops the provided session
            if (cast.type().parameterArray()[0] != ConnectorSession.class) {
                cast = MethodHandles.dropArguments(cast, 0, ConnectorSession.class);
            }
            MethodHandle target = MethodHandles.insertArguments(methodHandle, 0, cast);
            return new ChoicesScalarFunctionImplementation(boundSignature, FAIL_ON_NULL, argumentConventions, target, Optional.of(STATE_FACTORY));
        } catch (TrinoException e) {
            throw new TrinoException(INVALID_FUNCTION_ARGUMENT, format("Input type %s not supported", type), e);
        }
    }
}
Also used : ArrayType(io.trino.spi.type.ArrayType) UnknownType(io.trino.type.UnknownType) Type(io.trino.spi.type.Type) TypeSignature.arrayType(io.trino.spi.type.TypeSignature.arrayType) ArrayType(io.trino.spi.type.ArrayType) UnknownType(io.trino.type.UnknownType) InvocationArgumentConvention(io.trino.spi.function.InvocationConvention.InvocationArgumentConvention) InvocationConvention(io.trino.spi.function.InvocationConvention) TrinoException(io.trino.spi.TrinoException) ConnectorSession(io.trino.spi.connector.ConnectorSession) MethodHandle(java.lang.invoke.MethodHandle)

Aggregations

InvocationConvention (io.trino.spi.function.InvocationConvention)9 MethodHandle (java.lang.invoke.MethodHandle)7 ConnectorSession (io.trino.spi.connector.ConnectorSession)5 TrinoException (io.trino.spi.TrinoException)3 ArrayList (java.util.ArrayList)3 FunctionInvoker (io.trino.metadata.FunctionInvoker)2 Block (io.trino.spi.block.Block)2 InvocationArgumentConvention (io.trino.spi.function.InvocationConvention.InvocationArgumentConvention)2 BLOCK_POSITION (io.trino.spi.function.InvocationConvention.InvocationArgumentConvention.BLOCK_POSITION)2 FAIL_ON_NULL (io.trino.spi.function.InvocationConvention.InvocationReturnConvention.FAIL_ON_NULL)2 Type (io.trino.spi.type.Type)2 MethodType.methodType (java.lang.invoke.MethodType.methodType)2 Optional (java.util.Optional)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)1 BytecodeNode (io.airlift.bytecode.BytecodeNode)1 LabelNode (io.airlift.bytecode.instruction.LabelNode)1 Slice (io.airlift.slice.Slice)1