apache/shardingsphere · warning · SQLFeatureNotSupportedException
isLast
Error message
isLast
What it means
The federation result set deliberately does not implement cursor-positioning methods; isLast() throws SQLFeatureNotSupportedException with the method name. AbstractUnsupportedOperationSQLFederationResultSet marks JDBC capabilities that the Calcite-backed federation result set does not support, so drivers or code that probe isLast() fail loudly instead of getting wrong answers.
Source
Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java:55
@Override
public boolean isBeforeFirst() throws SQLException {
throw new SQLFeatureNotSupportedException("isBeforeFirst");
}
@Override
public boolean isAfterLast() throws SQLException {
throw new SQLFeatureNotSupportedException("isAfterLast");
}
@Override
public boolean isFirst() throws SQLException {
throw new SQLFeatureNotSupportedException("isFirst");
}
@Override
public boolean isLast() throws SQLException {
throw new SQLFeatureNotSupportedException("isLast");
}
@Override
public void beforeFirst() throws SQLException {
throw new SQLFeatureNotSupportedException("beforeFirst");
}
@Override
public void afterLast() throws SQLException {
throw new SQLFeatureNotSupportedException("afterLast");
}
@Override
public boolean first() throws SQLException {
throw new SQLFeatureNotSupportedException("first");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Avoid isLast() on ShardingSphere result sets; track row positions yourself while iterating with next().
- If the row count is needed, execute a COUNT query or fetch all rows into a list first.
- Disable federation for the query so a driver result set with full capabilities is returned.
- Configure ORMs to limit/offset via SQL rather than result-set positioning.
Example fix
// before
while (rs.next()) { if (rs.isLast()) { ... } }
// after
List<Row> rows = fetchAll(rs); // iterate rs.next() and collect
if (!rows.isEmpty()) { handleLast(rows.get(rows.size() - 1)); } Defensive patterns
Strategy: validation
Validate before calling
if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
// do not call isLast()/isFirst(); count rows while iterating
} Try / catch
try {
boolean last = rs.isLast();
} catch (final SQLFeatureNotSupportedException ex) {
// fall back to manual row tracking
} Prevention
- Never call isLast()/isFirst()/isAfterLast() on proxy result sets.
- Maintain row counters in application code during iteration.
- Configure ORMs to avoid result-set capability probing.
When it happens
Trigger: Application or ORM code calls ResultSet.isLast() on a result set produced by a federated query (federation enabled and the query executed through SQLFederationExecutor).
Common situations: OR frameworks and reporting tools that call isLast() for pagination/iteration logic; custom JDBC wrappers that always probe result-set capabilities; code migrated from non-federated paths where the underlying driver supported isLast().
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/d1bc772e49b64743.
Report an issue: GitHub.