@VisibleForTesting public static InternalAggregationFunction generateInternalAggregationFunction(Class<?> clazz, TypeSignature outputType, List<TypeSignature> inputTypes, TypeManager typeManager) { return generateInternalAggregationFunction(clazz, outputType, inputTypes, typeManager, BoundVariables.builder().build(), inputTypes.size()); }
@VisibleForTesting public static InternalAggregationFunction generateInternalAggregationFunction(Class<?> clazz, TypeSignature outputType, List<TypeSignature> inputTypes, TypeManager typeManager) { return generateInternalAggregationFunction(clazz, outputType, inputTypes, typeManager, BoundVariables.builder().build(), inputTypes.size()); }
@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"); }
@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"); }
@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 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 testWithNullablePrimitiveArgScalarParse() { Signature expectedSignature = new Signature( "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()); assertFalse(scalar.isHidden()); assertEquals(scalar.getDescription(), "Simple scalar with nullable primitive"); ScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 2, new TypeRegistry(), null); assertFalse(specialized.getInstanceFactory().isPresent()); assertEquals(specialized.getArgumentProperty(0), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); assertEquals(specialized.getArgumentProperty(1), valueTypeArgumentProperty(USE_NULL_FLAG)); }
@Test public void testWithNullableComplexArgScalarParse() { Signature expectedSignature = new Signature( "scalar_with_nullable_complex", FunctionKind.SCALAR, 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); assertEquals(scalar.getSignature(), expectedSignature); assertTrue(scalar.isDeterministic()); assertFalse(scalar.isHidden()); assertEquals(scalar.getDescription(), "Simple scalar with nullable complex type"); ScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 2, new TypeRegistry(), null); assertFalse(specialized.getInstanceFactory().isPresent()); assertEquals(specialized.getArgumentProperty(0), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); assertEquals(specialized.getArgumentProperty(1), valueTypeArgumentProperty(USE_BOXED_TYPE)); }
@Test public void testSingleImplementationScalarParse() { Signature expectedSignature = new Signature( "single_implementation_parametric_scalar", FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinition(SingleImplementationScalarFunction.class); assertEquals(functions.size(), 1); ParametricScalar scalar = (ParametricScalar) functions.get(0); assertEquals(scalar.getSignature(), expectedSignature); assertTrue(scalar.isDeterministic()); assertFalse(scalar.isHidden()); assertEquals(scalar.getDescription(), "Simple scalar with single implementation based on class"); assertImplementationCount(scalar, 1, 0, 0); ScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); assertFalse(specialized.getInstanceFactory().isPresent()); assertEquals(specialized.getArgumentProperty(0).getNullConvention(), RETURN_NULL_ON_NULL); }
@Test public void testSingleImplementationScalarParse() { Signature expectedSignature = new Signature( "single_implementation_parametric_scalar", FunctionKind.SCALAR, DOUBLE.getTypeSignature(), ImmutableList.of(DOUBLE.getTypeSignature())); List<SqlScalarFunction> functions = ScalarFromAnnotationsParser.parseFunctionDefinition(SingleImplementationScalarFunction.class); assertEquals(functions.size(), 1); ParametricScalar scalar = (ParametricScalar) functions.get(0); assertEquals(scalar.getSignature(), expectedSignature); assertTrue(scalar.isDeterministic()); assertFalse(scalar.isHidden()); assertEquals(scalar.getDescription(), "Simple scalar with single implementation based on class"); assertImplementationCount(scalar, 1, 0, 0); ScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); assertFalse(specialized.getInstanceFactory().isPresent()); assertEquals(specialized.getArgumentProperty(0).getNullConvention(), RETURN_NULL_ON_NULL); }
@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 testWithNullablePrimitiveArgScalarParse() { Signature expectedSignature = new Signature( "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()); assertFalse(scalar.isHidden()); assertEquals(scalar.getDescription(), "Simple scalar with nullable primitive"); ScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 2, new TypeRegistry(), null); assertFalse(specialized.getInstanceFactory().isPresent()); assertEquals(specialized.getArgumentProperty(0), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); assertEquals(specialized.getArgumentProperty(1), valueTypeArgumentProperty(USE_NULL_FLAG)); }
@Test public void testWithNullableComplexArgScalarParse() { Signature expectedSignature = new Signature( "scalar_with_nullable_complex", FunctionKind.SCALAR, 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); assertEquals(scalar.getSignature(), expectedSignature); assertTrue(scalar.isDeterministic()); assertFalse(scalar.isHidden()); assertEquals(scalar.getDescription(), "Simple scalar with nullable complex type"); ScalarFunctionImplementation specialized = scalar.specialize(BoundVariables.builder().build(), 2, new TypeRegistry(), null); assertFalse(specialized.getInstanceFactory().isPresent()); assertEquals(specialized.getArgumentProperty(0), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); assertEquals(specialized.getArgumentProperty(1), valueTypeArgumentProperty(USE_BOXED_TYPE)); }
@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 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"); }
public void testSimpleExplicitSpecializedAggregationParse() { Signature expectedSignature = new Signature( "explicit_specialized_aggregate", FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), parseTypeSignature("T"), ImmutableList.of(new TypeSignature(ARRAY, TypeSignatureParameter.of(parseTypeSignature("T")))), false); ParametricAggregation aggregation = parseFunctionDefinition(ExplicitSpecializedAggregationFunction.class); assertEquals(aggregation.getDescription(), "Simple explicit specialized aggregate"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations(); assertImplementationCount(implementations, 0, 1, 1); AggregationImplementation implementation1 = implementations.getSpecializedImplementations().get(0); assertTrue(implementation1.hasSpecializedTypeParameters()); assertFalse(implementation1.hasSpecializedTypeParameters()); List<AggregationMetadata.ParameterMetadata.ParameterType> expectedMetadataTypes = ImmutableList.of(AggregationMetadata.ParameterMetadata.ParameterType.STATE, AggregationMetadata.ParameterMetadata.ParameterType.INPUT_CHANNEL); assertTrue(implementation1.getInputParameterMetadataTypes().equals(expectedMetadataTypes)); AggregationImplementation implementation2 = implementations.getSpecializedImplementations().get(1); assertTrue(implementation2.hasSpecializedTypeParameters()); assertFalse(implementation2.hasSpecializedTypeParameters()); assertTrue(implementation2.getInputParameterMetadataTypes().equals(expectedMetadataTypes)); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().setTypeVariable("T", DoubleType.DOUBLE).build(), 1, new TypeRegistry(), null); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertTrue(specialized.isDecomposable()); assertEquals(specialized.name(), "implicit_specialized_aggregate"); }
@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 testBindParameters() { BoundVariables boundVariables = BoundVariables.builder() .setTypeVariable("T1", DOUBLE) .setTypeVariable("T2", BIGINT) .setTypeVariable("T3", DecimalType.createDecimalType(5, 3)) .setLongVariable("p", 1L) .setLongVariable("s", 2L) .build(); assertThat("bigint", boundVariables, "bigint"); assertThat("T1", boundVariables, "double"); assertThat("T2", boundVariables, "bigint"); assertThat("array(T1)", boundVariables, "array(double)"); assertThat("array(T3)", boundVariables, "array(decimal(5,3))"); assertThat("array<T1>", boundVariables, "array(double)"); assertThat("map(T1,T2)", boundVariables, "map(double,bigint)"); assertThat("map<T1,T2>", boundVariables, "map(double,bigint)"); assertThat("bla(T1,42,T2)", boundVariables, "bla(double,42,bigint)"); assertThat("varchar(p)", boundVariables, "varchar(1)"); assertThat("char(p)", boundVariables, "char(1)"); assertThat("decimal(p,s)", boundVariables, "decimal(1,2)"); assertThat("array(decimal(p,s))", boundVariables, "array(decimal(1,2))"); assertBindVariablesFails("T1(bigint)", boundVariables, "Unbounded parameters can not have parameters"); }