{"record":{"id":"3195178a23b5d2ef","repo":"apache/shardingsphere","slug":"last","errorCode":null,"errorMessage":"last","messagePattern":"last","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java","lineNumber":75,"sourceCode":"    \n    @Override\n    public final void beforeFirst() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"beforeFirst\");\n    }\n    \n    @Override\n    public final void afterLast() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"afterLast\");\n    }\n    \n    @Override\n    public final boolean first() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"first\");\n    }\n    \n    @Override\n    public final boolean last() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"last\");\n    }\n    \n    @Override\n    public final boolean absolute(final int row) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"absolute\");\n    }\n    \n    @Override\n    public final boolean relative(final int rows) throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"relative\");\n    }\n    \n    @Override\n    public final int getRow() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"getRow\");\n    }\n    \n    @Override","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java#L57-L93","documentation":"last() — jumping to the final row — requires knowing the end of the result ahead of arrival, impossible for ShardingSphere's streaming forward-only merge across shards. The driver therefore declares it final and it throws SQLFeatureNotSupportedException at runtime.","triggerScenarios":"Calling rs.last() to read the newest/last record, often followed by getRow() as a row-count trick, on results from the ShardingSphere driver.","commonSituations":"row-count idiom rs.last(); int n = rs.getRow(); rs.beforeFirst();; fetching the latest entry by cursor position instead of ORDER BY ... LIMIT 1; report code ported from scrollable cursors.","solutions":["Get row counts with SELECT COUNT(*) as a separate query.","Fetch the last logical row with ORDER BY <col> DESC LIMIT 1 (or OFFSET-based pagination), not cursor jumping.","Materialize rows into a List and take list.get(list.size()-1).","If a library relies on last(), hand it a CachedRowSet copy of the data."],"exampleFix":"// before\nrs.last(); // throws\nint count = rs.getRow();\n\n// after\ntry (ResultSet c = conn.createStatement().executeQuery(\"SELECT COUNT(*) FROM t_order\")) {\n    c.next(); int count = c.getInt(1);\n}","handlingStrategy":"fallback","validationCode":"if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {\n    // cannot jump to last row: use ORDER BY ... DESC LIMIT 1 or COUNT(*) instead\n}","typeGuard":null,"tryCatchPattern":"try {\n    rs.last();\n    int count = rs.getRow();\n} catch (SQLFeatureNotSupportedException e) {\n    // run SELECT COUNT(*) for the total\n}","preventionTips":["Replace last()+getRow() count idioms with COUNT(*) queries.","Fetch latest rows with ORDER BY + LIMIT, never cursor jumps.","For UI random access, preload rows into memory once."],"tags":["jdbc","resultset","cursor","last-row","row-count"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}