{"record":{"id":"c30dc609f0989945","repo":"apache/shardingsphere","slug":"islast","errorCode":null,"errorMessage":"isLast","messagePattern":"isLast","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java","lineNumber":55,"sourceCode":"    \n    @Override\n    public final boolean isBeforeFirst() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"isBeforeFirst\");\n    }\n    \n    @Override\n    public final boolean isAfterLast() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"isAfterLast\");\n    }\n    \n    @Override\n    public final boolean isFirst() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"isFirst\");\n    }\n    \n    @Override\n    public final boolean isLast() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"isLast\");\n    }\n    \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","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java#L37-L73","documentation":"isLast() on ShardingSphere's merged, forward-only ResultSet throws SQLFeatureNotSupportedException because knowing 'this is the last row' requires seeing ahead, which a streaming merge does not support. The method is final in AbstractUnsupportedOperationResultSet, so no driver subclass relaxes it.","triggerScenarios":"Calling rs.isLast() in an iteration loop — e.g. to omit a trailing comma — on results from ShardingSphereDataSource.","commonSituations":"Serializers that suppress separators after the final element; look-ahead pagination logic; code ported from Oracle/JDBC tutorial examples where isLast() is legal on scrollable cursors.","solutions":["Buffer the rows (List<Object[]>) so the last element is knowable by index, or emit separators before each element except the first (which you can track with a boolean).","Peek one row ahead: keep a 'current' row fetched via next() and compare the next next() result.","Use a COUNT query upfront if knowing total rows in advance is acceptable.","Run tools that require isLast() against a materialized CachedRowSet instead."],"exampleFix":"// before\nwhile (rs.next()) { writeRow(rs); if (!rs.isLast()) write(\",\"); } // throws\n\n// after\nboolean first = true;\nwhile (rs.next()) { if (!first) write(\",\"); writeRow(rs); first = false; }","handlingStrategy":"validation","validationCode":"if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {\n    // 'last row' is unknowable while streaming; buffer rows or track first-flag instead\n}","typeGuard":null,"tryCatchPattern":"try {\n    if (rs.isLast()) { ... }\n} catch (SQLFeatureNotSupportedException e) {\n    // emit separator before every element except the first, tracked locally\n}","preventionTips":["Invert separator logic to 'all but first' so the last row never needs to be known.","Buffer rows when trailing-element logic is unavoidable.","Add tests for serializers that run through the sharded driver."],"tags":["jdbc","resultset","cursor","position-check","last-row"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}