apache/shardingsphere · error · IllegalArgumentException

Unsupported BLR type: %s

Error message

Unsupported BLR type: %s

What it means

SQLFeatureNotSupportedException thrown by updateClob(String, Reader) on SQL federation ResultSets. The label+Reader overload is final and throws in AbstractUnsupportedUpdateOperationSQLFederationResultSet, whose entire role is to enumerate the ResultSet update operations SQL federation does not support. Federated cursors are CONCUR_READ_ONLY, so streaming character data into a named column of the current row is refused before the Reader is read.

Source

Thrown at database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdParseBatchBlr.java:201

    
    private static int fixedLengthOf(final int blrType) {
        if (BlrConstants.blr_short == blrType) {
            return Short.BYTES;
        }
        if (BlrConstants.blr_long == blrType || BlrConstants.blr_float == blrType || BlrConstants.blr_sql_date == blrType || BlrConstants.blr_sql_time == blrType) {
            return Integer.BYTES;
        }
        if (BlrConstants.blr_int64 == blrType || BlrConstants.blr_double == blrType || BlrConstants.blr_d_float == blrType
                || BlrConstants.blr_quad == blrType || BlrConstants.blr_timestamp == blrType) {
            return Long.BYTES;
        }
        if (BlrConstants.blr_int128 == blrType) {
            return Long.BYTES * 2;
        }
        if (BlrConstants.blr_bool == blrType) {
            return Byte.BYTES;
        }
        throw new IllegalArgumentException("Unsupported BLR type: " + blrType);
    }
    
    private static int alignmentOf(final int blrType) {
        if (BlrConstants.blr_text == blrType || BlrConstants.blr_text2 == blrType || BlrConstants.blr_bool == blrType) {
            return 1;
        }
        if (BlrConstants.blr_varying == blrType || BlrConstants.blr_varying2 == blrType || BlrConstants.blr_short == blrType) {
            return Short.BYTES;
        }
        if (BlrConstants.blr_int64 == blrType || BlrConstants.blr_double == blrType || BlrConstants.blr_d_float == blrType) {
            return Long.BYTES;
        }
        return Integer.BYTES;
    }
    
    private static int alignTo(final int value, final int alignment) {
        return value + alignment - 1 & ~(alignment - 1);
    }

View on GitHub (pinned to e952770a21)

Solutions

  1. Use an UPDATE statement with ps.setCharacterStream bound in SQL by column name instead of the cursor API
  2. Close the Reader in the caller after the failed/succeeded call; the federation path never reads it
  3. Probe rs.getConcurrency() before entering edit flows and use DML when CONCUR_READ_ONLY
  4. Avoid federation for editable result sets by adjusting the query or federation configuration

Example fix

// before
rs.updateClob("body", stringReader); // SQLFeatureNotSupportedException

// after
try (PreparedStatement ps = conn.prepareStatement("UPDATE docs SET body = ? WHERE id = ?")) {
    ps.setCharacterStream(1, stringReader);
    ps.setLong(2, rs.getLong("id"));
    ps.executeUpdate();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (rs.getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
    // label+Reader CLOB write unsupported: use UPDATE + setCharacterStream
}

Try / catch

try {
    rs.updateClob("body", reader);
} catch (SQLFeatureNotSupportedException e) {
    // federation cursor read-only; emit UPDATE DML and manage reader lifecycle
}

Prevention

When it happens

Trigger: Calling rs.updateClob("body", reader) on a federated ResultSet and then rs.updateRow(). Seen in label-based writers that pipe a Reader of text into a CLOB column during row iteration.

Common situations: Report/document generation writing output back to a CLOB in place; migration to ShardingSphere JDBC or proxy where federation now serves the query; generic persistence layers exposing the full JDBC update API to application code.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/d2f98b592e65713a. Report an issue: GitHub.