prestodb/presto · error · PrestoException

NOT_SUPPORTED

NOT_SUPPORTED

Error message

Invalid statement type for prepared statement: 

What it means

Thrown by PrepareTask when the statement inside PREPARE is itself PREPARE, EXECUTE, or DEALLOCATE. Prepared statements cannot nest these session-control statements, so the task rejects them with NOT_SUPPORTED, embedding the uppercase statement class name in the message.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/PrepareTask.java:67

    @Override
    public String getName()
    {
        return "PREPARE";
    }

    @Override
    public String explain(Prepare statement, List<Expression> parameters)
    {
        return "PREPARE " + statement.getName();
    }

    @Override
    public ListenableFuture<?> execute(Prepare prepare, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine queryStateMachine, List<Expression> parameters, String query)
    {
        Statement statement = prepare.getStatement();
        if ((statement instanceof Prepare) || (statement instanceof Execute) || (statement instanceof Deallocate)) {
            String type = statement.getClass().getSimpleName().toUpperCase(ENGLISH);
            throw new PrestoException(NOT_SUPPORTED, "Invalid statement type for prepared statement: " + type);
        }

        String sql = getFormattedSql(statement, sqlParser, Optional.empty());
        queryStateMachine.addPreparedStatement(prepare.getName().getValue(), sql);
        return immediateFuture(null);
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Remove the outer PREPARE and run EXECUTE/DEALLOCATE directly
  2. Filter session-control statements out of the input before wrapping in PREPARE
  3. Validate the inner statement type in application code before sending PREPARE

Example fix

// before
PREPARE my_stmt FROM EXECUTE other_stmt;
// after
EXECUTE other_stmt; -- cannot be prepared
PREPARE my_stmt FROM SELECT * FROM t WHERE id = ?;
Defensive patterns

Strategy: validation

Validate before calling

if (sql.trim().toUpperCase(Locale.ENGLISH).startsWith("PREPARE ")
    || sql.trim().toUpperCase(Locale.ENGLISH).startsWith("EXECUTE ")
    || sql.trim().toUpperCase(Locale.ENGLISH).startsWith("DEALLOCATE ")) {
    // do not wrap in PREPARE; execute directly
}

Try / catch

try { prepare(name, sql); } catch (PrestoException e) { if (e.getErrorCode().getCode() == StandardErrorCode.NOT_SUPPORTED.toErrorCodeCode()) { /* run statement directly instead */ } throw e; }

Prevention

When it happens

Trigger: Executing `PREPARE p FROM PREPARE ...`, `PREPARE p FROM EXECUTE ...`, or `PREPARE p FROM DEALLOCATE ...`. The check is on the parsed statement's Java type (Prepare/Execute/Deallocate instanceof).

Common situations: Dynamically generated SQL that blindly wraps any incoming statement in PREPARE; user pasting multi-statement session scripts into a single PREPARE; ORM/query builders that always emit prepared statements.

Understand the failure class

Background: Presto NOT_SUPPORTED error: what "not supported" means and how to fix it — this error's family across 3 libraries.

Related errors


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