prestodb/presto · error · SQLFeatureNotSupportedException
Result set holdability must be HOLD_CURSORS_OVER_COMMIT
Error message
Result set holdability must be HOLD_CURSORS_OVER_COMMIT
What it means
PrestoConnection.checkHoldability() throws SQLFeatureNotSupportedException when the requested resultSetHoldability is not ResultSet.HOLD_CURSORS_OVER_COMMIT. Presto has no cross-transaction cursor semantics; the driver only supports holdable cursors, rejecting CLOSE_CURSORS_AT_COMMIT in createStatement/prepareStatement/createStatement overload with holdability.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoConnection.java:905
}
}
private static void checkResultSet(int resultSetType, int resultSetConcurrency)
throws SQLFeatureNotSupportedException
{
if (resultSetType != ResultSet.TYPE_FORWARD_ONLY) {
throw new SQLFeatureNotSupportedException("Result set type must be TYPE_FORWARD_ONLY");
}
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {
throw new SQLFeatureNotSupportedException("Result set concurrency must be CONCUR_READ_ONLY");
}
}
private static void checkHoldability(int resultSetHoldability)
throws SQLFeatureNotSupportedException
{
if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
throw new SQLFeatureNotSupportedException("Result set holdability must be HOLD_CURSORS_OVER_COMMIT");
}
}
private static String getIsolationLevel(int level)
throws SQLException
{
switch (level) {
case TRANSACTION_READ_UNCOMMITTED:
return "READ UNCOMMITTED";
case TRANSACTION_READ_COMMITTED:
return "READ COMMITTED";
case TRANSACTION_REPEATABLE_READ:
return "REPEATABLE READ";
case TRANSACTION_SERIALIZABLE:
return "SERIALIZABLE";
}
throw new SQLException("Invalid transaction isolation level: " + level);
}View on GitHub (pinned to 55bb57d202)
Solutions
- Pass ResultSet.HOLD_CURSORS_OVER_COMMIT as the holdability argument
- Do not call setHoldability with CLOSE_CURSORS_AT_COMMIT; omit it and use driver defaults
- Restructure commit/rollback logic so it does not depend on cursors closing at commit
Example fix
// before
Statement stmt = conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
ResultSet.CLOSE_CURSORS_AT_COMMIT);
// after
Statement stmt = conn.createStatement(
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
ResultSet.HOLD_CURSORS_OVER_COMMIT); Defensive patterns
Strategy: validation
Validate before calling
if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
holdability = ResultSet.HOLD_CURSORS_OVER_COMMIT; // only supported value
} Try / catch
try {
stmt = conn.createStatement(type, concurrency, holdability);
} catch (SQLFeatureNotSupportedException e) {
stmt = conn.createStatement();
} Prevention
- Avoid setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT) on Presto connections
- Use the 3-arg createStatement overloads only when holdability is HOLD_CURSORS_OVER_COMMIT
- Do not carry transactional cursor semantics from OLTP drivers into Presto
When it happens
Trigger: createStatement(type, concurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT); prepareStatement(sql, type, concurrency, ResultSet.CLOSE_CURSORS_AT_COMMIT); setHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT) on the connection.
Common situations: Transaction-management code ported from DB2/Oracle that pins cursor behavior to commit; frameworks that set holdability explicitly for rollback safety.
Related errors
- Result set type must be TYPE_FORWARD_ONLY
- Result set concurrency must be CONCUR_READ_ONLY
- Invalid transaction isolation level:
- privileges not supported
- row identifiers not supported
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/83beef533a720755.
Report an issue: GitHub.