{"record":{"id":"77164cae5deb173d","repo":"prestodb/presto","slug":"not-supported-77164c","errorCode":"NOT_SUPPORTED","errorMessage":"Invalid statement type for prepared statement: ","messagePattern":"Invalid statement type for prepared statement: ","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/execution/PrepareTask.java","lineNumber":67,"sourceCode":"    @Override\n    public String getName()\n    {\n        return \"PREPARE\";\n    }\n\n    @Override\n    public String explain(Prepare statement, List<Expression> parameters)\n    {\n        return \"PREPARE \" + statement.getName();\n    }\n\n    @Override\n    public ListenableFuture<?> execute(Prepare prepare, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine queryStateMachine, List<Expression> parameters, String query)\n    {\n        Statement statement = prepare.getStatement();\n        if ((statement instanceof Prepare) || (statement instanceof Execute) || (statement instanceof Deallocate)) {\n            String type = statement.getClass().getSimpleName().toUpperCase(ENGLISH);\n            throw new PrestoException(NOT_SUPPORTED, \"Invalid statement type for prepared statement: \" + type);\n        }\n\n        String sql = getFormattedSql(statement, sqlParser, Optional.empty());\n        queryStateMachine.addPreparedStatement(prepare.getName().getValue(), sql);\n        return immediateFuture(null);\n    }\n}\n","sourceCodeStart":49,"sourceCodeEnd":75,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/execution/PrepareTask.java#L49-L75","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nPREPARE my_stmt FROM EXECUTE other_stmt;\n// after\nEXECUTE other_stmt; -- cannot be prepared\nPREPARE my_stmt FROM SELECT * FROM t WHERE id = ?;","handlingStrategy":"validation","validationCode":"if (sql.trim().toUpperCase(Locale.ENGLISH).startsWith(\"PREPARE \")\n    || sql.trim().toUpperCase(Locale.ENGLISH).startsWith(\"EXECUTE \")\n    || sql.trim().toUpperCase(Locale.ENGLISH).startsWith(\"DEALLOCATE \")) {\n    // do not wrap in PREPARE; execute directly\n}","typeGuard":null,"tryCatchPattern":"try { prepare(name, sql); } catch (PrestoException e) { if (e.getErrorCode().getCode() == StandardErrorCode.NOT_SUPPORTED.toErrorCodeCode()) { /* run statement directly instead */ } throw e; }","preventionTips":["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"],"tags":["presto","sql","prepared-statement","not-supported"],"backgroundTag":"unsupported-statement-type","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}