@Override public int hashCode() { return Objects.hash(function.getSignature(), boundVariables, arity); } }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } SpecializedFunctionKey that = (SpecializedFunctionKey) o; return Objects.equals(boundVariables, that.boundVariables) && Objects.equals(function.getSignature(), that.function.getSignature()) && arity == that.arity; }
public final synchronized void addFunctions(List<? extends SqlFunction> functions) { for (SqlFunction function : functions) { for (SqlFunction existingFunction : this.functions.list()) { checkArgument(!function.getSignature().equals(existingFunction.getSignature()), "Function already registered: %s", function.getSignature()); } } this.functions = new FunctionMap(this.functions, functions); }
private static String getFunctionType(SqlFunction function) { FunctionKind kind = function.getSignature().getKind(); switch (kind) { case AGGREGATE: return "aggregate"; case WINDOW: return "window"; case SCALAR: return "scalar"; } throw new IllegalArgumentException("Unsupported function kind: " + kind); }
@VisibleForTesting public List<SqlFunction> listOperators() { Set<String> operatorNames = Arrays.asList(OperatorType.values()).stream() .map(FunctionRegistry::mangleOperatorName) .collect(toImmutableSet()); return functions.list().stream() .filter(function -> operatorNames.contains(function.getSignature().getName())) .collect(toImmutableList()); }
public boolean isAggregationFunction(QualifiedName name) { return Iterables.any(functions.get(name), function -> function.getSignature().getKind() == AGGREGATE); }
private List<ApplicableFunction> identifyApplicableFunctions(Collection<SqlFunction> candidates, List<TypeSignatureProvider> actualParameters, boolean allowCoercion) { ImmutableList.Builder<ApplicableFunction> applicableFunctions = ImmutableList.builder(); for (SqlFunction function : candidates) { Signature declaredSignature = function.getSignature(); Optional<Signature> boundSignature = new SignatureBinder(typeManager, declaredSignature, allowCoercion) .bind(actualParameters); if (boundSignature.isPresent()) { applicableFunctions.add(new ApplicableFunction(declaredSignature, boundSignature.get())); } } return applicableFunctions.build(); }
public FunctionMap(FunctionMap map, Iterable<? extends SqlFunction> functions) { this.functions = ImmutableListMultimap.<QualifiedName, SqlFunction>builder() .putAll(map.functions) .putAll(Multimaps.index(functions, function -> QualifiedName.of(function.getSignature().getName()))) .build(); // Make sure all functions with the same name are aggregations or none of them are for (Map.Entry<QualifiedName, Collection<SqlFunction>> entry : this.functions.asMap().entrySet()) { Collection<SqlFunction> values = entry.getValue(); long aggregations = values.stream() .map(function -> function.getSignature().getKind()) .filter(kind -> kind == AGGREGATE) .count(); checkState(aggregations == 0 || aggregations == values.size(), "'%s' is both an aggregation and a scalar function", entry.getKey()); } }
.filter(function -> function.getSignature().getTypeVariableConstraints().isEmpty()) .collect(Collectors.toList()); .filter(function -> !function.getSignature().getTypeVariableConstraints().isEmpty()) .collect(Collectors.toList()); expectedParameters.add(format("%s(%s) %s", name, Joiner.on(", ").join(function.getSignature().getArgumentTypes()), Joiner.on(", ").join(function.getSignature().getTypeVariableConstraints())));
for (SqlFunction function : metadata.listFunctions()) { rows.add(row( new StringLiteral(function.getSignature().getName()), new StringLiteral(function.getSignature().getReturnType().toString()), new StringLiteral(Joiner.on(", ").join(function.getSignature().getArgumentTypes())), new StringLiteral(getFunctionType(function)), function.isDeterministic() ? TRUE_LITERAL : FALSE_LITERAL,
@Test public void testListingHiddenFunctions() { TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); List<SqlFunction> functions = registry.list(); List<String> names = transform(functions, input -> input.getSignature().getName()); assertTrue(names.contains("length"), "Expected function names " + names + " to contain 'length'"); assertTrue(names.contains("stddev"), "Expected function names " + names + " to contain 'stddev'"); assertTrue(names.contains("rank"), "Expected function names " + names + " to contain 'rank'"); assertFalse(names.contains("like"), "Expected function names " + names + " not to contain 'like'"); assertFalse(names.contains("$internal$sum_data_size_for_stats"), "Expected function names " + names + " not to contain '$internal$sum_data_size_for_stats'"); assertFalse(names.contains("$internal$max_data_size_for_stats"), "Expected function names " + names + " not to contain '$internal$max_data_size_for_stats'"); }
List<TypeSignatureProvider> argumentTypeSignatureProviders = fromTypeSignatures(signature.getArgumentTypes()); for (SqlFunction candidate : candidates) { Optional<BoundVariables> boundVariables = new SignatureBinder(typeManager, candidate.getSignature(), false) .bindVariables(argumentTypeSignatureProviders, returnType); if (boundVariables.isPresent()) { SignatureBinder binder = new SignatureBinder(typeManager, candidate.getSignature(), true); Optional<BoundVariables> boundVariables = binder.bindVariables(argumentTypeSignatureProviders, returnType); if (!boundVariables.isPresent()) { continue; Signature boundSignature = applyBoundVariables(candidate.getSignature(), boundVariables.get(), argumentTypes.size());
@Test public void testExactMatchBeforeCoercion() { TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); boolean foundOperator = false; for (SqlFunction function : registry.listOperators()) { OperatorType operatorType = unmangleOperator(function.getSignature().getName()); if (operatorType == OperatorType.CAST || operatorType == OperatorType.SATURATED_FLOOR_CAST) { continue; } if (!function.getSignature().getTypeVariableConstraints().isEmpty()) { continue; } if (function.getSignature().getArgumentTypes().stream().anyMatch(TypeSignature::isCalculated)) { continue; } Signature exactOperator = registry.resolveOperator(operatorType, resolveTypes(function.getSignature().getArgumentTypes(), typeManager)); assertEquals(exactOperator, function.getSignature()); foundOperator = true; } assertTrue(foundOperator); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "\\QFunction already registered: custom_add(bigint,bigint):bigint\\E") public void testDuplicateFunctions() { List<SqlFunction> functions = new FunctionListBuilder() .scalars(CustomFunctions.class) .getFunctions() .stream() .filter(input -> input.getSignature().getName().equals("custom_add")) .collect(toImmutableList()); TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), new FeaturesConfig()); registry.addFunctions(functions); registry.addFunctions(functions); }
return supplier(key.getFunction().getSignature(), specializedAggregationCache.getUnchecked(key));
@Override public int hashCode() { return Objects.hash(function.getSignature(), boundTypeParameters, arity); } }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } SpecializedFunctionKey that = (SpecializedFunctionKey) o; return Objects.equals(arity, that.arity) && Objects.equals(boundTypeParameters, that.boundTypeParameters) && Objects.equals(function.getSignature(), that.function.getSignature()); }
public final synchronized void addFunctions(List<? extends SqlFunction> functions) { for (SqlFunction function : functions) { for (SqlFunction existingFunction : this.functions.list()) { checkArgument(!function.getSignature().equals(existingFunction.getSignature()), "Function already registered: %s", function.getSignature()); } } this.functions = new FunctionMap(this.functions, functions); }
@VisibleForTesting public List<SqlFunction> listOperators() { Set<String> operatorNames = Arrays.asList(OperatorType.values()).stream() .map(FunctionRegistry::mangleOperatorName) .collect(toImmutableSet()); return functions.list().stream() .filter(function -> operatorNames.contains(function.getSignature().getName())) .collect(toImmutableList()); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "\\QFunction already registered: custom_add(bigint,bigint):bigint\\E") public void testDuplicateFunctions() { List<SqlFunction> functions = new FunctionListBuilder(new TypeRegistry()) .scalar(CustomFunctions.class) .getFunctions() .stream() .filter(input -> input.getSignature().getName().equals("custom_add")) .collect(toImmutableList()); TypeRegistry typeManager = new TypeRegistry(); FunctionRegistry registry = new FunctionRegistry(typeManager, new BlockEncodingManager(typeManager), true); registry.addFunctions(functions); registry.addFunctions(functions); }