prestodb/presto · error · SemanticException
AMBIGUOUS_FUNCTION_CALL
AMBIGUOUS_FUNCTION_CALL
Error message
AMBIGUOUS_FUNCTION_CALL semantic error with cause message
What it means
When function resolution is ambiguous — the argument types match more than one registered function signature — the registry's AMBIGUOUS_FUNCTION_CALL PrestoException is converted into a SemanticException AMBIGUOUS_FUNCTION_CALL tied to the FunctionCall node, preserving the cause message.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/ExpressionAnalyzer.java:1970
Optional<Map<SqlFunctionId, SqlInvokedFunction>> sessionFunctions,
Optional<TransactionId> transactionId,
FunctionCall node,
List<TypeSignatureProvider> argumentTypes,
FunctionAndTypeResolver functionAndTypeResolver)
{
try {
return functionAndTypeResolver.resolveFunction(
sessionFunctions,
transactionId,
functionAndTypeResolver.qualifyObjectName(node.getName()),
argumentTypes);
}
catch (PrestoException e) {
if (e.getErrorCode().getCode() == StandardErrorCode.FUNCTION_NOT_FOUND.toErrorCode().getCode()) {
throw new SemanticException(SemanticErrorCode.FUNCTION_NOT_FOUND, node, e.getMessage());
}
if (e.getErrorCode().getCode() == StandardErrorCode.AMBIGUOUS_FUNCTION_CALL.toErrorCode().getCode()) {
throw new SemanticException(SemanticErrorCode.AMBIGUOUS_FUNCTION_CALL, node, e.getMessage());
}
throw e;
}
}
public static Map<NodeRef<Expression>, Type> getExpressionTypes(
Session session,
Metadata metadata,
SqlParser sqlParser,
TypeProvider types,
Expression expression,
Map<NodeRef<Parameter>, Expression> parameters,
WarningCollector warningCollector)
{
return getExpressionTypes(session, metadata, sqlParser, types, expression, parameters, warningCollector, false);
}
public static Map<NodeRef<Expression>, Type> getExpressionTypes(View on GitHub (pinned to 55bb57d202)
Solutions
- CAST the ambiguous arguments so exactly one overload matches (e.g. CAST(NULL AS DOUBLE))
- Qualify the function name with its catalog/schema if a same-named function shadows the builtin
- Remove or rename a user-defined function creating the ambiguous overload
Example fix
// before SELECT greatest(NULL, NULL) // after SELECT greatest(CAST(NULL AS BIGINT), CAST(NULL AS BIGINT))
Defensive patterns
Strategy: try-catch
Validate before calling
// Check how many overloads match the intended signature SELECT function_name, argument_types FROM system.metadata.functions WHERE function_name = 'greatest'; -- >1 match on identical types = risk of ambiguity
Try / catch
try {
return session.execute(sql);
} catch (SemanticException e) {
if (e.getCode() == SemanticErrorCode.AMBIGUOUS_FUNCTION_CALL) {
throw new IllegalArgumentException("Ambiguous call — add explicit CASTs to select one overload: " + e.getMessage(), e);
}
throw e;
} Prevention
- CAST NULL and untyped literal arguments to concrete types
- Qualify function names to avoid builtin/UDF shadowing
- Avoid registering exact-duplicate signatures
When it happens
Trigger: Invoking an overloaded function with argument types (often NULLs or exact types matching multiple overloads) that do not uniquely select a signature during analysis.
Common situations: Passing NULL or untyped literals to overloaded functions (e.g. greatest(NULL, NULL)), calls that exactly match both a builtin and a catalog-registered function.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/9da85ab713d9e362.
Report an issue: GitHub.