apache/shardingsphere · error · SQLFeatureNotSupportedException
updateAsciiStream
Error message
updateAsciiStream
What it means
The ShardingSphere SQL federation ResultSet throws SQLFeatureNotSupportedException("updateAsciiStream") because the federation engine produces read-only, memory-computed result sets. The abstract class AbstractUnsupportedUpdateOperationSQLFederationResultSet implements every JDBC row-update method as an unconditional throw, and concrete federation result sets inherit this. Updating a column in-place on a federated query result is therefore unsupported by design.
Source
Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedUpdateOperationSQLFederationResultSet.java:194
@Override
public final void updateTime(final String columnLabel, final Time x) throws SQLException {
throw new SQLFeatureNotSupportedException("updateTime");
}
@Override
public final void updateTimestamp(final int columnIndex, final Timestamp x) throws SQLException {
throw new SQLFeatureNotSupportedException("updateTimestamp");
}
@Override
public final void updateTimestamp(final String columnLabel, final Timestamp x) throws SQLException {
throw new SQLFeatureNotSupportedException("updateTimestamp");
}
@Override
public final void updateAsciiStream(final int columnIndex, final InputStream inputStream) throws SQLException {
throw new SQLFeatureNotSupportedException("updateAsciiStream");
}
@Override
public final void updateAsciiStream(final String columnLabel, final InputStream inputStream) throws SQLException {
throw new SQLFeatureNotSupportedException("updateAsciiStream");
}
@Override
public final void updateAsciiStream(final int columnIndex, final InputStream x, final int length) throws SQLException {
throw new SQLFeatureNotSupportedException("updateAsciiStream");
}
@Override
public final void updateAsciiStream(final String columnLabel, final InputStream x, final int length) throws SQLException {
throw new SQLFeatureNotSupportedException("updateAsciiStream");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Stop using result-set update APIs on federated query results; issue a separate UPDATE statement (or PreparedStatement) against the target table instead.
- If the query does not actually need federation (not a cross-database JOIN/complex subquery), rewrite the SQL or adjust sharding rules so it is routed normally and does not return the federation ResultSet.
- Disable SQL federation for these statements if the feature is not required (check sql_federation / SQLFederationRule configuration), so a standard driver ResultSet with driver-native update support is returned.
- Wrap update paths in code that checks rs.getClass() or capability before calling update* methods, falling back to explicit UPDATE SQL.
Example fix
// before
ResultSet rs = stmt.executeQuery("SELECT a, b FROM t_order JOIN t_user ...");
rs.updateAsciiStream(1, in); // SQLFeatureNotSupportedException
rs.updateRow();
// after
ResultSet rs = stmt.executeQuery("SELECT a, b FROM t_order JOIN t_user ...");
String a = new String(in.readAllBytes(), StandardCharsets.US_ASCII);
stmt2.executeUpdate("UPDATE t_order SET a = ? WHERE ..."); Defensive patterns
Strategy: try-catch
Validate before calling
int concurrency = rs.getConcurrency();
if (concurrency != ResultSet.CONCUR_UPDATABLE || rs instanceof org.apache.shardingsphere.sqlfederation.resultset.SQLFederationResultSet) {
// use UPDATE statement instead of rs.updateAsciiStream(...)
} Type guard
boolean isFederationResultSet(ResultSet rs) {
return rs instanceof org.apache.shardingsphere.sqlfederation.resultset.SQLFederationResultSet;
} Try / catch
try {
rs.updateAsciiStream(col, in);
} catch (SQLFeatureNotSupportedException e) {
// fall back to explicit UPDATE statement
throw new UnsupportedOperationException("Federated result sets are read-only; use UPDATE SQL", e);
} Prevention
- Never call ResultSet.update* APIs on results from ShardingSphere federation queries; use standalone UPDATE statements.
- Check rs.getConcurrency() before positioned updates.
- Add integration tests behind ShardingSphere for any code that previously relied on updatable cursors.
When it happens
Trigger: Calling ResultSet.updateAsciiStream(int, InputStream) (the two-arg overload, no length) on a ResultSet returned by a SQL federation query (e.g. a cross-shard JOIN or subquery routed through sqlfederation). Happens when application code or an ORM tries the JDBC 4.0+ updateRow flow: rs.updateAsciiStream(...) followed by rs.updateRow().
Common situations: Applications or frameworks (Hibernate, Spring JDBC, iBatis, reporting tools) that use positioned result-set updates; enabling sql_federation (SQL Federation / federation execution) in shardingsphere.yaml so queries return SQLFederationResultSet; migrating code from a plain MySQL/PG driver that allowed updatable result sets.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/3f35ee0dc588c3e4.
Report an issue: GitHub.