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

  1. Read the Reader into a String in application code and execute a parameterized UPDATE with setString.
  2. Use bulk SQL loading (INSERT INTO ... SELECT from staged text data) instead of per-row cursor updates.
  3. Request CONCUR_READ_ONLY so cursor-update paths are not relied upon.
  4. 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

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.