{"record":{"id":"3d6b39218bdd989e","repo":"apache/shardingsphere","slug":"getcursorname-3d6b39","errorCode":null,"errorMessage":"getCursorName","messagePattern":"getCursorName","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java","lineNumber":145,"sourceCode":"    \n    @Override\n    public final boolean rowInserted() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"rowInserted\");\n    }\n    \n    @Override\n    public final boolean rowUpdated() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"rowUpdated\");\n    }\n    \n    @Override\n    public final boolean rowDeleted() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"rowDeleted\");\n    }\n    \n    @Override\n    public final String getCursorName() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getCursorName\");\n    }\n    \n    @Override\n    public final int getHoldability() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getHoldability\");\n    }\n    \n    @Override\n    public final NClob getNClob(final int columnIndex) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getNClob\");\n    }\n    \n    @Override\n    public final NClob getNClob(final String columnLabel) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getNClob\");\n    }\n    \n    @Override","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/resultset/AbstractUnsupportedOperationSQLFederationResultSet.java#L127-L163","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nString cursor = rs.getCursorName();\nstmt.execute(\"UPDATE t SET c = 1 WHERE CURRENT OF \" + cursor);\n\n// after\ntry (PreparedStatement ps = conn.prepareStatement(\"UPDATE t SET c = 1 WHERE id = ?\")) {\n    ps.setLong(1, currentId); ps.executeUpdate();\n}","handlingStrategy":"try-catch","validationCode":"try { rs.getCursorName(); /* positioned updates possible */ }\ncatch (final SQLFeatureNotSupportedException e) { /* no cursor name: use keyed UPDATE */ }","typeGuard":"private boolean supportsPositionedUpdate(final ResultSet rs) {\n    try { rs.getCursorName(); return true; }\n    catch (final SQLFeatureNotSupportedException e) { return false; }\n}","tryCatchPattern":"String cursor;\ntry { cursor = rs.getCursorName(); }\ncatch (final SQLFeatureNotSupportedException e) { cursor = null; }\nif (cursor == null) { executeKeyedUpdate(conn, table, changes, id); }","preventionTips":["Never log getCursorName() unconditionally in wrappers","Replace WHERE CURRENT OF with WHERE pk = ?","Probe cursor support once per connection, not per row"],"tags":["jdbc","resultset","sql-federation","positioned-update","cursor","shardingsphere"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}