{"record":{"id":"bcc60de08e10c72c","repo":"pentaho/pentaho-kettle","slug":"unable-to-move-the-resultset-forward-rows-rows","errorCode":null,"errorMessage":"Unable to move the resultset forward \" + rows + \" rows","messagePattern":"Unable to move the resultset forward \" \\+ rows \\+ \" rows","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/Database.java","lineNumber":2953,"sourceCode":"    }\n\n    throw new KettleDatabaseException( \"Unable to handle database column '\"\n      + name + \"', on column index \" + i + \" : not a handled data type\" );\n  }\n\n  public boolean absolute( ResultSet rs, int position ) throws KettleDatabaseException {\n    try {\n      return rs.absolute( position );\n    } catch ( SQLException e ) {\n      throw new KettleDatabaseException( \"Unable to move resultset to position \" + position, e );\n    }\n  }\n\n  public boolean relative( ResultSet rs, int rows ) throws KettleDatabaseException {\n    try {\n      return rs.relative( rows );\n    } catch ( SQLException e ) {\n      throw new KettleDatabaseException( \"Unable to move the resultset forward \" + rows + \" rows\", e );\n    }\n  }\n\n  public void afterLast( ResultSet rs ) throws KettleDatabaseException {\n    try {\n      rs.afterLast();\n    } catch ( SQLException e ) {\n      throw new KettleDatabaseException( \"Unable to move resultset to after the last position\", e );\n    }\n  }\n\n  public void first( ResultSet rs ) throws KettleDatabaseException {\n    try {\n      rs.first();\n    } catch ( SQLException e ) {\n      throw new KettleDatabaseException( \"Unable to move resultset to the first position\", e );\n    }\n  }","sourceCodeStart":2935,"sourceCodeEnd":2971,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/Database.java#L2935-L2971","documentation":"KettleDatabaseException wrapper for ResultSet.relative(rows) failures. relative() moves the cursor forward or backward the given number of rows and, like absolute(), requires a scrollable, non-forward-only result set.","triggerScenarios":"Calling Database.relative(rs, rows) on a TYPE_FORWARD_ONLY result set, after the result set is closed, or on a driver that doesn't implement relative cursor movement.","commonSituations":"Paging through results with relative() on a default statement; connection or cursor invalidated by timeout; drivers lacking scrollable cursor support.","solutions":["Request a scrollable result set when creating the Statement","Replace relative() navigation with repeated rs.next() calls or an OFFSET-based re-query","Confirm the result set is open and the connection alive","Verify driver support for scrollable cursors"],"exampleFix":"// before\ndb.relative(rs, rows);\n// after\nboolean moved = true;\nfor (int i = 0; i < rows && moved; i++) {\n  moved = rs.next();\n}","handlingStrategy":"fallback","validationCode":"if (rs.getType() == ResultSet.TYPE_FORWARD_ONLY) {\n  // use rs.next() loop instead of relative()\n}","typeGuard":"null","tryCatchPattern":"try {\n  db.relative(rs, rows);\n} catch (KettleDatabaseException e) {\n  // fallback: advance with rs.next() one row at a time\n}","preventionTips":["Request TYPE_SCROLL_INSENSITIVE result sets when paging","Replace relative navigation with next()-loops or OFFSET queries","Check result set type before any cursor movement","Test with streaming configurations which force forward-only"],"tags":["jdbc","resultset","cursor"],"backgroundTag":"unsupported-operation","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}