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

  1. CAST the ambiguous arguments so exactly one overload matches (e.g. CAST(NULL AS DOUBLE))
  2. Qualify the function name with its catalog/schema if a same-named function shadows the builtin
  3. 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

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.