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));
}
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);
}
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));
}
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);
}
}
}
Aggregations