apache/shardingsphere · error · SQLFeatureNotSupportedException
first
Error message
first
What it means
The SQL Federation ResultSet does not implement first(), the JDBC cursor method that moves the cursor to the first row. AbstractUnsupportedOperationSQLFederationResultSet intentionally throws SQLFeatureNotSupportedException for all scroll-position methods because federation results are forward-only streams produced by the federation engine. Any invocation of first() fails immediately.
Source
Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java:70
@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
public boolean relative(final int rows) throws SQLException {
throw new SQLFeatureNotSupportedException("relative");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Replace the first() reset pattern with a single forward loop, or re-execute the query if a second pass is needed
- To test emptiness, call rs.next() once instead of first()
- If random re-positioning is mandatory, populate a client-side scrollable RowSet (CachedRowSet) from the federated ResultSet and call first() on that
Example fix
// before
if (rs.first()) { doSomething(rs); }
// after
if (rs.next()) { doSomething(rs); } Defensive patterns
Strategy: try-catch
Validate before calling
if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
// first() unsupported: use rs.next() to test/reach the first row
} Type guard
private boolean canRewind(final ResultSet rs) throws SQLException {
return rs.getType() != ResultSet.TYPE_FORWARD_ONLY;
} Try / catch
try {
ok = rs.first();
} catch (final SQLFeatureNotSupportedException e) {
ok = rs.next(); // forward-only fallback
} Prevention
- Prefer rs.next() for emptiness checks over rs.first()
- Document federation datasources as forward-only in team coding guides
- Wrap shared DAO code with a scroll-capability check via rs.getType()
When it happens
Trigger: Calling rs.first() on a ResultSet returned by a statement executed with SQL Federation enabled (cross-database or push-down query rewritten by the federation optimizer), typically to reset iteration or read row 1 again after partial iteration.
Common situations: Application code that restarts result-set iteration with first() (common in legacy JDBC DAOs); frameworks that call first() to check emptiness; migrating an app from a plain MySQL/PostgreSQL driver (which supports scrollable cursors) to ShardingSphere with federation turned on.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/7bbd20d186d15696.
Report an issue: GitHub.