use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation in project trino by trinodb.
the class ParametricScalarImplementation method specialize.
public Optional<ScalarFunctionImplementation> specialize(FunctionBinding functionBinding, FunctionDependencies functionDependencies) {
List<ScalarImplementationChoice> implementationChoices = new ArrayList<>();
for (Map.Entry<String, Class<?>> entry : specializedTypeParameters.entrySet()) {
if (!entry.getValue().isAssignableFrom(functionBinding.getTypeVariable(entry.getKey()).getJavaType())) {
return Optional.empty();
}
}
BoundSignature boundSignature = functionBinding.getBoundSignature();
if (returnNativeContainerType != Object.class && returnNativeContainerType != boundSignature.getReturnType().getJavaType()) {
return Optional.empty();
}
for (int i = 0; i < boundSignature.getArgumentTypes().size(); i++) {
if (boundSignature.getArgumentTypes().get(i) instanceof FunctionType) {
if (argumentNativeContainerTypes.get(i).isPresent()) {
return Optional.empty();
}
} else {
if (argumentNativeContainerTypes.get(i).isEmpty()) {
return Optional.empty();
}
Class<?> argumentType = boundSignature.getArgumentTypes().get(i).getJavaType();
Class<?> argumentNativeContainerType = argumentNativeContainerTypes.get(i).get();
if (argumentNativeContainerType != Object.class && argumentNativeContainerType != argumentType) {
return Optional.empty();
}
}
}
for (ParametricScalarImplementationChoice choice : choices) {
MethodHandle boundMethodHandle = bindDependencies(choice.getMethodHandle(), choice.getDependencies(), functionBinding, functionDependencies);
Optional<MethodHandle> boundConstructor = choice.getConstructor().map(constructor -> {
MethodHandle result = bindDependencies(constructor, choice.getConstructorDependencies(), functionBinding, functionDependencies);
checkCondition(result.type().parameterList().isEmpty(), FUNCTION_IMPLEMENTATION_ERROR, "All parameters of a constructor in a function definition class must be Dependencies. Signature: %s", boundSignature);
return result;
});
implementationChoices.add(new ScalarImplementationChoice(choice.getReturnConvention(), choice.getArgumentConventions(), choice.getLambdaInterfaces(), boundMethodHandle.asType(javaMethodType(choice, boundSignature)), boundConstructor));
}
return Optional.of(new ChoicesScalarFunctionImplementation(boundSignature, implementationChoices));
}
use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation in project trino by trinodb.
the class TestPolymorphicScalarFunction method testSameLiteralInArgumentsAndReturnValue.
@Test
public void testSameLiteralInArgumentsAndReturnValue() throws Throwable {
Signature signature = Signature.builder().name("foo").returnType(new TypeSignature("varchar", typeVariable("x"))).argumentTypes(new TypeSignature("varchar", typeVariable("x"))).build();
SqlScalarFunction function = new PolymorphicScalarFunctionBuilder(TestMethods.class).signature(signature).deterministic(true).choice(choice -> choice.implementation(methodsGroup -> methodsGroup.methods("varcharToVarchar"))).build();
BoundSignature boundSignature = new BoundSignature(signature.getName(), createVarcharType(INPUT_VARCHAR_LENGTH), ImmutableList.of(createVarcharType(INPUT_VARCHAR_LENGTH)));
ChoicesScalarFunctionImplementation functionImplementation = (ChoicesScalarFunctionImplementation) function.specialize(boundSignature, new FunctionDependencies(FUNCTION_MANAGER::getScalarFunctionInvoker, ImmutableMap.of(), ImmutableSet.of()));
Slice slice = (Slice) functionImplementation.getChoices().get(0).getMethodHandle().invoke(INPUT_SLICE);
assertEquals(slice, VARCHAR_TO_VARCHAR_RETURN_VALUE);
}
use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation in project trino by trinodb.
the class TestPolymorphicScalarFunction method testSelectsMultipleChoiceWithBlockPosition.
@Test
public void testSelectsMultipleChoiceWithBlockPosition() throws Throwable {
Signature signature = Signature.builder().operatorType(IS_DISTINCT_FROM).argumentTypes(DECIMAL_SIGNATURE, DECIMAL_SIGNATURE).returnType(BOOLEAN.getTypeSignature()).build();
SqlScalarFunction function = new PolymorphicScalarFunctionBuilder(TestMethods.class).signature(signature).argumentNullability(true, true).deterministic(true).choice(choice -> choice.argumentProperties(NULL_FLAG, NULL_FLAG).implementation(methodsGroup -> methodsGroup.methods("shortShort", "longLong"))).choice(choice -> choice.argumentProperties(BLOCK_POSITION, BLOCK_POSITION).implementation(methodsGroup -> methodsGroup.methodWithExplicitJavaTypes("blockPositionLongLong", asList(Optional.of(Int128.class), Optional.of(Int128.class))).methodWithExplicitJavaTypes("blockPositionShortShort", asList(Optional.of(long.class), Optional.of(long.class))))).build();
BoundSignature shortDecimalBoundSignature = new BoundSignature(signature.getName(), BOOLEAN, ImmutableList.of(SHORT_DECIMAL_BOUND_TYPE, SHORT_DECIMAL_BOUND_TYPE));
ChoicesScalarFunctionImplementation functionImplementation = (ChoicesScalarFunctionImplementation) function.specialize(shortDecimalBoundSignature, new FunctionDependencies(FUNCTION_MANAGER::getScalarFunctionInvoker, ImmutableMap.of(), ImmutableSet.of()));
assertEquals(functionImplementation.getChoices().size(), 2);
assertEquals(functionImplementation.getChoices().get(0).getInvocationConvention(), new InvocationConvention(ImmutableList.of(NULL_FLAG, NULL_FLAG), FAIL_ON_NULL, false, false));
assertEquals(functionImplementation.getChoices().get(1).getInvocationConvention(), new InvocationConvention(ImmutableList.of(BLOCK_POSITION, BLOCK_POSITION), FAIL_ON_NULL, false, false));
Block block1 = new LongArrayBlock(0, Optional.empty(), new long[0]);
Block block2 = new LongArrayBlock(0, Optional.empty(), new long[0]);
assertFalse((boolean) functionImplementation.getChoices().get(1).getMethodHandle().invoke(block1, 0, block2, 0));
BoundSignature longDecimalBoundSignature = new BoundSignature(signature.getName(), BOOLEAN, ImmutableList.of(LONG_DECIMAL_BOUND_TYPE, LONG_DECIMAL_BOUND_TYPE));
functionImplementation = (ChoicesScalarFunctionImplementation) function.specialize(longDecimalBoundSignature, new FunctionDependencies(FUNCTION_MANAGER::getScalarFunctionInvoker, ImmutableMap.of(), ImmutableSet.of()));
assertTrue((boolean) functionImplementation.getChoices().get(1).getMethodHandle().invoke(block1, 0, block2, 0));
}
use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation in project trino by trinodb.
the class TestAnnotationEngineForScalars method testWithNullableComplexArgScalarParse.
@Test
public void testWithNullableComplexArgScalarParse() {
Signature expectedSignature = new Signature("scalar_with_nullable_complex", DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature(), DOUBLE.getTypeSignature()));
List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinition(WithNullableComplexArgScalarFunction.class);
assertEquals(functions.size(), 1);
ParametricScalar scalar = (ParametricScalar) functions.get(0);
FunctionMetadata functionMetadata = scalar.getFunctionMetadata();
assertEquals(functionMetadata.getSignature(), expectedSignature);
assertTrue(functionMetadata.isDeterministic());
assertFalse(functionMetadata.isHidden());
assertEquals(functionMetadata.getDescription(), "Simple scalar with nullable complex type");
assertFalse(functionMetadata.getFunctionNullability().isArgumentNullable(0));
assertTrue(functionMetadata.getFunctionNullability().isArgumentNullable(1));
BoundSignature boundSignature = new BoundSignature(expectedSignature.getName(), DOUBLE, ImmutableList.of(DOUBLE, DOUBLE));
ChoicesScalarFunctionImplementation specialized = (ChoicesScalarFunctionImplementation) scalar.specialize(boundSignature, new FunctionDependencies(FUNCTION_MANAGER::getScalarFunctionInvoker, ImmutableMap.of(), ImmutableSet.of()));
assertFalse(specialized.getChoices().get(0).getInstanceFactory().isPresent());
}
use of io.trino.operator.scalar.ChoicesScalarFunctionImplementation in project trino by trinodb.
the class TestAnnotationEngineForScalars method testWithNullablePrimitiveArgScalarParse.
@Test
public void testWithNullablePrimitiveArgScalarParse() {
Signature expectedSignature = new Signature("scalar_with_nullable", DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature(), DOUBLE.getTypeSignature()));
List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinition(WithNullablePrimitiveArgScalarFunction.class);
assertEquals(functions.size(), 1);
ParametricScalar scalar = (ParametricScalar) functions.get(0);
FunctionMetadata functionMetadata = scalar.getFunctionMetadata();
assertEquals(functionMetadata.getSignature(), expectedSignature);
assertTrue(functionMetadata.isDeterministic());
assertFalse(functionMetadata.isHidden());
assertEquals(functionMetadata.getDescription(), "Simple scalar with nullable primitive");
assertFalse(functionMetadata.getFunctionNullability().isArgumentNullable(0));
assertTrue(functionMetadata.getFunctionNullability().isArgumentNullable(1));
BoundSignature boundSignature = new BoundSignature(expectedSignature.getName(), DOUBLE, ImmutableList.of(DOUBLE, DOUBLE));
ChoicesScalarFunctionImplementation specialized = (ChoicesScalarFunctionImplementation) scalar.specialize(boundSignature, new FunctionDependencies(FUNCTION_MANAGER::getScalarFunctionInvoker, ImmutableMap.of(), ImmutableSet.of()));
assertFalse(specialized.getChoices().get(0).getInstanceFactory().isPresent());
}
Aggregations