prestodb/presto · error · SQLFeatureNotSupportedException
updateCharacterStream
Error message
updateCharacterStream
What it means
PrestoResultSet.updateCharacterStream(int, Reader, int) always throws SQLFeatureNotSupportedException("updateCharacterStream"). The Presto JDBC driver offers read-only result sets; character-stream update methods are stubs that reject the call. Text data cannot be streamed into a row through the ResultSet cursor.
Source
Thrown at presto-jdbc/src/main/java/com/facebook/presto/jdbc/PrestoResultSet.java:886
@Override
public void updateAsciiStream(int columnIndex, InputStream x, int length)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateAsciiStream");
}
@Override
public void updateBinaryStream(int columnIndex, InputStream x, int length)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateBinaryStream");
}
@Override
public void updateCharacterStream(int columnIndex, Reader x, int length)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateCharacterStream");
}
@Override
public void updateObject(int columnIndex, Object x, int scaleOrLength)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateObject");
}
@Override
public void updateObject(int columnIndex, Object x)
throws SQLException
{
throw new SQLFeatureNotSupportedException("updateObject");
}
@Override
public void updateNull(String columnLabel)View on GitHub (pinned to 55bb57d202)
Solutions
- Read the Reader into a String in application code and execute a parameterized UPDATE with setString.
- Use bulk SQL loading (INSERT INTO ... SELECT from staged text data) instead of per-row cursor updates.
- Request CONCUR_READ_ONLY so cursor-update paths are not relied upon.
- Configure the ORM/persistence layer to treat the Presto connection as read-only.
Example fix
// before
rs.updateCharacterStream("body", reader, length);
rs.updateRow();
// after
String body = new BufferedReader(reader).lines().collect(Collectors.joining("\n"));
try (PreparedStatement ps = conn.prepareStatement("UPDATE docs SET body = ? WHERE id = ?")) {
ps.setString(1, body);
ps.setLong(2, id);
ps.executeUpdate();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (rs instanceof com.facebook.presto.jdbc.PrestoResultSet) {
// Presto: collect Reader into String, then UPDATE with setString
} Type guard
boolean allowsCharacterStreamUpdate(ResultSet rs) {
return !(rs instanceof com.facebook.presto.jdbc.PrestoResultSet);
} Try / catch
try {
rs.updateCharacterStream("body", reader, length);
rs.updateRow();
} catch (SQLFeatureNotSupportedException e) {
// materialize text and run parameterized UPDATE
} Prevention
- Materialize Reader content in the application before writing it with a PreparedStatement.
- Use staged-file ingestion plus INSERT INTO ... SELECT for bulk document loads.
- Create Presto statements with CONCUR_READ_ONLY.
- Grep codebases for updateCharacterStream/updateAsciiStream when migrating to Presto.
When it happens
Trigger: Calling updateCharacterStream(columnIndex, reader, length) (or label/length variants) on a PrestoResultSet, typically to fill a large VARCHAR column from a Reader before updateRow().
Common situations: CLOB-style code ported from Oracle/MySQL JDBC usage; document-ingestion jobs updating text columns row by row; persistence frameworks that stream character data through updatable result sets.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/67a4466cab4fa0c8.
Report an issue: GitHub.