use of io.trino.spi.function.AccumulatorState in project trino by trinodb.
the class AggregationFromAnnotationsParser method parseFunctionDefinitions.
public static List<ParametricAggregation> parseFunctionDefinitions(Class<?> aggregationDefinition) {
AggregationFunction aggregationAnnotation = aggregationDefinition.getAnnotation(AggregationFunction.class);
requireNonNull(aggregationAnnotation, "aggregationAnnotation is null");
ImmutableList.Builder<ParametricAggregation> functions = ImmutableList.builder();
// There must be a single state class and combine function
Class<? extends AccumulatorState> stateClass = getStateClass(aggregationDefinition);
Optional<Method> combineFunction = getCombineFunction(aggregationDefinition, stateClass);
// Each output function defines a new aggregation function
for (Method outputFunction : getOutputFunctions(aggregationDefinition, stateClass)) {
AggregationHeader header = parseHeader(aggregationDefinition, outputFunction);
if (header.isDecomposable()) {
checkArgument(combineFunction.isPresent(), "Decomposable method %s does not have a combine method", header.getName());
} else if (combineFunction.isPresent()) {
log.warn("Aggregation function %s is not decomposable, but has combine method", header.getName());
}
// Input functions can have either an exact signature, or generic/calculate signature
List<AggregationImplementation> exactImplementations = new ArrayList<>();
List<AggregationImplementation> nonExactImplementations = new ArrayList<>();
for (Method inputFunction : getInputFunctions(aggregationDefinition, stateClass)) {
Optional<Method> removeInputFunction = getRemoveInputFunction(aggregationDefinition, inputFunction);
AggregationImplementation implementation = parseImplementation(aggregationDefinition, header.getName(), inputFunction, removeInputFunction, outputFunction, combineFunction.filter(function -> header.isDecomposable()));
if (isGenericOrCalculated(implementation.getSignature())) {
exactImplementations.add(implementation);
} else {
nonExactImplementations.add(implementation);
}
}
// register a set functions for the canonical name, and each alias
functions.addAll(buildFunctions(header.getName(), header, stateClass, exactImplementations, nonExactImplementations));
for (String alias : getAliases(aggregationDefinition.getAnnotation(AggregationFunction.class), outputFunction)) {
functions.addAll(buildFunctions(alias, header, stateClass, exactImplementations, nonExactImplementations));
}
}
return functions.build();
}
use of io.trino.spi.function.AccumulatorState in project trino by trinodb.
the class AggregationFromAnnotationsParser method getStateClass.
private static Class<? extends AccumulatorState> getStateClass(Class<?> clazz) {
ImmutableSet.Builder<Class<? extends AccumulatorState>> builder = ImmutableSet.builder();
for (Method inputFunction : FunctionsParserHelper.findPublicStaticMethodsWithAnnotation(clazz, InputFunction.class)) {
checkArgument(inputFunction.getParameterTypes().length > 0, "Input function has no parameters");
Class<?> stateClass = AggregationImplementation.Parser.findAggregationStateParamType(inputFunction);
checkArgument(AccumulatorState.class.isAssignableFrom(stateClass), "stateClass is not a subclass of AccumulatorState");
builder.add(stateClass.asSubclass(AccumulatorState.class));
}
ImmutableSet<Class<? extends AccumulatorState>> stateClasses = builder.build();
checkArgument(!stateClasses.isEmpty(), "No input functions found");
checkArgument(stateClasses.size() == 1, "There must be exactly one @AccumulatorState in class %s", clazz.toGenericString());
return getOnlyElement(stateClasses);
}
Aggregations