use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.
the class PolymorphicScalarFunction method matchesParameterAndReturnTypes.
private static boolean matchesParameterAndReturnTypes(MethodAndNativeContainerTypes methodAndNativeContainerTypes, BoundSignature boundSignature, List<InvocationArgumentConvention> argumentConventions, InvocationReturnConvention returnConvention) {
Method method = methodAndNativeContainerTypes.getMethod();
checkState(method.getParameterCount() >= boundSignature.getArity(), "method %s has not enough arguments: %s (should have at least %s)", method.getName(), method.getParameterCount(), boundSignature.getArity());
Class<?>[] methodParameterJavaTypes = method.getParameterTypes();
int methodParameterIndex = 0;
for (int i = 0; i < boundSignature.getArity(); i++) {
Type resolvedType = boundSignature.getArgumentType(i);
InvocationArgumentConvention argumentConvention = argumentConventions.get(i);
Class<?> expectedType = null;
Class<?> actualType;
switch(argumentConvention) {
case NEVER_NULL:
case NULL_FLAG:
expectedType = methodParameterJavaTypes[methodParameterIndex];
actualType = resolvedType.getJavaType();
break;
case BOXED_NULLABLE:
expectedType = methodParameterJavaTypes[methodParameterIndex];
actualType = Primitives.wrap(resolvedType.getJavaType());
break;
case BLOCK_POSITION:
Optional<Class<?>> explicitNativeContainerTypes = methodAndNativeContainerTypes.getExplicitNativeContainerTypes().get(i);
if (explicitNativeContainerTypes.isPresent()) {
expectedType = explicitNativeContainerTypes.get();
}
actualType = resolvedType.getJavaType();
break;
default:
throw new UnsupportedOperationException("Unknown argument convention: " + argumentConvention);
}
if (!actualType.equals(expectedType)) {
return false;
}
methodParameterIndex += argumentConvention.getParameterCount();
}
return method.getReturnType().equals(getNullAwareContainerType(boundSignature.getReturnType().getJavaType(), returnConvention));
}
use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.
the class PolymorphicScalarFunction method applyExtraParameters.
private MethodHandle applyExtraParameters(Method matchingMethod, List<Object> extraParameters, List<InvocationArgumentConvention> argumentConventions) {
int expectedArgumentsCount = extraParameters.size() + argumentConventions.stream().mapToInt(InvocationArgumentConvention::getParameterCount).sum();
int matchingMethodArgumentCount = matchingMethod.getParameterCount();
checkState(matchingMethodArgumentCount == expectedArgumentsCount, "method %s has invalid number of arguments: %s (should have %s)", matchingMethod.getName(), matchingMethodArgumentCount, expectedArgumentsCount);
MethodHandle matchingMethodHandle = Reflection.methodHandle(matchingMethod);
matchingMethodHandle = MethodHandles.insertArguments(matchingMethodHandle, matchingMethodArgumentCount - extraParameters.size(), extraParameters.toArray());
return matchingMethodHandle;
}
use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention 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);
}
}
}
use of io.trino.spi.function.InvocationConvention.InvocationArgumentConvention in project trino by trinodb.
the class TestScalarFunctionAdapter method toCallArgumentValues.
private static List<Object> toCallArgumentValues(InvocationConvention callingConvention, BitSet nullArguments, Target target, List<Type> argumentTypes) {
List<Object> callArguments = new ArrayList<>();
callArguments.add(target);
for (int i = 0; i < callingConvention.getArgumentConventions().size(); i++) {
Type argumentType = argumentTypes.get(i);
boolean nullArgument = nullArguments.get(i);
Object testValue;
if (nullArgument) {
testValue = null;
} else {
testValue = getTestValue(argumentType);
}
InvocationArgumentConvention argumentConvention = callingConvention.getArgumentConvention(i);
switch(argumentConvention) {
case NEVER_NULL:
verify(testValue != null, "null can not be passed to a never null argument");
callArguments.add(testValue);
break;
case BOXED_NULLABLE:
callArguments.add(testValue);
break;
case NULL_FLAG:
callArguments.add(testValue == null ? Defaults.defaultValue(argumentType.getJavaType()) : testValue);
callArguments.add(testValue == null);
break;
case BLOCK_POSITION:
BlockBuilder blockBuilder = argumentType.createBlockBuilder(null, 3);
blockBuilder.appendNull();
writeNativeValue(argumentType, blockBuilder, testValue);
blockBuilder.appendNull();
callArguments.add(blockBuilder.build());
callArguments.add(1);
break;
default:
throw new IllegalArgumentException("Unsupported argument convention: " + argumentConvention);
}
}
return callArguments;
}
Aggregations