prestodb/presto · error · PrestoException

ALREADY_EXISTS

ALREADY_EXISTS

Error message

Session function %s has already been defined

What it means

Thrown by QueryStateMachine.addSessionFunction when a session function with the same SqlFunctionId signature is already registered for the query session. Presto sessions allow only one definition per function signature; re-registering the same signature is treated as a conflict. The check consults both the session's existing functions and the set of functions added during this query.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/QueryStateMachine.java:744

    }

    public void removePreparedStatement(String key)
    {
        requireNonNull(key, "key is null");

        if (!session.getPreparedStatements().containsKey(key)) {
            throw new PrestoException(NOT_FOUND, "Prepared statement not found: " + key);
        }
        deallocatedPreparedStatements.add(key);
    }

    public void addSessionFunction(SqlFunctionId signature, SqlInvokedFunction function)
    {
        requireNonNull(signature, "signature is null");
        requireNonNull(function, "function is null");

        if (session.getSessionFunctions().containsKey(signature) || addedSessionFunctions.putIfAbsent(signature, function) != null) {
            throw new PrestoException(ALREADY_EXISTS, format("Session function %s has already been defined", signature));
        }
    }

    public void removeSessionFunction(SqlFunctionId signature, boolean suppressNotFoundException)
    {
        requireNonNull(signature, "signature is null");

        if (!session.getSessionFunctions().containsKey(signature)) {
            if (!suppressNotFoundException) {
                throw new PrestoException(NOT_FOUND, format("Session function %s not found", signature.getFunctionName()));
            }
        }
        else {
            removedSessionFunctions.add(signature);
        }
    }

    public void setStartedTransactionId(TransactionId startedTransactionId)

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Drop the existing session function first via removeSessionFunction (or DROP FUNCTION in SQL) before re-adding it
  2. Use a different function signature (distinct parameter types) if the intent is an overload
  3. Check session.getSessionFunctions().containsKey(signature) before calling addSessionFunction
  4. Guard against concurrent registration by ensuring a single thread owns session function management

Example fix

// before
stateMachine.addSessionFunction(signature, function); // throws if already defined
// after
if (!session.getSessionFunctions().containsKey(signature)) {
    stateMachine.addSessionFunction(signature, function);
} else {
    stateMachine.removeSessionFunction(signature, false);
    stateMachine.addSessionFunction(signature, function);
}
Defensive patterns

Strategy: validation

Validate before calling

if (session.getSessionFunctions().containsKey(signature)) {
    // already defined — skip or drop-then-add
    return;
}
stateMachine.addSessionFunction(signature, function);

Try / catch

try {
    stateMachine.addSessionFunction(signature, function);
} catch (PrestoException e) {
    if (e.getErrorCode().getCode() == StandardErrorCode.ALREADY_EXISTS.getCode()) {
        stateMachine.removeSessionFunction(signature, true);
        stateMachine.addSessionFunction(signature, function);
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling addSessionFunction with a SqlFunctionId already present in session.getSessionFunctions() or already added via addedSessionFunctions (putIfAbsent returns non-null). Typically two ADD FUNCTION statements for the same signature in one session, or a concurrent registration race.

Common situations: Re-running an ADD FUNCTION SQL statement without DROP FUNCTION first; client retry re-sending the same session-function registration; two threads sharing a session registering the same function concurrently.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/58a178537cdda5b2. Report an issue: GitHub.