{"record":{"id":"12bec183a7cdf22e","repo":"apache/shardingsphere","slug":"isfirst","errorCode":null,"errorMessage":"isFirst","messagePattern":"isFirst","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java","lineNumber":50,"sourceCode":"    \n    @Override\n    public final boolean previous() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"previous\");\n    }\n    \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","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java#L32-L68","documentation":"isFirst() — asking whether the cursor is on the first row — is a final, throwing method in ShardingSphere's AbstractUnsupportedOperationResultSet. Forward-only merged results do not maintain row-number state for position introspection, so the call fails with SQLFeatureNotSupportedException.","triggerScenarios":"Calling rs.isFirst() inside an iteration loop, e.g. to skip a separator/header only on the first row, on a result set produced via the ShardingSphere driver.","commonSituations":"CSV/JSON exporters that special-case the first row; pagination logic that branches on cursor position; generic row visitors copied from code written against scrollable result sets.","solutions":["Track the position yourself with a boolean or row counter updated as you call next().","Pre-buffer all rows into a List and use index-based checks (i == 0).","If you must special-case the first row, read it once before entering the loop for the remainder.","For heavyweight frameworks needing position APIs, feed them a CachedRowSet or RowSetProvider copy."],"exampleFix":"// before\nwhile (rs.next()) { if (rs.isFirst()) writeHeader(); writeRow(rs); } // throws\n\n// after\nboolean first = true;\nwhile (rs.next()) { if (first) { writeHeader(); first = false; } writeRow(rs); }","handlingStrategy":"validation","validationCode":"if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {\n    // track first-row state in a local boolean, never rs.isFirst()\n}","typeGuard":null,"tryCatchPattern":"try {\n    if (rs.isFirst()) { ... }\n} catch (SQLFeatureNotSupportedException e) {\n    // fall back to your own row counter (row == 1 means first)\n}","preventionTips":["Maintain a local row counter or boolean for first-row special-casing.","Prefer index-based logic over an in-memory list for position-dependent formatting.","Static-analysis rule: no ResultSet position getters on forward-only cursors."],"tags":["jdbc","resultset","cursor","position-check","first-row"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}