use of com.facebook.presto.spi.function.SqlFunction in project presto by prestodb.
the class BuiltInTypeAndFunctionNamespaceManager method doGetSpecializedFunctionKey.
private SpecializedFunctionKey doGetSpecializedFunctionKey(Signature signature) {
Iterable<SqlFunction> candidates = getFunctions(null, signature.getName());
// search for exact match
Type returnType = functionAndTypeManager.getType(signature.getReturnType());
List<TypeSignatureProvider> argumentTypeSignatureProviders = fromTypeSignatures(signature.getArgumentTypes());
for (SqlFunction candidate : candidates) {
Optional<BoundVariables> boundVariables = new SignatureBinder(functionAndTypeManager, candidate.getSignature(), false).bindVariables(argumentTypeSignatureProviders, returnType);
if (boundVariables.isPresent()) {
return new SpecializedFunctionKey(candidate, boundVariables.get(), argumentTypeSignatureProviders.size());
}
}
// TODO: hack because there could be "type only" coercions (which aren't necessarily included as implicit casts),
// so do a second pass allowing "type only" coercions
List<Type> argumentTypes = resolveTypes(signature.getArgumentTypes(), functionAndTypeManager);
for (SqlFunction candidate : candidates) {
SignatureBinder binder = new SignatureBinder(functionAndTypeManager, candidate.getSignature(), true);
Optional<BoundVariables> boundVariables = binder.bindVariables(argumentTypeSignatureProviders, returnType);
if (!boundVariables.isPresent()) {
continue;
}
Signature boundSignature = applyBoundVariables(candidate.getSignature(), boundVariables.get(), argumentTypes.size());
if (!functionAndTypeManager.isTypeOnlyCoercion(functionAndTypeManager.getType(boundSignature.getReturnType()), returnType)) {
continue;
}
boolean nonTypeOnlyCoercion = false;
for (int i = 0; i < argumentTypes.size(); i++) {
Type expectedType = functionAndTypeManager.getType(boundSignature.getArgumentTypes().get(i));
if (!functionAndTypeManager.isTypeOnlyCoercion(argumentTypes.get(i), expectedType)) {
nonTypeOnlyCoercion = true;
break;
}
}
if (nonTypeOnlyCoercion) {
continue;
}
return new SpecializedFunctionKey(candidate, boundVariables.get(), argumentTypes.size());
}
// TODO: this is a hack and should be removed
if (signature.getNameSuffix().startsWith(MAGIC_LITERAL_FUNCTION_PREFIX)) {
List<TypeSignature> parameterTypes = signature.getArgumentTypes();
// extract type from function name
String typeName = signature.getNameSuffix().substring(MAGIC_LITERAL_FUNCTION_PREFIX.length());
// lookup the type
Type type = functionAndTypeManager.getType(parseTypeSignature(typeName));
// verify we have one parameter of the proper type
checkArgument(parameterTypes.size() == 1, "Expected one argument to literal function, but got %s", parameterTypes);
Type parameterType = functionAndTypeManager.getType(parameterTypes.get(0));
requireNonNull(parameterType, format("Type %s not found", parameterTypes.get(0)));
return new SpecializedFunctionKey(magicLiteralFunction, BoundVariables.builder().setTypeVariable("T", parameterType).setTypeVariable("R", type).build(), 1);
}
throw new PrestoException(FUNCTION_IMPLEMENTATION_MISSING, format("%s not found", signature));
}
use of com.facebook.presto.spi.function.SqlFunction in project presto by prestodb.
the class BuiltInTypeAndFunctionNamespaceManager method getFunctionMetadata.
@Override
public FunctionMetadata getFunctionMetadata(FunctionHandle functionHandle) {
checkArgument(functionHandle instanceof BuiltInFunctionHandle, "Expect BuiltInFunctionHandle");
Signature signature = ((BuiltInFunctionHandle) functionHandle).getSignature();
SpecializedFunctionKey functionKey;
try {
functionKey = specializedFunctionKeyCache.getUnchecked(signature);
} catch (UncheckedExecutionException e) {
throwIfInstanceOf(e.getCause(), PrestoException.class);
throw e;
}
SqlFunction function = functionKey.getFunction();
Optional<OperatorType> operatorType = tryGetOperatorType(signature.getName());
if (operatorType.isPresent()) {
return new FunctionMetadata(operatorType.get(), signature.getArgumentTypes(), signature.getReturnType(), signature.getKind(), JAVA, function.isDeterministic(), function.isCalledOnNullInput());
} else if (function instanceof SqlInvokedFunction) {
SqlInvokedFunction sqlFunction = (SqlInvokedFunction) function;
List<String> argumentNames = sqlFunction.getParameters().stream().map(Parameter::getName).collect(toImmutableList());
return new FunctionMetadata(signature.getName(), signature.getArgumentTypes(), argumentNames, signature.getReturnType(), signature.getKind(), sqlFunction.getRoutineCharacteristics().getLanguage(), SQL, function.isDeterministic(), function.isCalledOnNullInput(), sqlFunction.getVersion());
} else {
return new FunctionMetadata(signature.getName(), signature.getArgumentTypes(), signature.getReturnType(), signature.getKind(), JAVA, function.isDeterministic(), function.isCalledOnNullInput());
}
}
use of com.facebook.presto.spi.function.SqlFunction in project presto by prestodb.
the class FunctionSignatureMatcher method constructFunctionNotFoundErrorMessage.
static String constructFunctionNotFoundErrorMessage(QualifiedObjectName functionName, List<TypeSignatureProvider> parameterTypes, Collection<? extends SqlFunction> candidates) {
String name = toConciseFunctionName(functionName);
List<String> expectedParameters = new ArrayList<>();
for (SqlFunction function : candidates) {
expectedParameters.add(format("%s(%s) %s", name, Joiner.on(", ").join(function.getSignature().getArgumentTypes()), Joiner.on(", ").join(function.getSignature().getTypeVariableConstraints())));
}
String parameters = Joiner.on(", ").join(parameterTypes);
String message = format("Function %s not registered", name);
if (!expectedParameters.isEmpty()) {
String expected = Joiner.on(", ").join(expectedParameters);
message = format("Unexpected parameters (%s) for function %s. Expected: %s", parameters, name, expected);
}
return message;
}
use of com.facebook.presto.spi.function.SqlFunction in project presto by prestodb.
the class TestFunctionAndTypeManager method testConflictingScalarAggregation.
@Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "'presto.default.sum' is both an aggregation and a scalar function")
public void testConflictingScalarAggregation() {
List<SqlFunction> functions = new FunctionListBuilder().scalars(ScalarSum.class).getFunctions();
FunctionAndTypeManager functionAndTypeManager = createTestFunctionAndTypeManager();
functionAndTypeManager.registerBuiltInFunctions(functions);
}
use of com.facebook.presto.spi.function.SqlFunction in project presto by prestodb.
the class TestFunctionAndTypeManager method testListingVisibilityBetaFunctionsEnabled.
@Test
public void testListingVisibilityBetaFunctionsEnabled() {
Session session = testSessionBuilder().setCatalog("tpch").setSchema(TINY_SCHEMA_NAME).setSystemProperty(EXPERIMENTAL_FUNCTIONS_ENABLED, "true").build();
FunctionAndTypeManager functionAndTypeManager = createTestFunctionAndTypeManager();
List<SqlFunction> functions = functionAndTypeManager.listFunctions(session, Optional.empty(), Optional.empty());
List<String> names = transform(functions, input -> input.getSignature().getNameSuffix());
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'");
assertTrue(names.contains("tdigest_agg"), "Expected function names " + names + " to contain 'tdigest_agg'");
assertTrue(names.contains("quantiles_at_values"), "Expected function names " + names + " to contain 'tdigest_agg'");
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'");
}
Aggregations