prestodb/presto · error

JDBC_ERROR

JDBC_ERROR

Error message

Failed to execute query. ${e.message}

What it means

ExecuteProcedure's EXECUTE procedure runs an arbitrary SQL statement (typically DDL/DML like TRUNCATE or COMMENT) directly on the underlying database connection via statement.executeUpdate. If the database throws a SQLException, it is rethrown as a PrestoException with code JDBC_ERROR and the database's own message. This indicates the remote database rejected the query.

Source

Thrown at presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/procedure/ExecuteProcedure.java:73

    public void execute(ConnectorSession session, String query)
    {
        try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(getClass().getClassLoader())) {
            doExecute(session, query);
        }
    }

    private void doExecute(ConnectorSession session, String query)
    {
        try (Connection connection = jdbcClient.getConnection(session, JdbcIdentity.from(session), (JdbcSplit) null)) {
            connection.setReadOnly(false);
            try (Statement statement = connection.createStatement()) {
                //noinspection SqlSourceToSinkFlow
                statement.executeUpdate(query);
            }
        }
        catch (SQLException e) {
            throw new PrestoException(JDBC_ERROR, "Failed to execute query. " + firstNonNull(e.getMessage(), e), e);
        }
    }

    @Override
    public Procedure get()
    {
        return new Procedure(
                "system",
                "execute",
                ImmutableList.of(new Argument("QUERY", VARCHAR)),
                EXECUTE.bindTo(this));
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Read the wrapped SQLException message (the cause) to get the database-specific reason
  2. Run the query directly in the target database's client to confirm and fix syntax
  3. Check the connected user's privileges for the operation (DDL, TRUNCATE, etc.)
  4. Qualify table/schema names the way the underlying database expects and use its dialect's syntax

Example fix

// before
CALL jdbc.system.execute_query('TRUNCATE TABLE mytable');
// after (fully qualified, DB-correct syntax and adequate privileges)
CALL jdbc.system.execute_query('TRUNCATE TABLE my_schema.my_table');
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the SQL before executing via the procedure:
// ensure statement is one the backend DB supports, e.g.
String q = query.trim().toLowerCase();
if (q.contains("/*presto-only") || !isKnownBackendStatement(q)) {
    throw new IllegalArgumentException("Query may not be valid for the underlying database dialect");
}

Try / catch

try {
    CALL jdbc.system.execute(query => :sql);
} catch (PrestoException e) {
    if ("JDBC_ERROR".equals(e.getErrorCode().getName())) {
        Throwable cause = e.getCause(); // SQLException from backend; log cause.getMessage() for DB-specific detail
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Invoking system.procedure execute(query => '...') on a JDBC catalog where the query is invalid SQL for the target DB, lacks privileges, references missing objects, violates constraints, or the connection is in a bad state.

Common situations: Typing Presto/MySQL-flavored syntax for a different backend DB; executing DDL without DBA privileges; TRUNCATE on a table with foreign keys; quoting/identifier differences between Presto and the underlying database.

Related errors


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