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");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Remove the afterLast() call and rely on forward-only iteration (next()) over the federated ResultSet
  2. 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
  3. 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

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.