use of com.facebook.presto.spi.function.Signature in project presto by prestodb.
the class BuiltInTypeAndFunctionNamespaceManager method getAggregateFunctionImplementation.
public InternalAggregationFunction getAggregateFunctionImplementation(FunctionHandle functionHandle) {
checkArgument(functionHandle instanceof BuiltInFunctionHandle, "Expect BuiltInFunctionHandle");
Signature signature = ((BuiltInFunctionHandle) functionHandle).getSignature();
checkArgument(signature.getKind() == AGGREGATE, "%s is not an aggregate function", signature);
checkArgument(signature.getTypeVariableConstraints().isEmpty(), "%s has unbound type parameters", signature);
try {
return specializedAggregationCache.getUnchecked(getSpecializedFunctionKey(signature));
} catch (UncheckedExecutionException e) {
throwIfInstanceOf(e.getCause(), PrestoException.class);
throw e;
}
}
use of com.facebook.presto.spi.function.Signature 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.Signature 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.Signature in project presto by prestodb.
the class FunctionAndTypeManager method lookupFunction.
/**
* Lookup up a function with name and fully bound types. This can only be used for builtin functions. {@link #resolveFunction(Optional, Optional, QualifiedObjectName, List)}
* should be used for dynamically registered functions.
*
* @throws PrestoException if function could not be found
*/
public FunctionHandle lookupFunction(String name, List<TypeSignatureProvider> parameterTypes) {
QualifiedObjectName functionName = qualifyObjectName(QualifiedName.of(name));
if (parameterTypes.stream().noneMatch(TypeSignatureProvider::hasDependency)) {
return lookupCachedFunction(functionName, parameterTypes);
}
Collection<? extends SqlFunction> candidates = builtInTypeAndFunctionNamespaceManager.getFunctions(Optional.empty(), functionName);
Optional<Signature> match = functionSignatureMatcher.match(candidates, parameterTypes, false);
if (!match.isPresent()) {
throw new PrestoException(FUNCTION_NOT_FOUND, constructFunctionNotFoundErrorMessage(functionName, parameterTypes, candidates));
}
return builtInTypeAndFunctionNamespaceManager.getFunctionHandle(Optional.empty(), match.get());
}
use of com.facebook.presto.spi.function.Signature in project presto by prestodb.
the class FunctionSignatureMatcher method returnsNullOnGivenInputTypes.
private static boolean returnsNullOnGivenInputTypes(ApplicableFunction applicableFunction, List<Type> parameterTypes) {
Signature boundSignature = applicableFunction.getBoundSignature();
FunctionKind functionKind = boundSignature.getKind();
// Window and Aggregation functions have fixed semantic where NULL values are always skipped
if (functionKind != SCALAR) {
return true;
}
for (int i = 0; i < parameterTypes.size(); i++) {
Type parameterType = parameterTypes.get(i);
if (parameterType.equals(UNKNOWN)) {
// to SQL spec. So there is a loss of precision here.
if (applicableFunction.isCalledOnNullInput()) {
return false;
}
}
}
return true;
}
Aggregations