{"record":{"id":"2106c1b7703c7856","repo":"apache/shardingsphere","slug":"beforefirst","errorCode":null,"errorMessage":"beforeFirst","messagePattern":"beforeFirst","errorType":"exception","errorClass":"SQLFeatureNotSupportedException","httpStatus":null,"severity":"error","filePath":"jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java","lineNumber":60,"sourceCode":"    \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\n    public final boolean last() throws SQLException {\n        throw new SQLFeatureNotSupportedException(\"last\");\n    }\n    \n    @Override","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/unsupported/AbstractUnsupportedOperationResultSet.java#L42-L78","documentation":"beforeFirst() would reposition the cursor before the first row for a second pass, which ShardingSphere's forward-only merge result cannot do — the underlying streams from multiple shards are consumed once. The driver implements it as a final method throwing SQLFeatureNotSupportedException.","triggerScenarios":"Calling rs.beforeFirst() after an iteration to loop over the same ResultSet again — the classic 'second pass' pattern — on any ShardingSphere-driver query result.","commonSituations":"Two-phase algorithms (compute totals, then details); serializers that validate first and write second; JDBC tutorial examples; code that worked on MySQL Connector/J scrollable result sets before introducing sharding.","solutions":["Collect rows into a List during the first pass and iterate the List again.","If two passes over server data are truly needed, execute the query twice (each execution re-routes to shards).","Use a CachedRowSet (RowSetProvider.newFactory().createCachedRowSet()) populated from the result for repeatable navigation.","Restructure to a single pass that carries computed state forward."],"exampleFix":"// before\nwhile (rs.next()) { total += rs.getDouble(2); }\nrs.beforeFirst(); // throws\nwhile (rs.next()) { write(rs, total); }\n\n// after\nList<Object[]> rows = new ArrayList<>();\nwhile (rs.next()) { total += rs.getDouble(2); rows.add(new Object[]{rs.getObject(1), rs.getDouble(2)}); }\nfor (Object[] r : rows) { write(r, total); }","handlingStrategy":"fallback","validationCode":"if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {\n    List<Object[]> rows = new ArrayList<>();\n    while (rs.next()) { rows.add(mapRow(rs)); }\n    // iterate 'rows' as many passes as needed — never call beforeFirst()\n}","typeGuard":null,"tryCatchPattern":"try {\n    rs.beforeFirst();\n} catch (SQLFeatureNotSupportedException e) {\n    // second pass impossible: re-execute the query or use the buffered copy\n}","preventionTips":["Assume single-pass semantics for every sharded query result; buffer on first read.","Use CachedRowSet when handing results to code you don't control.","Design two-phase algorithms around a pre-fetched list, not cursor rewinds."],"tags":["jdbc","resultset","cursor","rewind","two-pass"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}