use of com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation in project presto by prestodb.
the class TestAnnotationEngineForScalars method testWithNullablePrimitiveArgScalarParse.
@Test
public void testWithNullablePrimitiveArgScalarParse() {
Signature expectedSignature = new Signature(QualifiedObjectName.valueOf(DEFAULT_NAMESPACE, "scalar_with_nullable"), FunctionKind.SCALAR, 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);
assertEquals(scalar.getSignature(), expectedSignature);
assertTrue(scalar.isDeterministic());
assertEquals(scalar.getVisibility(), PUBLIC);
assertEquals(scalar.getDescription(), "Simple scalar with nullable primitive");
BuiltInScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 2, FUNCTION_AND_TYPE_MANAGER);
assertFalse(specialized.getInstanceFactory().isPresent());
assertEquals(specialized.getArgumentProperty(0), valueTypeArgumentProperty(RETURN_NULL_ON_NULL));
assertEquals(specialized.getArgumentProperty(1), valueTypeArgumentProperty(USE_NULL_FLAG));
}
use of com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation in project presto by prestodb.
the class TestPolymorphicScalarFunction method testSetsHiddenToTrueForOperators.
@Test
public void testSetsHiddenToTrueForOperators() {
Signature signature = SignatureBuilder.builder().operatorType(ADD).kind(SCALAR).returnType(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))).argumentTypes(parseTypeSignature("varchar(x)", ImmutableSet.of("x"))).build();
SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class, ADD).signature(signature).deterministic(true).choice(choice -> choice.implementation(methodsGroup -> methodsGroup.methods("varcharToVarchar"))).build();
BuiltInScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, FUNCTION_AND_TYPE_MANAGER);
}
use of com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation in project presto by prestodb.
the class TestPolymorphicScalarFunction method testSelectsMethodBasedOnArgumentTypes.
@Test
public void testSelectsMethodBasedOnArgumentTypes() throws Throwable {
SqlScalarFunction function = SqlScalarFunction.builder(TestMethods.class).signature(SIGNATURE).deterministic(true).calledOnNullInput(false).choice(choice -> choice.implementation(methodsGroup -> methodsGroup.methods("bigintToBigintReturnExtraParameter")).implementation(methodsGroup -> methodsGroup.methods("varcharToBigintReturnExtraParameter").withExtraParameters(context -> ImmutableList.of(context.getLiteral("x"))))).build();
BuiltInScalarFunctionImplementation functionImplementation = function.specialize(BOUND_VARIABLES, 1, FUNCTION_AND_TYPE_MANAGER);
assertEquals(functionImplementation.getMethodHandle().invoke(INPUT_SLICE), INPUT_VARCHAR_LENGTH);
}
use of com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation in project presto by prestodb.
the class CodegenScalarFromAnnotationsParser method createSqlScalarFunction.
private static SqlScalarFunction createSqlScalarFunction(Method method) {
CodegenScalarFunction codegenScalarFunction = method.getAnnotation(CodegenScalarFunction.class);
Signature signature = new Signature(QualifiedObjectName.valueOf(DEFAULT_NAMESPACE, codegenScalarFunction.value()), FunctionKind.SCALAR, Arrays.stream(method.getAnnotationsByType(TypeParameter.class)).map(t -> withVariadicBound(t.value(), t.boundedBy().isEmpty() ? null : t.boundedBy())).collect(toImmutableList()), ImmutableList.of(), parseTypeSignature(method.getAnnotation(SqlType.class).value()), Arrays.stream(method.getParameters()).map(p -> parseTypeSignature(p.getAnnotation(SqlType.class).value())).collect(toImmutableList()), false);
return new SqlScalarFunction(signature) {
@Override
public BuiltInScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, FunctionAndTypeManager functionAndTypeManager) {
Signature boundSignature = applyBoundVariables(signature, boundVariables, arity);
MethodHandle handle;
try {
handle = (MethodHandle) method.invoke(null, boundSignature.getArgumentTypes().stream().map(t -> functionAndTypeManager.getType(t)).toArray());
} catch (Exception e) {
throw new PrestoException(FUNCTION_IMPLEMENTATION_ERROR, format("Method %s does not return valid MethodHandle", method), e);
}
return new BuiltInScalarFunctionImplementation(method.getAnnotation(SqlNullable.class) != null, getArgumentProperties(method), handle, Optional.empty());
}
@Override
public SqlFunctionVisibility getVisibility() {
return codegenScalarFunction.visibility();
}
@Override
public boolean isDeterministic() {
return codegenScalarFunction.deterministic();
}
@Override
public String getDescription() {
Description description = method.getAnnotation(Description.class);
return description == null ? "" : description.value();
}
@Override
public boolean isCalledOnNullInput() {
return codegenScalarFunction.calledOnNullInput();
}
};
}
use of com.facebook.presto.operator.scalar.BuiltInScalarFunctionImplementation in project presto by prestodb.
the class ParametricScalarImplementation method specialize.
public Optional<BuiltInScalarFunctionImplementation> specialize(Signature boundSignature, BoundVariables boundVariables, FunctionAndTypeManager functionAndTypeManager) {
List<ScalarFunctionImplementationChoice> implementationChoices = new ArrayList<>();
for (Map.Entry<String, Class<?>> entry : specializedTypeParameters.entrySet()) {
if (entry.getValue() != boundVariables.getTypeVariable(entry.getKey()).getJavaType()) {
return Optional.empty();
}
}
if (returnNativeContainerType != Object.class && returnNativeContainerType != functionAndTypeManager.getType(boundSignature.getReturnType()).getJavaType()) {
return Optional.empty();
}
for (int i = 0; i < boundSignature.getArgumentTypes().size(); i++) {
if (boundSignature.getArgumentTypes().get(i).getBase().equals(FunctionType.NAME)) {
if (argumentNativeContainerTypes.get(i).isPresent()) {
return Optional.empty();
}
} else {
if (!argumentNativeContainerTypes.get(i).isPresent()) {
return Optional.empty();
}
Class<?> argumentType = functionAndTypeManager.getType(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(), boundVariables, functionAndTypeManager);
Optional<MethodHandle> boundConstructor = choice.getConstructor().map(constructor -> {
MethodHandle result = bindDependencies(constructor, choice.getConstructorDependencies(), boundVariables, functionAndTypeManager);
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 ScalarFunctionImplementationChoice(choice.nullable, choice.argumentProperties, choice.returnPlaceConvention, boundMethodHandle.asType(javaMethodType(choice, boundSignature, functionAndTypeManager)), boundConstructor));
}
return Optional.of(new BuiltInScalarFunctionImplementation(implementationChoices));
}
Aggregations