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
- Remove the outer PREPARE and run EXECUTE/DEALLOCATE directly
- Filter session-control statements out of the input before wrapping in PREPARE
- 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
- Parse/classify statements before wrapping them in PREPARE
- Block PREPARE/EXECUTE/DEALLOCATE in generic prepare-anything pipelines
- Emit prepared statements only for SELECT/DML statements
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.