prestodb/presto · error · SQLFeatureNotSupportedException
insertRow
Error message
insertRow
What it means
Presto's JDBC driver implements read-only, forward-only result sets. insertRow() is part of the JDBC updatable-resultset API, which Presto does not support, so the method unconditionally throws SQLFeatureNotSupportedException with the method name as the message. The driver exposes the method only to satisfy the java.sql.ResultSet interface.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoResultSet.java:1040
@Override
public void updateObject(String columnLabel, Object x, int scaleOrLength)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateObject");
}
@Override
public void updateObject(String columnLabel, Object x)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateObject");
}
@Override
public void insertRow()
throws SQLException
{
throw new SQLFeatureNotSupportedException("insertRow");
}
@Override
public void updateRow()
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateRow");
}
@Override
public void deleteRow()
throws SQLException
{
throw new SQLFeatureNotSupportedException("deleteRow");
}
@Override
public void refreshRow()View on GitHub (pinned to 55bb57d202)
Solutions
- Rewrite the code to INSERT via Statement/PreparedStatement (executeUpdate of an INSERT statement) instead of using ResultSet row insertion
- Check result-set capabilities first with resultSet.getConcurrency() == ResultSet.CONCUR_READ_ONLY and take the SQL path when updatable is unavailable
- If row writes through a cursor are required, use a database that supports updatable result sets; Presto results are read-only by design
Example fix
// before
ResultSet rs = stmt.executeQuery("SELECT * FROM orders");
rs.moveToInsertRow();
rs.updateString("status", "SHIPPED");
rs.insertRow();
// after
try (PreparedStatement ps = conn.prepareStatement(
"INSERT INTO orders (status) VALUES (?)")) {
ps.setString(1, "SHIPPED");
ps.executeUpdate();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
// use SQL INSERT instead of rs.insertRow()
} Type guard
static boolean supportsInsertRow(ResultSet rs) {
try {
return rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE;
} catch (SQLException e) {
return false;
}
} Try / catch
try {
rs.insertRow();
} catch (SQLFeatureNotSupportedException e) {
// fall back to PreparedStatement INSERT
} Prevention
- Treat Presto result sets as read-only by default
- Check getConcurrency() before any updatable-resultset API call
- Write data with PreparedStatement INSERT/UPDATE/DELETE statements
When it happens
Trigger: Calling insertRow() on a java.sql.ResultSet obtained from a PrestoConnection (via PrestoStatement), typically after moveToInsertRow() in code written for updatable result sets.
Common situations: Porting legacy MySQL/PostgreSQL JDBC code that writes rows through ResultSet objects to Presto; ORM or report-builder code that assumes a CONCUR_UPDATABLE result set; generic JDBC frameworks that probe updatable-resultset capabilities.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/6589e21350e7f61b.
Report an issue: GitHub.