apache/shardingsphere · error · SQLFeatureNotSupportedException

isLast

Error message

isLast

What it means

isLast() on ShardingSphere's merged, forward-only ResultSet throws SQLFeatureNotSupportedException because knowing 'this is the last row' requires seeing ahead, which a streaming merge does not support. The method is final in AbstractUnsupportedOperationResultSet, so no driver subclass relaxes it.

Source

Thrown at jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java:55

    
    @Override
    public final boolean isBeforeFirst() throws SQLException {
        throw new SQLFeatureNotSupportedException("isBeforeFirst");
    }
    
    @Override
    public final boolean isAfterLast() throws SQLException {
        throw new SQLFeatureNotSupportedException("isAfterLast");
    }
    
    @Override
    public final boolean isFirst() throws SQLException {
        throw new SQLFeatureNotSupportedException("isFirst");
    }
    
    @Override
    public final boolean isLast() throws SQLException {
        throw new SQLFeatureNotSupportedException("isLast");
    }
    
    @Override
    public final void beforeFirst() throws SQLException {
        throw new SQLFeatureNotSupportedException("beforeFirst");
    }
    
    @Override
    public final void afterLast() throws SQLException {
        throw new SQLFeatureNotSupportedException("afterLast");
    }
    
    @Override
    public final boolean first() throws SQLException {
        throw new SQLFeatureNotSupportedException("first");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Buffer the rows (List<Object[]>) so the last element is knowable by index, or emit separators before each element except the first (which you can track with a boolean).
  2. Peek one row ahead: keep a 'current' row fetched via next() and compare the next next() result.
  3. Use a COUNT query upfront if knowing total rows in advance is acceptable.
  4. Run tools that require isLast() against a materialized CachedRowSet instead.

Example fix

// before
while (rs.next()) { writeRow(rs); if (!rs.isLast()) write(","); } // throws

// after
boolean first = true;
while (rs.next()) { if (!first) write(","); writeRow(rs); first = false; }
Defensive patterns

Strategy: validation

Validate before calling

if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
    // 'last row' is unknowable while streaming; buffer rows or track first-flag instead
}

Try / catch

try {
    if (rs.isLast()) { ... }
} catch (SQLFeatureNotSupportedException e) {
    // emit separator before every element except the first, tracked locally
}

Prevention

When it happens

Trigger: Calling rs.isLast() in an iteration loop — e.g. to omit a trailing comma — on results from ShardingSphereDataSource.

Common situations: Serializers that suppress separators after the final element; look-ahead pagination logic; code ported from Oracle/JDBC tutorial examples where isLast() is legal on scrollable cursors.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/c30dc609f0989945. Report an issue: GitHub.