apache/shardingsphere · error · SQLFeatureNotSupportedException
getCursorName
Error message
getCursorName
What it means
getCursorName() throws SQLFeatureNotSupportedException in the SQL Federation ResultSet. Cursor names exist for positioned UPDATE/DELETE ... WHERE CURRENT OF statements; federation result sets are not backed by an updatable server cursor, so the abstract class rejects cursor-name retrieval (method is final).
Source
Thrown at kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java:145
@Override
public final boolean rowInserted() throws SQLException {
throw new SQLFeatureNotSupportedException("rowInserted");
}
@Override
public final boolean rowUpdated() throws SQLException {
throw new SQLFeatureNotSupportedException("rowUpdated");
}
@Override
public final boolean rowDeleted() throws SQLException {
throw new SQLFeatureNotSupportedException("rowDeleted");
}
@Override
public final String getCursorName() throws SQLException {
throw new SQLFeatureNotSupportedException("getCursorName");
}
@Override
public final int getHoldability() throws SQLException {
throw new SQLFeatureNotSupportedException("getHoldability");
}
@Override
public final NClob getNClob(final int columnIndex) throws SQLException {
throw new SQLFeatureNotSupportedException("getNClob");
}
@Override
public final NClob getNClob(final String columnLabel) throws SQLException {
throw new SQLFeatureNotSupportedException("getNClob");
}
@OverrideView on GitHub (pinned to e952770a21)
Solutions
- Replace positioned (WHERE CURRENT OF) updates with keyed UPDATE ... WHERE pk = ? statements
- Remove unconditional getCursorName() logging/metadata calls from generic ResultSet wrappers
- Guard utility code to skip cursor-name retrieval for federation datasources (check the connection/DataSource class or product name)
Example fix
// before
String cursor = rs.getCursorName();
stmt.execute("UPDATE t SET c = 1 WHERE CURRENT OF " + cursor);
// after
try (PreparedStatement ps = conn.prepareStatement("UPDATE t SET c = 1 WHERE id = ?")) {
ps.setLong(1, currentId); ps.executeUpdate();
} Defensive patterns
Strategy: try-catch
Validate before calling
try { rs.getCursorName(); /* positioned updates possible */ }
catch (final SQLFeatureNotSupportedException e) { /* no cursor name: use keyed UPDATE */ } Type guard
private boolean supportsPositionedUpdate(final ResultSet rs) {
try { rs.getCursorName(); return true; }
catch (final SQLFeatureNotSupportedException e) { return false; }
} Try / catch
String cursor;
try { cursor = rs.getCursorName(); }
catch (final SQLFeatureNotSupportedException e) { cursor = null; }
if (cursor == null) { executeKeyedUpdate(conn, table, changes, id); } Prevention
- Never log getCursorName() unconditionally in wrappers
- Replace WHERE CURRENT OF with WHERE pk = ?
- Probe cursor support once per connection, not per row
When it happens
Trigger: Calling rs.getCursorName(), usually generated by positioned-update helpers (named-cursor pattern: SELECT ... FOR UPDATE + UPDATE ... WHERE CURRENT OF <cursor>) executed against a federation-routed statement.
Common situations: Code ported from DB2/Oracle/Sybase style positioned updates; framework utilities that always query getCursorName() for logging; wrappers that inspect ResultSet metadata and unconditionally fetch the cursor name on every result set, blowing up only when the statement happens to run under ShardingSphere federation.
Related errors
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/3d6b39218bdd989e.
Report an issue: GitHub.