You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In resultPageIterator.HasNext(), when a fetched page has HasMoreRows == false,
the code calls rpf.Close() to close the operation handle on the server but never
sets rpf.isFinished = true.
After Next() consumes that last page and clears nextResultPage, any subsequent
call to HasNext() bypasses the early-exit guard at the top of the function
(which checks isFinished && nextResultPage == nil) and falls through to getNextPage(). Since isFinished is still false, getNextPage() proceeds to
issue a FetchResults RPC against an already-closed operation handle, resulting
in a spurious server-side error instead of a clean io.EOF.
Fix
Set rpf.isFinished = true alongside rpf.Close() in the no-more-rows branch,
mirroring what the error path in the same function already does correctly:
Any caller that invokes HasNext() more than once after the last page is consumed
— a reasonable and common pattern — would previously receive an unexpected RPC
error. After this fix they receive false / io.EOF as intended.
This change is functionally a no-op — rpf.isFinished is already true by the time we reach line 137.
Tracing HasNext → getNextPage: the fetch loop at line 177 always runs at least once (the loop entry condition !Contains(Start()+Count()) is always true because Contains uses an inclusive [start, end] range and Start()+Count() == end+1), and lines 202–205 unconditionally write rpf.isFinished from HasMoreRows. So when control returns to HasNext and we enter the !nrp.GetHasMoreRows() branch, isFinished is already true.
The early-exit guard at line 117 (if rpf.isFinished && rpf.nextResultPage == nil) therefore already short-circuits any subsequent HasNext() after the final page is consumed — no spurious FetchResults RPC, no server error. I can't construct a path on main where the described bug actually fires; do you have a concrete repro (stack trace, server log showing FetchResults after CloseOperation, or a failing test)?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In
resultPageIterator.HasNext(), when a fetched page hasHasMoreRows == false,the code calls
rpf.Close()to close the operation handle on the server but neversets
rpf.isFinished = true.After
Next()consumes that last page and clearsnextResultPage, any subsequentcall to
HasNext()bypasses the early-exit guard at the top of the function(which checks
isFinished && nextResultPage == nil) and falls through togetNextPage(). SinceisFinishedis stillfalse,getNextPage()proceeds toissue a
FetchResultsRPC against an already-closed operation handle, resultingin a spurious server-side error instead of a clean
io.EOF.Fix
Set
rpf.isFinished = truealongsiderpf.Close()in the no-more-rows branch,mirroring what the error path in the same function already does correctly:
Impact
Any caller that invokes
HasNext()more than once after the last page is consumed— a reasonable and common pattern — would previously receive an unexpected RPC
error. After this fix they receive
false/io.EOFas intended.