apache/shardingsphere · error · SQLFeatureNotSupportedException

absolute

Error message

absolute

What it means

absolute(int row) positions the cursor at an arbitrary row number; ShardingSphere's merged result set is forward-only and final-blocks this method with SQLFeatureNotSupportedException. Random positioning across a multi-shard merge would require full materialization, which the driver deliberately avoids for memory reasons.

Source

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

    
    @Override
    public final void afterLast() throws SQLException {
        throw new SQLFeatureNotSupportedException("afterLast");
    }
    
    @Override
    public final boolean first() throws SQLException {
        throw new SQLFeatureNotSupportedException("first");
    }
    
    @Override
    public final boolean last() throws SQLException {
        throw new SQLFeatureNotSupportedException("last");
    }
    
    @Override
    public final boolean absolute(final int row) throws SQLException {
        throw new SQLFeatureNotSupportedException("absolute");
    }
    
    @Override
    public final boolean relative(final int rows) throws SQLException {
        throw new SQLFeatureNotSupportedException("relative");
    }
    
    @Override
    public final int getRow() throws SQLException {
        throw new SQLFeatureNotSupportedException("getRow");
    }
    
    @Override
    public final void insertRow() throws SQLException {
        throw new SQLFeatureNotSupportedException("insertRow");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Push pagination into SQL: append LIMIT <size> OFFSET <start> (or database-native syntax) so shards return only the needed window.
  2. For UI-style random access, load all rows once into a List or CachedRowSet and index them.
  3. Use ORDER BY with a tiebreaker column so LIMIT/OFFSET paging is deterministic across shards.
  4. Verify any third-party paginator is configured for SQL-based paging, not cursor-based.

Example fix

// before
ResultSet rs = ps.executeQuery();
rs.absolute(pageStart + 1); // throws

// after
String sql = "SELECT * FROM t_order ORDER BY order_id LIMIT ? OFFSET ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, pageSize); ps.setInt(2, pageStart);
ResultSet rs = ps.executeQuery();
Defensive patterns

Strategy: fallback

Validate before calling

if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
    // no absolute positioning: push paging into SQL with LIMIT/OFFSET and ORDER BY
}

Try / catch

try {
    rs.absolute(pageStart + 1);
} catch (SQLFeatureNotSupportedException e) {
    // re-query with LIMIT ? OFFSET ? and a deterministic ORDER BY
}

Prevention

When it happens

Trigger: Calling rs.absolute(5), rs.absolute(-1) (last row), or any absolute(n) on a query result obtained through ShardingDataSource/ShardingSphereDataSource.

Common situations: Hand-rolled pagination that seeks to page start via absolute(offset+1); jumping to the last row with absolute(-1); Swing/table-model code or export tools that random-access rows.

Related errors


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