fix(finisher_api): resolve FindInBatches cursor primary key from dest schema - #7820
Open
wbrunovieira wants to merge 1 commit into
Open
Conversation
… schema
FindInBatches builds its batch cursor by reading the primary key of the last
scanned row through Statement.Schema. When a different Model is set (e.g.
Model(A).FindInBatches(&[]B{})), Statement.Schema describes A, whose field index
does not apply to B, so the read returns the wrong field (panic "reflect: Field
index out of range" on older versions, "sql: unsupported type ..." on master),
breaking pagination.
Resolve the primary field from dest's own schema, matched by the Model's
primary-key column name so the cursor value stays in sync with the ORDER BY /
comparison column. Mirrors how Scan already re-parses a mismatched dest. When
dest has no field for that column, fail with ErrPrimaryKeyRequired.
Adds a regression test covering []B and []*B destinations.
Closes go-gorm#7737
wbrunovieira
force-pushed
the
fix/7737-findinbatches-model-dest-mismatch
branch
from
July 6, 2026 21:10
40f63d0 to
b6be0cb
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What this fixes
Model(A).FindInBatches(&[]B{}, ...)— whereBembedsAbut has a different field layout — panics withreflect: Field index out of range(v1.31.1) or, on current master, returnssql: converting argument $2 type: unsupported type gorm.Model, a structand breaks pagination.Reproduction: #7737 (playground: go-gorm/playground#848).
Root cause
The batch cursor reads the primary key of the last scanned row via
result.Statement.Schema.PrioritizedPrimaryField.ValueOf(...). When aModelis set,Statement.Schemais the Model's schema, whose fieldIndexpath does not apply to the destination's element type — so the read resolves the wrong field (a whole embedded struct, or an out-of-range index).The scan path already handles this by re-parsing the schema from
destwhen the element type differs from the Model type (scan.go:212-214).FindInBatcheswas the one place still reading the cursor value through the Model schema.Fix
Resolve the cursor's primary field from the destination's own schema, matched by the Model's primary-key column name (
LookUpField(DBName)), so the value always corresponds to the same column used in theORDER BY/>comparison (which is built from the Model schema). The common case (dest type == Model type) keeps the Model's field unchanged. Ifdesthas no field for that column there is no valid cursor, so it fails withErrPrimaryKeyRequiredinstead of risking a wrong-index read.Tests
TestFindInBatchesModelDestMismatch(intests/) covers[]Band[]*Bdestinations and asserts every row is paged exactly once (no duplicate, no skip) across batches withbatchSize < total. It fails without the fix (the exact#7737error) and passes with it.Closes #7737