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");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Use rs.next() once per row; skip rows by calling next() repeatedly and ignoring the returned rows.
- Buffer rows into a List and advance an index by any offset you like.
- Express skip/limit semantics in SQL (LIMIT/OFFSET) rather than cursor movement.
- 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
- Express row skipping as repeated next() calls or, better, in SQL OFFSET.
- Never use relative(-1) as a substitute for previous() — both throw.
- Buffer rows when step-based traversal is required.
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.