Skip to content

Commit 420df13

Browse files
jmikolaajdavis
authored andcommitted
CDRIVER-1054: Support negative cursor limit
This adds internal support for specifying a negative cursor limit (i.e. single-batch mode) for both OP_QUERY and find command code paths. Note that this does not change the public API, which will be handled for 2.0 by CDRIVER-1053.
1 parent ab08255 commit 420df13

File tree

3 files changed

+30
-7
lines changed

3 files changed

+30
-7
lines changed

src/mongoc/mongoc-cursor-private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ struct _mongoc_cursor_t
7070

7171
mongoc_query_flags_t flags;
7272
uint32_t skip;
73-
uint32_t limit;
73+
int32_t limit;
7474
uint32_t count;
7575
uint32_t batch_size;
7676
uint32_t max_await_time_ms;
@@ -96,7 +96,7 @@ mongoc_cursor_t * _mongoc_cursor_new (mongoc_client_t
9696
const char *db_and_collection,
9797
mongoc_query_flags_t flags,
9898
uint32_t skip,
99-
uint32_t limit,
99+
int32_t limit,
100100
uint32_t batch_size,
101101
bool is_command,
102102
const bson_t *query,

src/mongoc/mongoc-cursor.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ _mongoc_n_return (mongoc_cursor_t * cursor)
4747
if (cursor->is_command) {
4848
/* commands always have n_return of 1 */
4949
return 1;
50+
} else if (cursor->limit < 0) {
51+
return cursor->limit;
5052
} else if (cursor->limit) {
5153
int32_t remaining = cursor->limit - cursor->count;
5254
BSON_ASSERT (remaining > 0);
@@ -67,7 +69,7 @@ _mongoc_cursor_new (mongoc_client_t *client,
6769
const char *db_and_collection,
6870
mongoc_query_flags_t qflags,
6971
uint32_t skip,
70-
uint32_t limit,
72+
int32_t limit,
7173
uint32_t batch_size,
7274
bool is_command,
7375
const bson_t *query,
@@ -738,7 +740,11 @@ _mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor,
738740
}
739741

740742
if (cursor->limit) {
741-
bson_append_int64 (command, "limit", 5, cursor->limit);
743+
if (cursor->limit < 0) {
744+
bson_append_bool (command, "singleBatch", 11, true);
745+
}
746+
747+
bson_append_int64 (command, "limit", 5, labs(cursor->limit));
742748
}
743749

744750
if (cursor->batch_size) {
@@ -1035,7 +1041,7 @@ _mongoc_cursor_next (mongoc_cursor_t *cursor,
10351041
* If we reached our limit, make sure we mark this as done and do not try to
10361042
* make further progress.
10371043
*/
1038-
if (cursor->limit && cursor->count >= cursor->limit) {
1044+
if (cursor->limit && cursor->count >= labs(cursor->limit)) {
10391045
cursor->done = true;
10401046
RETURN (false);
10411047
}

tests/test-mongoc-collection-find.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ typedef struct
2424
bson_t *fields_bson;
2525
const char *expected_find_command;
2626
const char *expected_op_query;
27-
uint32_t n_return;
27+
int32_t n_return;
2828
const char *expected_result;
2929
bson_t *expected_result_bson;
3030
uint32_t skip;
31-
uint32_t limit;
31+
int32_t limit;
3232
uint32_t batch_size;
3333
mongoc_query_flags_t flags;
3434
mongoc_read_prefs_t *read_prefs;
@@ -687,6 +687,21 @@ test_limit (void)
687687
}
688688

689689

690+
static void
691+
test_negative_limit (void)
692+
{
693+
test_collection_find_t test_data = TEST_COLLECTION_FIND_INIT;
694+
test_data.docs = "[{'_id': 1}, {'_id': 2}, {'_id': 3}]";
695+
test_data.limit = -2;
696+
test_data.query_input = "{'$query': {}, '$orderby': {'_id': 1}}";
697+
test_data.expected_op_query = test_data.query_input;
698+
test_data.n_return = -2;
699+
test_data.expected_find_command = "{'find': 'collection', 'filter': {}, 'sort': {'_id': 1}, 'singleBatch': true, 'limit': {'$numberLong': '2'}}";
700+
test_data.expected_result = "[{'_id': 1}, {'_id': 2}]";
701+
_test_collection_find (&test_data);
702+
}
703+
704+
690705
static void
691706
test_unrecognized_dollar_option (void)
692707
{
@@ -1016,6 +1031,8 @@ test_collection_find_install (TestSuite *suite)
10161031
test_batch_size);
10171032
TestSuite_Add (suite, "/Collection/find/limit",
10181033
test_limit);
1034+
TestSuite_Add (suite, "/Collection/find/negative_limit",
1035+
test_negative_limit);
10191036
TestSuite_Add (suite, "/Collection/find/unrecognized",
10201037
test_unrecognized_dollar_option);
10211038
TestSuite_Add (suite, "/Collection/find/flags",

0 commit comments

Comments
 (0)