apache/shardingsphere · error · SQLFeatureNotSupportedException

updateBigDecimal

Error message

updateBigDecimal

What it means

AbstractUnsupportedUpdateOperationSQLFederationResultSet defines the update contract for every SQL federation ResultSet in ShardingSphere: each updateXxx method unconditionally throws SQLFeatureNotSupportedException, with the message naming the method ('updateBigDecimal'). Federated results are in-memory computed rows without an updatable cursor, so BigDecimal writes by column index always fail fast rather than silently no-op.

Source

Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedUpdateOperationSQLFederationResultSet.java:124

    
    @Override
    public final void updateFloat(final String columnLabel, final float x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateFloat");
    }
    
    @Override
    public final void updateDouble(final int columnIndex, final double x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateDouble");
    }
    
    @Override
    public final void updateDouble(final String columnLabel, final double x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateDouble");
    }
    
    @Override
    public final void updateBigDecimal(final int columnIndex, final BigDecimal x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateBigDecimal");
    }
    
    @Override
    public final void updateBigDecimal(final String columnLabel, final BigDecimal x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateBigDecimal");
    }
    
    @Override
    public final void updateString(final int columnIndex, final String x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateString");
    }
    
    @Override
    public final void updateString(final String columnLabel, final String x) throws SQLException {
        throw new SQLFeatureNotSupportedException("updateString");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Move the write out of the cursor: read with getBigDecimal(columnIndex), then execute a PreparedStatement UPDATE setting the BigDecimal by setBigDecimal, keyed on the primary key.
  2. Pre-check rs.getConcurrency() and branch to UPDATE statements when the set is read-only; optionally assert DatabaseMetaData.supportsResultSetConcurrency(TYPE_FORWARD_ONLY, CONCUR_UPDATABLE) is true before relying on cursor updates.
  3. Scope the sql_federation rule so this query is not federated and the backend driver's native ResultSet semantics apply.

Example fix

// before
rs.updateBigDecimal(4, new BigDecimal("123.45"));  // SQLFeatureNotSupportedException: updateBigDecimal
rs.updateRow();

// after
try (PreparedStatement upd = conn.prepareStatement("UPDATE ledger SET amount = ? WHERE id = ?")) {
    upd.setBigDecimal(1, new BigDecimal("123.45"));
    upd.setLong(2, rs.getLong(1));
    upd.executeUpdate();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (rs.getConcurrency() != ResultSet.CONCUR_UPDATABLE) {
    // monetary writes must go through UPDATE + setBigDecimal
}

Type guard

private static boolean supportsRowUpdates(final ResultSet rs) throws SQLException {
    return rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE;
}

Try / catch

try {
    rs.updateBigDecimal(4, amount);
} catch (final SQLFeatureNotSupportedException ignored) {
    try (PreparedStatement upd = conn.prepareStatement("UPDATE ledger SET amount = ? WHERE id = ?")) {
        upd.setBigDecimal(1, amount);
        upd.setLong(2, rs.getLong(1));
        upd.executeUpdate();
    }
}

Prevention

When it happens

Trigger: Calling ResultSet.updateBigDecimal(int columnIndex, BigDecimal x) on the ResultSet of a federation-executed statement (cross-shard join/subquery under an enabled sql_federation rule). Encountered in financial/billing code that patches monetary columns in place, or generic row-edit frameworks.

Common situations: Money-handling code that assumed CONCUR_UPDATABLE on the underlying MySQL/Oracle driver and now runs against ShardingSphere federation; sqlFederation turned on during a sharding migration, silently routing previously normal queries through the federation engine; reusable JDBC utilities that call updateXxx on every ResultSet they process.

Related errors


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