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

View on GitHub (pinned to e952770a21)

Solutions

  1. Replace the first() reset pattern with a single forward loop, or re-execute the query if a second pass is needed
  2. To test emptiness, call rs.next() once instead of first()
  3. 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

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.