apache/shardingsphere · error · SQLFeatureNotSupportedException
afterLast
Error message
afterLast
What it means
The ShardingSphere SQL Federation forward-only ResultSet implementation does not support the cursor-control method afterLast(). This abstract class deliberately overrides JDBC ResultSet methods that require a scroll-sensitive cursor with a throw of SQLFeatureNotSupportedException, because federated query results are streamed once through the federation engine. Calling afterLast() on a federation ResultSet triggers the exception unconditionally.
Source
Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java:65
@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");
}
@Override
public boolean last() throws SQLException {
throw new SQLFeatureNotSupportedException("last");
}
@Override
public boolean absolute(final int row) throws SQLException {
throw new SQLFeatureNotSupportedException("absolute");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Remove the afterLast() call and rely on forward-only iteration (next()) over the federated ResultSet
- If backward scrolling is required, fetch all rows into a scrollable cache first: e.g. copy rows into a org.apache.shardingsphere.sqlfederation.resultset or a client-side RowSet with TYPE_SCROLL_INSENSITIVE (new CachedRowSetImpl() and populate(rs)) and scroll that
- Rewrite the query so navigation is unnecessary (ORDER BY DESC instead of reverse iteration), or execute the query outside federation mode against a single shard
Example fix
// before
ResultSet rs = stmt.executeQuery(federatedSql);
rs.afterLast();
while (rs.previous()) { ... }
// after
ResultSet rs = stmt.executeQuery(federatedSql);
while (rs.next()) { ... } Defensive patterns
Strategy: try-catch
Validate before calling
int type = rs.getType();
if (type == ResultSet.TYPE_FORWARD_ONLY) {
// afterLast() will throw SQLFeatureNotSupportedException on federation result sets
} Type guard
private boolean supportsBackwardScroll(final ResultSet rs) throws SQLException {
return rs.getType() != ResultSet.TYPE_FORWARD_ONLY;
} Try / catch
try {
rs.afterLast();
} catch (final SQLFeatureNotSupportedException e) {
// forward-only federation result: iterate with next() instead
LOGGER.debug("scroll unsupported, falling back to forward iteration", e);
} Prevention
- Grep for afterLast|previous|beforeFirst before enabling sql-federation
- Treat all federation ResultSets as TYPE_FORWARD_ONLY
- Keep iteration utilities single-direction by default
When it happens
Trigger: Calling java.sql.ResultSet.afterLast() on a ResultSet produced by a SQL Federation (federated query) statement, e.g. rs.afterLast() while iterating results of a cross-database federated SELECT executed through ShardingSphere Proxy or JDBC in federation mode.
Common situations: Reusing ORM or reporting code that navigates result sets backwards (e.g. iterating in reverse with afterLast()/previous()) against a ShardingSphere federation data source; enabling sql-federation for cross-shard queries and pointing existing scroll-sensitive application code at it; MyBatis or JasperReports-style row visitors that call afterLast to detect row counts.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/0d6e5e6df6571582.
Report an issue: GitHub.