@Override public SolverReturnStatus update(BoundVariables.Builder bindings) { if (!bindings.containsTypeVariable(typeParameter)) { if (!satisfiesConstraints(actualType)) { return SolverReturnStatus.UNSOLVABLE; } bindings.setTypeVariable(typeParameter, actualType); return SolverReturnStatus.CHANGED; } Type originalType = bindings.getTypeVariable(typeParameter); Optional<Type> commonSuperType = typeManager.getCommonSuperType(originalType, actualType); if (!commonSuperType.isPresent()) { return SolverReturnStatus.UNSOLVABLE; } if (!satisfiesConstraints(commonSuperType.get())) { // This check must not be skipped even if commonSuperType is equal to originalType return SolverReturnStatus.UNSOLVABLE; } if (commonSuperType.get().equals(originalType)) { return SolverReturnStatus.UNCHANGED_SATISFIED; } bindings.setTypeVariable(typeParameter, commonSuperType.get()); return SolverReturnStatus.CHANGED; }
@Override public SolverReturnStatus update(BoundVariables.Builder bindings) { if (!bindings.containsTypeVariable(typeParameter)) { if (!satisfiesConstraints(actualType)) { return SolverReturnStatus.UNSOLVABLE; } bindings.setTypeVariable(typeParameter, actualType); return SolverReturnStatus.CHANGED; } Type originalType = bindings.getTypeVariable(typeParameter); Optional<Type> commonSuperType = typeManager.getCommonSuperType(originalType, actualType); if (!commonSuperType.isPresent()) { return SolverReturnStatus.UNSOLVABLE; } if (!satisfiesConstraints(commonSuperType.get())) { // This check must not be skipped even if commonSuperType is equal to originalType return SolverReturnStatus.UNSOLVABLE; } if (commonSuperType.get().equals(originalType)) { return SolverReturnStatus.UNCHANGED_SATISFIED; } bindings.setTypeVariable(typeParameter, commonSuperType.get()); return SolverReturnStatus.CHANGED; }
magicLiteralFunction, BoundVariables.builder() .setTypeVariable("T", parameterType) .setTypeVariable("R", type) .build(), 1);
.boundTo("integer", "function(integer,varchar)", "function(varchar,double)") .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .setTypeVariable("U", VARCHAR) .setTypeVariable("V", DOUBLE) .build()); assertThat(applyTwice) new TypeSignatureProvider(functionArgumentTypes -> TypeSignature.parseTypeSignature("function(varchar,double)"))) .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .setTypeVariable("U", VARCHAR) .setTypeVariable("V", DOUBLE) .build()); assertThat(applyTwice) .boundTo("array(integer)", "function(integer, array(integer))") .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .build()); .boundTo("integer", "function(integer, integer)", "function(integer, integer)", "function(integer, integer)") .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .build()); assertThat(varargApply) .withCoercion() .produces(BoundVariables.builder()
.boundTo("integer", "function(integer,varchar)", "function(varchar,double)") .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .setTypeVariable("U", VARCHAR) .setTypeVariable("V", DOUBLE) .build()); assertThat(applyTwice) new TypeSignatureProvider(functionArgumentTypes -> TypeSignature.parseTypeSignature("function(varchar,double)"))) .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .setTypeVariable("U", VARCHAR) .setTypeVariable("V", DOUBLE) .build()); assertThat(applyTwice) .boundTo("array(integer)", "function(integer, array(integer))") .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .build()); .boundTo("integer", "function(integer, integer)", "function(integer, integer)", "function(integer, integer)") .produces(BoundVariables.builder() .setTypeVariable("T", INTEGER) .build()); assertThat(varargApply) .withCoercion() .produces(BoundVariables.builder()
magicLiteralFunction, BoundVariables.builder() .setTypeVariable("T", parameterType) .setTypeVariable("R", type) .build(), 1);
BoundVariables.builder().setTypeVariable("T", DoubleType.DOUBLE).build(), 1, new TypeRegistry(),
BoundVariables.builder().setTypeVariable("T1", DoubleType.DOUBLE).setTypeVariable("T2", DoubleType.DOUBLE).build(), 1, new TypeRegistry(),
InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().setTypeVariable("T", DoubleType.DOUBLE).build(), 1, typeRegistry, functionRegistry); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertTrue(specialized.isDecomposable());
BoundVariables.builder().setTypeVariable("T", DoubleType.DOUBLE).build(), 1, new TypeRegistry(),
InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().setTypeVariable("T", DoubleType.DOUBLE).build(), 1, typeRegistry, functionRegistry); assertEquals(specialized.getFinalType(), DoubleType.DOUBLE); assertTrue(specialized.isDecomposable());
BoundVariables.builder().setTypeVariable("T1", DoubleType.DOUBLE).setTypeVariable("T2", DoubleType.DOUBLE).build(), 1, new TypeRegistry(),
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"); }
public void testSimpleImplicitSpecializedAggregationParse() { Signature expectedSignature = new Signature( "implicit_specialized_aggregate", FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), parseTypeSignature("T"), ImmutableList.of(new TypeSignature(ARRAY, TypeSignatureParameter.of(parseTypeSignature("T"))), parseTypeSignature("T")), false); ParametricAggregation aggregation = parseFunctionDefinition(ImplicitSpecializedAggregationFunction.class); assertEquals(aggregation.getDescription(), "Simple implicit specialized aggregate"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations(); assertImplementationCount(implementations, 0, 0, 2); 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, 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"); }
public void testSimpleImplicitSpecializedAggregationParse() { Signature expectedSignature = new Signature( "implicit_specialized_aggregate", FunctionKind.AGGREGATE, ImmutableList.of(typeVariable("T")), ImmutableList.of(), parseTypeSignature("T"), ImmutableList.of(new TypeSignature(ARRAY, TypeSignatureParameter.of(parseTypeSignature("T"))), parseTypeSignature("T")), false); ParametricAggregation aggregation = parseFunctionDefinition(ImplicitSpecializedAggregationFunction.class); assertEquals(aggregation.getDescription(), "Simple implicit specialized aggregate"); assertTrue(aggregation.isDeterministic()); assertEquals(aggregation.getSignature(), expectedSignature); ParametricImplementationsGroup<AggregationImplementation> implementations = aggregation.getImplementations(); assertImplementationCount(implementations, 0, 0, 2); 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, 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 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"); }
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 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"); }