Skip to content

fix: fix off-by-one bug in ArrayResultSet.next() causing 'No current row' error#2

Merged
sophiecuiy merged 4 commits intomainfrom
fix/array-resultset-off-by-one
Mar 13, 2026
Merged

fix: fix off-by-one bug in ArrayResultSet.next() causing 'No current row' error#2
sophiecuiy merged 4 commits intomainfrom
fix/array-resultset-off-by-one

Conversation

@sophiecuiy
Copy link

Summary

  • Fix off-by-one bug in ArrayResultSet.next() that caused it to return true one extra time past the end of the array, leading to a "No current row" SQLException on the phantom iteration.
  • The guard condition pos == length was checked before incrementing pos, so when pos was at length-1 (last valid index), it passed the guard, incremented to length, and returned true. Fix: change to pos >= length - 1.
  • Add regression tests (testNextIterationCount, testNextSingleElement) verifying the standard JDBC iteration pattern while (rs.next()) { rs.getString(2); } works correctly.

Discovered via Airbyte connector source-clickhouse (airbytehq/airbyte#61419).

Test plan

  • Verify testNextIterationCount passes — iterates a 3-element array exactly 3 times
  • Verify testNextSingleElement passes — single-element array iterates once
  • Verify existing ArrayResultSetTest tests still pass
  • Run full jdbc-v2 test suite

🤖 Generated with Claude Code

…row' error

ArrayResultSet.next() returned true one extra time past the end of the
array. For an N-element array, next() was called N+1 times successfully
before getString(2) threw 'No current row' on the phantom iteration.

Root cause: the guard condition 'pos == length' checked BEFORE
incrementing pos, so when pos was at length-1 (last valid index), it
passed the guard, incremented to length, and returned true. The
subsequent checkRowPosition() then correctly detected pos >= length and
threw SQLException.

Fix: change the guard to 'pos >= length - 1' so that next() returns
false when pos is already at the last valid index.

The 'length == 0' guard is kept for clarity (empty arrays) even though
'pos >= length - 1' would handle it (pos=-1 >= -1 is true).

Affects all consumers that iterate ArrayResultSet with the standard
JDBC pattern: while (rs.next()) { rs.getString(2); }

Discovered via Airbyte connector source-clickhouse (airbytehq/airbyte#61419).

Co-Authored-By: sophie.cui@airbyte.io <sophie.cui@airbyte.io>
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Collaborator

@mwbayley Matt Bayley (mwbayley) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very close! Have you confirmed that the new tests fail without the change to next()? I imagine they do. I was going to suggest adding only 1 test, but now that I think about it, the cases are different. It's probably worth adding a test for the empty array case, too.

sophiecuiy and others added 3 commits March 13, 2026 12:40
Removed comments explaining the test for next() method behavior.
Ensures next() returns false immediately for an empty array and
continues returning false on subsequent calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Collaborator

@mwbayley Matt Bayley (mwbayley) left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@sophiecuiy sophiecuiy merged commit 5a449f4 into main Mar 13, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants