public static List<SqlAggregationFunction> createFunctionByAnnotations(Class<?> aggregationDefinition) { return ImmutableList.of(AggregationFromAnnotationsParser.parseFunctionDefinition(aggregationDefinition)); }
@VisibleForTesting public static InternalAggregationFunction generateInternalAggregationFunction(Class<?> clazz, TypeSignature outputType, List<TypeSignature> inputTypes, TypeManager typeManager, BoundVariables boundVariables, int arity) { return AggregationFromAnnotationsParser.parseFunctionDefinitionWithTypesConstraint(clazz, outputType, inputTypes).specialize(boundVariables, arity, typeManager); } }
public static List<SqlAggregationFunction> createFunctionsByAnnotations(Class<?> aggregationDefinition) { return AggregationFromAnnotationsParser.parseFunctionDefinitions(aggregationDefinition) .stream() .map(x -> (SqlAggregationFunction) x) .collect(toImmutableList()); }
public static List<ParametricAggregation> parseFunctionDefinitions(Class<?> aggregationDefinition) { AggregationFunction aggregationAnnotation = aggregationDefinition.getAnnotation(AggregationFunction.class); requireNonNull(aggregationAnnotation, "aggregationAnnotation is null"); ImmutableList.Builder<ParametricAggregation> builder = ImmutableList.builder(); for (Class<?> stateClass : getStateClasses(aggregationDefinition)) { Method combineFunction = getCombineFunction(aggregationDefinition, stateClass); Optional<Method> aggregationStateSerializerFactory = getAggregationStateSerializerFactory(aggregationDefinition, stateClass); for (Method outputFunction : getOutputFunctions(aggregationDefinition, stateClass)) { for (Method inputFunction : getInputFunctions(aggregationDefinition, stateClass)) { for (AggregationHeader header : parseHeaders(aggregationDefinition, outputFunction)) { AggregationImplementation onlyImplementation = parseImplementation(aggregationDefinition, header, stateClass, inputFunction, outputFunction, combineFunction, aggregationStateSerializerFactory); ParametricImplementationsGroup<AggregationImplementation> implementations = ParametricImplementationsGroup.of(onlyImplementation); builder.add(new ParametricAggregation(implementations.getSignature(), header, implementations)); } } } } return builder.build(); }
public static ParametricAggregation parseFunctionDefinition(Class<?> aggregationDefinition) { ParametricImplementationsGroup.Builder<AggregationImplementation> implementationsBuilder = ParametricImplementationsGroup.builder(); AggregationHeader header = parseHeader(aggregationDefinition); for (Class<?> stateClass : getStateClasses(aggregationDefinition)) { Method combineFunction = getCombineFunction(aggregationDefinition, stateClass); Optional<Method> aggregationStateSerializerFactory = getAggregationStateSerializerFactory(aggregationDefinition, stateClass); Method outputFunction = getOnlyElement(getOutputFunctions(aggregationDefinition, stateClass)); for (Method inputFunction : getInputFunctions(aggregationDefinition, stateClass)) { AggregationImplementation implementation = parseImplementation(aggregationDefinition, header, stateClass, inputFunction, outputFunction, combineFunction, aggregationStateSerializerFactory); implementationsBuilder.addImplementation(implementation); } } ParametricImplementationsGroup<AggregationImplementation> implementations = implementationsBuilder.build(); return new ParametricAggregation(implementations.getSignature(), header, implementations); }
private static List<AggregationHeader> parseHeaders(AnnotatedElement aggregationDefinition, AnnotatedElement toParse) { AggregationFunction aggregationAnnotation = aggregationDefinition.getAnnotation(AggregationFunction.class); return getNames(toParse, aggregationAnnotation).stream() .map(name -> new AggregationHeader( name, parseDescription(aggregationDefinition, toParse), aggregationAnnotation.decomposable(), aggregationAnnotation.isOrderSensitive(), aggregationAnnotation.hidden())) .collect(toImmutableList()); }
@Test public void testNotAnnotatedAggregateStateAggregationParse() { ParametricAggregation aggregation = parseFunctionDefinition(NotAnnotatedAggregateStateAggregationFunction.class); AggregationImplementation implementation = getOnlyElement(aggregation.getImplementations().getExactImplementations().values()); List<AggregationMetadata.ParameterMetadata.ParameterType> expectedMetadataTypes = ImmutableList.of(AggregationMetadata.ParameterMetadata.ParameterType.STATE, AggregationMetadata.ParameterMetadata.ParameterType.INPUT_CHANNEL); assertTrue(implementation.getInputParameterMetadataTypes().equals(expectedMetadataTypes)); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertTrue(specialized.isDecomposable()); assertEquals(specialized.name(), "no_aggregation_state_aggregate"); }
@VisibleForTesting public static ParametricAggregation parseFunctionDefinitionWithTypesConstraint(Class<?> clazz, TypeSignature returnType, List<TypeSignature> argumentTypes) { requireNonNull(returnType, "returnType is null"); requireNonNull(argumentTypes, "argumentTypes is null"); for (ParametricAggregation aggregation : parseFunctionDefinitions(clazz)) { if (aggregation.getSignature().getReturnType().equals(returnType) && aggregation.getSignature().getArgumentTypes().equals(argumentTypes)) { return aggregation; } } throw new IllegalArgumentException(String.format("No method with return type %s and arguments %s", returnType, argumentTypes)); }
@Test public void testLearnLibSvm() { Type mapType = typeManager.getParameterizedType("map", ImmutableList.of(TypeSignatureParameter.of(parseTypeSignature(StandardTypes.BIGINT)), TypeSignatureParameter.of(parseTypeSignature(StandardTypes.DOUBLE)))); InternalAggregationFunction aggregation = AggregationFromAnnotationsParser.parseFunctionDefinitionWithTypesConstraint( LearnLibSvmClassifierAggregation.class, ClassifierType.BIGINT_CLASSIFIER.getTypeSignature(), ImmutableList.of(BIGINT.getTypeSignature(), mapType.getTypeSignature(), VarcharType.getParametrizedVarcharSignature("x")) ).specialize(BoundVariables.builder().setLongVariable("x", (long) Integer.MAX_VALUE).build(), 3, typeManager); assertLearnClassifer(aggregation.bind(ImmutableList.of(0, 1, 2), Optional.empty()).createAccumulator()); }
@Test public void testStateOnDifferentThanFirstPositionAggregationParse() { Signature expectedSignature = new Signature( "simple_exact_aggregate_aggregation_state_moved", FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); ParametricAggregation aggregation = parseFunctionDefinition(StateOnDifferentThanFirstPositionAggregationFunction.class); assertEquals(aggregation.getSignature(), expectedSignature); AggregationImplementation implementation = getOnlyElement(aggregation.getImplementations().getExactImplementations().values()); assertEquals(implementation.getDefinitionClass(), StateOnDifferentThanFirstPositionAggregationFunction.class); List<AggregationMetadata.ParameterMetadata.ParameterType> expectedMetadataTypes = ImmutableList.of(AggregationMetadata.ParameterMetadata.ParameterType.INPUT_CHANNEL, AggregationMetadata.ParameterMetadata.ParameterType.STATE); assertTrue(implementation.getInputParameterMetadataTypes().equals(expectedMetadataTypes)); }
ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); List<ParametricAggregation> aggregations = parseFunctionDefinitions(MultiOutputAggregationFunction.class); assertEquals(aggregations.size(), 2);
@Test public void testCustomStateSerializerAggregationParse() { ParametricAggregation aggregation = parseFunctionDefinition(CustomStateSerializerAggregationFunction.class); AggregationImplementation implementation = getOnlyElement(aggregation.getImplementations().getExactImplementations().values()); assertTrue(implementation.getStateSerializerFactory().isPresent()); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); AccumulatorStateSerializer<?> createdSerializer = getOnlyElement(((LazyAccumulatorFactoryBinder) specialized.getAccumulatorFactoryBinder()) .getGenericAccumulatorFactoryBinder().getStateDescriptors()).getSerializer(); Class<?> serializerFactory = implementation.getStateSerializerFactory().get().type().returnType(); assertTrue(serializerFactory.isInstance(createdSerializer)); }
@Test public void testFixedTypeParameterInjectionAggregateFunctionParse() { Signature expectedSignature = new Signature( "fixed_type_parameter_injection", FunctionKind.AGGREGATE, ImmutableList.of(), ImmutableList.of(), DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature()), false); ParametricAggregation aggregation = parseFunctionDefinition(FixedTypeParameterInjectionAggregateFunction.class); assertEquals(aggregation.getDescription(), "Simple aggregate with fixed parameter type injected"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations(); assertImplementationCount(implementations, 1, 0, 0); AggregationImplementation implementationDouble = implementations.getExactImplementations().get(expectedSignature); assertFalse(implementationDouble.getStateSerializerFactory().isPresent()); assertEquals(implementationDouble.getDefinitionClass(), FixedTypeParameterInjectionAggregateFunction.class); assertDependencyCount(implementationDouble, 1, 1, 1); assertFalse(implementationDouble.hasSpecializedTypeParameters()); List<AggregationMetadata.ParameterMetadata.ParameterType> expectedMetadataTypes = ImmutableList.of(AggregationMetadata.ParameterMetadata.ParameterType.STATE, AggregationMetadata.ParameterMetadata.ParameterType.INPUT_CHANNEL); assertTrue(implementationDouble.getInputParameterMetadataTypes().equals(expectedMetadataTypes)); assertEquals(implementationDouble.getStateClass(), NullableDoubleState.class); }
@Test public void testNotDecomposableAggregationParse() { Signature expectedSignature = new Signature( "custom_decomposable_aggregate", FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); ParametricAggregation aggregation = parseFunctionDefinition(NotDecomposableAggregationFunction.class); assertEquals(aggregation.getDescription(), "Aggregate with Decomposable=false"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertFalse(specialized.isDecomposable()); assertEquals(specialized.name(), "custom_decomposable_aggregate"); }
@Test public void testSimpleExactAggregationParse() { Signature expectedSignature = new Signature( "simple_exact_aggregate", FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); ParametricAggregation aggregation = parseFunctionDefinition(ExactAggregationFunction.class); assertEquals(aggregation.getDescription(), "Simple exact aggregate description"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations(); assertImplementationCount(implementations, 1, 0, 0); AggregationImplementation implementation = getOnlyElement(implementations.getExactImplementations().values()); assertFalse(implementation.getStateSerializerFactory().isPresent()); assertEquals(implementation.getDefinitionClass(), ExactAggregationFunction.class); assertDependencyCount(implementation, 0, 0, 0); assertFalse(implementation.hasSpecializedTypeParameters()); List<AggregationMetadata.ParameterMetadata.ParameterType> expectedMetadataTypes = ImmutableList.of(AggregationMetadata.ParameterMetadata.ParameterType.STATE, AggregationMetadata.ParameterMetadata.ParameterType.INPUT_CHANNEL); assertTrue(implementation.getInputParameterMetadataTypes().equals(expectedMetadataTypes)); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertTrue(specialized.isDecomposable()); assertEquals(specialized.name(), "simple_exact_aggregate"); }
@Test public void testSimpleBlockInputAggregationParse() { Signature expectedSignature = new Signature( "block_input_aggregate", FunctionKind.AGGREGATE, DoubleType.DOUBLE.getTypeSignature(), ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); ParametricAggregation aggregation = parseFunctionDefinition(BlockInputAggregationFunction.class); assertEquals(aggregation.getDescription(), "Simple aggregate with @BlockPosition usage"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations(); assertImplementationCount(implementations, 1, 0, 0); AggregationImplementation implementation = getOnlyElement(implementations.getExactImplementations().values()); assertFalse(implementation.getStateSerializerFactory().isPresent()); assertEquals(implementation.getDefinitionClass(), BlockInputAggregationFunction.class); assertDependencyCount(implementation, 0, 0, 0); assertFalse(implementation.hasSpecializedTypeParameters()); List<AggregationMetadata.ParameterMetadata.ParameterType> expectedMetadataTypes = ImmutableList.of(AggregationMetadata.ParameterMetadata.ParameterType.STATE, AggregationMetadata.ParameterMetadata.ParameterType.BLOCK_INPUT_CHANNEL, AggregationMetadata.ParameterMetadata.ParameterType.BLOCK_INDEX); assertEquals(implementation.getInputParameterMetadataTypes(), expectedMetadataTypes); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertTrue(specialized.isDecomposable()); assertEquals(specialized.name(), "block_input_aggregate"); }
ImmutableList.of(parseTypeSignature("varchar(x)", ImmutableSet.of("x")))); ParametricAggregation aggregation = parseFunctionDefinition(InjectLiteralAggregateFunction.class); assertEquals(aggregation.getDescription(), "Simple aggregate with type literal"); assertTrue(aggregation.isDeterministic());
false); ParametricAggregation aggregation = parseFunctionDefinition(GenericAggregationFunction.class); assertEquals(aggregation.getDescription(), "Simple aggregate with two generic implementations"); assertTrue(aggregation.isDeterministic());
ImmutableList.of(DoubleType.DOUBLE.getTypeSignature())); ParametricAggregation aggregation = parseFunctionDefinition(InjectOperatorAggregateFunction.class); assertEquals(aggregation.getDescription(), "Simple aggregate with operator injected"); assertTrue(aggregation.isDeterministic());
false); ParametricAggregation aggregation = parseFunctionDefinition(InjectTypeAggregateFunction.class); assertEquals(aggregation.getDescription(), "Simple aggregate with type injected"); assertTrue(aggregation.isDeterministic());