apache/shardingsphere · error · SQLFeatureNotSupportedException

getRow

Error message

getRow

What it means

getRow() — returning the current row number — throws SQLFeatureNotSupportedException in the SQL Federation ResultSet. Because the cursor model is forward-only and the class also rejects absolute/last positioning, the row-index contract of getRow() is deliberately not implemented.

Source

Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java:90

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

View on GitHub (pinned to e952770a21)

Solutions

  1. Maintain an application-side row counter (int row = 1; ... row++) instead of getRow()
  2. For totals, run a separate COUNT query rather than last()+getRow()
  3. Audit code paths that run against federation-enabled datasources with grep for getRow/absolute/relative/first/last before migration

Example fix

// before
while (rs.next()) { log("row {}", rs.getRow()); }

// after
int row = 0;
while (rs.next()) { row++; log("row {}", row); }
Defensive patterns

Strategy: validation

Validate before calling

boolean supportsGetRow;
try { rs.getRow(); supportsGetRow = true; }
catch (final SQLFeatureNotSupportedException e) { supportsGetRow = false; }

Type guard

private int safeRow(final ResultSet rs, final int fallbackRow) throws SQLException {
    try { return rs.getRow(); }
    catch (final SQLFeatureNotSupportedException e) { return fallbackRow; }
}

Try / catch

int row;
try { row = rs.getRow(); }
catch (final SQLFeatureNotSupportedException e) { row = localRowCounter++; }

Prevention

When it happens

Trigger: Calling rs.getRow() while iterating a federated ResultSet, e.g. progress logging ('processing row ' + rs.getRow()), row-count via last()+getRow(), or conditional logic keyed on the current row index.

Common situations: Row counters inside iteration loops; pagination totals computed with last()/getRow(); code migrated from MySQL Connector/J where getRow() is cheap and supported. Surfaces only for statements routed through the SQL Federation engine (sql_federation_type=BASIC/ADVANCED and a federation-eligible query).

Related errors


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