use of io.trino.metadata.FunctionMetadata 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());
}
use of io.trino.metadata.FunctionMetadata in project trino by trinodb.
the class TestAnnotationEngineForScalars method testConstructorInjectionScalarParse.
@Test
public void testConstructorInjectionScalarParse() {
Signature expectedSignature = new Signature("parametric_scalar_inject_constructor", ImmutableList.of(typeVariable("T")), ImmutableList.of(), BIGINT.getTypeSignature(), ImmutableList.of(arrayType(new TypeSignature("T"))), false);
List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinition(ConstructorInjectionScalarFunction.class);
assertEquals(functions.size(), 1);
ParametricScalar scalar = (ParametricScalar) functions.get(0);
assertImplementationCount(scalar, 2, 0, 1);
List<ParametricScalarImplementationChoice> parametricScalarImplementationChoices = scalar.getImplementations().getGenericImplementations().get(0).getChoices();
assertEquals(parametricScalarImplementationChoices.size(), 1);
List<ImplementationDependency> dependencies = parametricScalarImplementationChoices.get(0).getDependencies();
assertEquals(dependencies.size(), 0);
List<ImplementationDependency> constructorDependencies = parametricScalarImplementationChoices.get(0).getConstructorDependencies();
assertEquals(constructorDependencies.size(), 1);
assertTrue(constructorDependencies.get(0) instanceof TypeImplementationDependency);
FunctionMetadata functionMetadata = scalar.getFunctionMetadata();
assertEquals(functionMetadata.getSignature(), expectedSignature);
assertTrue(functionMetadata.isDeterministic());
assertFalse(functionMetadata.isHidden());
assertEquals(functionMetadata.getDescription(), "Parametric scalar with type injected though constructor");
}
use of io.trino.metadata.FunctionMetadata in project trino by trinodb.
the class ParametricScalar method specialize.
@Override
public ScalarFunctionImplementation specialize(BoundSignature boundSignature, FunctionDependencies functionDependencies) {
FunctionMetadata metadata = getFunctionMetadata();
FunctionBinding functionBinding = SignatureBinder.bindFunction(metadata.getFunctionId(), metadata.getSignature(), boundSignature);
ParametricScalarImplementation exactImplementation = implementations.getExactImplementations().get(boundSignature.toSignature());
if (exactImplementation != null) {
Optional<ScalarFunctionImplementation> scalarFunctionImplementation = exactImplementation.specialize(functionBinding, functionDependencies);
checkCondition(scalarFunctionImplementation.isPresent(), FUNCTION_IMPLEMENTATION_ERROR, format("Exact implementation of %s do not match expected java types.", boundSignature.getName()));
return scalarFunctionImplementation.get();
}
ScalarFunctionImplementation selectedImplementation = null;
for (ParametricScalarImplementation implementation : implementations.getSpecializedImplementations()) {
Optional<ScalarFunctionImplementation> scalarFunctionImplementation = implementation.specialize(functionBinding, functionDependencies);
if (scalarFunctionImplementation.isPresent()) {
checkCondition(selectedImplementation == null, AMBIGUOUS_FUNCTION_IMPLEMENTATION, "Ambiguous implementation for %s with bindings %s", metadata.getSignature(), boundSignature);
selectedImplementation = scalarFunctionImplementation.get();
}
}
if (selectedImplementation != null) {
return selectedImplementation;
}
for (ParametricScalarImplementation implementation : implementations.getGenericImplementations()) {
Optional<ScalarFunctionImplementation> scalarFunctionImplementation = implementation.specialize(functionBinding, functionDependencies);
if (scalarFunctionImplementation.isPresent()) {
checkCondition(selectedImplementation == null, AMBIGUOUS_FUNCTION_IMPLEMENTATION, "Ambiguous implementation for %s with bindings %s", metadata.getSignature(), boundSignature);
selectedImplementation = scalarFunctionImplementation.get();
}
}
if (selectedImplementation != null) {
return selectedImplementation;
}
throw new TrinoException(FUNCTION_IMPLEMENTATION_MISSING, format("Unsupported binding %s for signature %s", boundSignature, getFunctionMetadata().getSignature()));
}
use of io.trino.metadata.FunctionMetadata in project trino by trinodb.
the class ParametricAggregation method specialize.
@Override
public AggregationMetadata specialize(BoundSignature boundSignature, FunctionDependencies functionDependencies) {
// Find implementation matching arguments
AggregationImplementation concreteImplementation = findMatchingImplementation(boundSignature);
// Build state factory and serializer
AccumulatorStateDescriptor<?> accumulatorStateDescriptor = generateAccumulatorStateDescriptor(stateClass);
// Bind provided dependencies to aggregation method handlers
FunctionMetadata metadata = getFunctionMetadata();
FunctionBinding functionBinding = SignatureBinder.bindFunction(metadata.getFunctionId(), metadata.getSignature(), boundSignature);
MethodHandle inputHandle = bindDependencies(concreteImplementation.getInputFunction(), concreteImplementation.getInputDependencies(), functionBinding, functionDependencies);
Optional<MethodHandle> removeInputHandle = concreteImplementation.getRemoveInputFunction().map(removeInputFunction -> bindDependencies(removeInputFunction, concreteImplementation.getRemoveInputDependencies(), functionBinding, functionDependencies));
Optional<MethodHandle> combineHandle = concreteImplementation.getCombineFunction();
if (getAggregationMetadata().isDecomposable()) {
checkArgument(combineHandle.isPresent(), "Decomposable method %s does not have a combine method", boundSignature.getName());
combineHandle = combineHandle.map(combineFunction -> bindDependencies(combineFunction, concreteImplementation.getCombineDependencies(), functionBinding, functionDependencies));
} else {
checkArgument(concreteImplementation.getCombineFunction().isEmpty(), "Decomposable method %s does not have a combine method", boundSignature.getName());
}
MethodHandle outputHandle = bindDependencies(concreteImplementation.getOutputFunction(), concreteImplementation.getOutputDependencies(), functionBinding, functionDependencies);
List<AggregationParameterKind> inputParameterKinds = concreteImplementation.getInputParameterKinds();
inputHandle = normalizeInputMethod(inputHandle, boundSignature, inputParameterKinds);
removeInputHandle = removeInputHandle.map(function -> normalizeInputMethod(function, boundSignature, inputParameterKinds));
return new AggregationMetadata(inputHandle, removeInputHandle, combineHandle, outputHandle, ImmutableList.of(accumulatorStateDescriptor));
}
use of io.trino.metadata.FunctionMetadata in project trino by trinodb.
the class TestAnnotationEngineForAggregates method specializeAggregationFunction.
private static void specializeAggregationFunction(BoundSignature boundSignature, SqlAggregationFunction aggregation) {
FunctionMetadata functionMetadata = aggregation.getFunctionMetadata();
FunctionBinding functionBinding = MetadataManager.toFunctionBinding(functionMetadata.getFunctionId(), boundSignature, functionMetadata.getSignature());
AggregationFunctionMetadata aggregationMetadata = aggregation.getAggregationMetadata();
assertFalse(aggregationMetadata.isOrderSensitive());
assertFalse(aggregationMetadata.getIntermediateTypes().isEmpty());
ResolvedFunction resolvedFunction = METADATA.resolve(TEST_SESSION, functionBinding, functionMetadata, aggregation.getFunctionDependencies(boundSignature));
FunctionDependencies functionDependencies = new FunctionDependencies(FUNCTION_MANAGER::getScalarFunctionInvoker, resolvedFunction.getTypeDependencies(), resolvedFunction.getFunctionDependencies());
aggregation.specialize(boundSignature, functionDependencies);
}
Aggregations