apache/shardingsphere · error · SQLFeatureNotSupportedException

relative

Error message

relative

What it means

relative(int rows) moves the cursor by an offset from the current position; ShardingSphere's forward-only streaming result cannot honor it and implements the method as final, throwing SQLFeatureNotSupportedException. Only the single-row forward step next() is supported.

Source

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

    
    @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
    public final void updateRow() throws SQLException {
        throw new SQLFeatureNotSupportedException("updateRow");
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Use rs.next() once per row; skip rows by calling next() repeatedly and ignoring the returned rows.
  2. Buffer rows into a List and advance an index by any offset you like.
  3. Express skip/limit semantics in SQL (LIMIT/OFFSET) rather than cursor movement.
  4. Give libraries requiring relative() a materialized CachedRowSet.

Example fix

// before
while (rs.next()) { process(rs); rs.relative(1); } // throws

// after
while (rs.next()) { process(rs); if (!rs.next()) break; } // explicit skip
Defensive patterns

Strategy: validation

Validate before calling

if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {
    // only next() moves the cursor; skip rows by repeated next(), not relative(n)
}

Try / catch

try {
    rs.relative(2);
} catch (SQLFeatureNotSupportedException e) {
    rs.next(); rs.next(); // forward skips are safe
}

Prevention

When it happens

Trigger: Calling rs.relative(1) to double-step, or rs.relative(-1) as a substitute for previous(), on a ShardingSphere-driver ResultSet.

Common situations: Pair-processing code that skips every other row; backtracking attempted via relative(-1); generic cursor wrappers that normalize movement through relative().

Related errors


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