Skip to content

Commit f537927

Browse files
benjirewisBenjamin Rewis
authored andcommitted
GODRIVER-1831 Avoid accidental extra getMore when using limit on Find (#562)
1 parent de35f93 commit f537927

File tree

2 files changed

+98
-1
lines changed

2 files changed

+98
-1
lines changed

mongo/integration/collection_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,103 @@ func TestCollection(t *testing.T) {
883883
_, ok := err.(mongo.CommandError)
884884
assert.True(mt, ok, "expected error type %v, got %v", mongo.CommandError{}, err)
885885
})
886+
mt.Run("limit and batch size and skip", func(mt *mtest.T) {
887+
testCases := []struct {
888+
limit int64
889+
batchSize int32
890+
skip int64
891+
name string
892+
}{
893+
{
894+
99, 100, 10,
895+
"case 1",
896+
},
897+
{
898+
100, 100, 20,
899+
"case 2",
900+
},
901+
{
902+
80, 20, 90,
903+
"case 3",
904+
},
905+
{
906+
201, 201, 0,
907+
"case 4",
908+
},
909+
{
910+
100, 200, 120,
911+
"case 5",
912+
},
913+
}
914+
for _, tc := range testCases {
915+
mt.Run(tc.name, func(mt *mtest.T) {
916+
var insertDocs []interface{}
917+
for i := 1; i <= 201; i++ {
918+
insertDocs = append(insertDocs, bson.D{{"x", int32(i)}})
919+
}
920+
921+
_, err := mt.Coll.InsertMany(mtest.Background, insertDocs)
922+
assert.Nil(mt, err, "InsertMany error for initial data: %v", err)
923+
924+
findOptions := options.Find().SetLimit(tc.limit).SetBatchSize(tc.batchSize).
925+
SetSkip(tc.skip)
926+
cursor, err := mt.Coll.Find(mtest.Background, bson.D{}, findOptions)
927+
assert.Nil(mt, err, "Find error: %v", err)
928+
929+
var docs []interface{}
930+
err = cursor.All(mtest.Background, &docs)
931+
assert.Nil(mt, err, "All error: %v", err)
932+
if (201 - tc.skip) < tc.limit {
933+
assert.Equal(mt, int(201-tc.skip), len(docs), "expected number of docs to be %v, got %v", int(201-tc.skip), len(docs))
934+
} else {
935+
assert.Equal(mt, int(tc.limit), len(docs), "expected number of docs to be %v, got %v", tc.limit, len(docs))
936+
}
937+
})
938+
}
939+
})
940+
mt.Run("unset batch size does not surpass limit", func(mt *mtest.T) {
941+
testCases := []struct {
942+
limit int64
943+
name string
944+
}{
945+
{
946+
99,
947+
"99",
948+
},
949+
{
950+
100,
951+
"100",
952+
},
953+
{
954+
101,
955+
"101",
956+
},
957+
{
958+
200,
959+
"200",
960+
},
961+
}
962+
for _, tc := range testCases {
963+
mt.Run(tc.name, func(mt *mtest.T) {
964+
var insertDocs []interface{}
965+
for i := 1; i <= 201; i++ {
966+
insertDocs = append(insertDocs, bson.D{{"x", int32(i)}})
967+
}
968+
969+
_, err := mt.Coll.InsertMany(mtest.Background, insertDocs)
970+
assert.Nil(mt, err, "InsertMany error for initial data: %v", err)
971+
opts := options.Find().SetSkip(0).SetLimit(tc.limit)
972+
cursor, err := mt.Coll.Find(mtest.Background, bson.D{}, opts)
973+
assert.Nil(mt, err, "Find error with limit %v: %v", tc.limit, err)
974+
975+
var docs []interface{}
976+
err = cursor.All(mtest.Background, &docs)
977+
assert.Nil(mt, err, "All error with limit %v: %v", tc.limit, err)
978+
979+
assert.Equal(mt, int(tc.limit), len(docs), "expected number of docs to be %v, got %v", tc.limit, len(docs))
980+
})
981+
}
982+
})
886983
})
887984
mt.RunOpts("find one", noClientOpts, func(mt *mtest.T) {
888985
mt.Run("limit", func(mt *mtest.T) {

x/mongo/driver/batch_cursor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ func (bc *BatchCursor) getMore(ctx context.Context) {
241241

242242
// Required for legacy operations which don't support limit.
243243
numToReturn := bc.batchSize
244-
if bc.limit != 0 && bc.numReturned+bc.batchSize > bc.limit {
244+
if bc.limit != 0 && bc.numReturned+bc.batchSize >= bc.limit {
245245
numToReturn = bc.limit - bc.numReturned
246246
if numToReturn <= 0 {
247247
err := bc.Close(ctx)

0 commit comments

Comments
 (0)