Skip to content

Commit 701dc20

Browse files
committed
CSHARP-4445: Support 64-bit values for Skip and Limit/Take.
1 parent 5ebe18f commit 701dc20

File tree

10 files changed

+344
-14
lines changed

10 files changed

+344
-14
lines changed

src/MongoDB.Driver/AggregateFluent.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public override IAggregateFluent<TNewResult> Group<TNewResult>(ProjectionDefinit
146146
return WithPipeline(_pipeline.Group(group));
147147
}
148148

149-
public override IAggregateFluent<TResult> Limit(int limit)
149+
public override IAggregateFluent<TResult> Limit(long limit)
150150
{
151151
return WithPipeline(_pipeline.Limit(limit));
152152
}
@@ -259,7 +259,7 @@ public override IAggregateFluent<BsonDocument> SetWindowFields<TPartitionBy, TWi
259259
return WithPipeline(_pipeline.SetWindowFields(partitionBy, sortBy, output));
260260
}
261261

262-
public override IAggregateFluent<TResult> Skip(int skip)
262+
public override IAggregateFluent<TResult> Skip(long skip)
263263
{
264264
return WithPipeline(_pipeline.Skip(skip));
265265
}

src/MongoDB.Driver/AggregateFluentBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public virtual IAggregateFluent<TNewResult> GraphLookup<TFrom, TConnectFrom, TCo
141141
public abstract IAggregateFluent<TNewResult> Group<TNewResult>(ProjectionDefinition<TResult, TNewResult> group);
142142

143143
/// <inheritdoc />
144-
public abstract IAggregateFluent<TResult> Limit(int limit);
144+
public abstract IAggregateFluent<TResult> Limit(long limit);
145145

146146
/// <inheritdoc />
147147
public virtual IAggregateFluent<TNewResult> Lookup<TForeignDocument, TNewResult>(string foreignCollectionName, FieldDefinition<TResult> localField, FieldDefinition<TForeignDocument> foreignField, FieldDefinition<TNewResult> @as, AggregateLookupOptions<TForeignDocument, TNewResult> options)
@@ -240,7 +240,7 @@ public virtual IAggregateFluent<BsonDocument> SetWindowFields<TPartitionBy, TWin
240240
}
241241

242242
/// <inheritdoc />
243-
public abstract IAggregateFluent<TResult> Skip(int skip);
243+
public abstract IAggregateFluent<TResult> Skip(long skip);
244244

245245
/// <inheritdoc />
246246
public abstract IAggregateFluent<TResult> Sort(SortDefinition<TResult> sort);

src/MongoDB.Driver/IAggregateFluent.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ IAggregateFluent<TNewResult> GraphLookup<TFrom, TConnectFrom, TConnectTo, TStart
215215
/// </summary>
216216
/// <param name="limit">The limit.</param>
217217
/// <returns>The fluent aggregate interface.</returns>
218-
IAggregateFluent<TResult> Limit(int limit);
218+
IAggregateFluent<TResult> Limit(long limit);
219219

220220
/// <summary>
221221
/// Appends a lookup stage to the pipeline.
@@ -384,7 +384,7 @@ IAggregateFluent<BsonDocument> SetWindowFields<TPartitionBy, TWindowFields>(
384384
/// </summary>
385385
/// <param name="skip">The number of documents to skip.</param>
386386
/// <returns>The fluent aggregate interface.</returns>
387-
IAggregateFluent<TResult> Skip(int skip);
387+
IAggregateFluent<TResult> Skip(long skip);
388388

389389
/// <summary>
390390
/// Appends a sort stage to the pipeline.

src/MongoDB.Driver/Linq/Linq3Implementation/Reflection/MongoQueryableMethod.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ internal static class MongoQueryableMethod
6868
private static readonly MethodInfo __singleOrDefaultAsync;
6969
private static readonly MethodInfo __singleOrDefaultWithPredicateAsync;
7070
private static readonly MethodInfo __singleWithPredicateAsync;
71+
private static readonly MethodInfo __skipWithLong;
7172
private static readonly MethodInfo __standardDeviationPopulationDecimal;
7273
private static readonly MethodInfo __standardDeviationPopulationDecimalAsync;
7374
private static readonly MethodInfo __standardDeviationPopulationDecimalWithSelector;
@@ -168,6 +169,7 @@ internal static class MongoQueryableMethod
168169
private static readonly MethodInfo __sumNullableSingleWithSelectorAsync;
169170
private static readonly MethodInfo __sumSingleAsync;
170171
private static readonly MethodInfo __sumSingleWithSelectorAsync;
172+
private static readonly MethodInfo __takeWithLong;
171173

172174
// static constructor
173175
static MongoQueryableMethod()
@@ -215,6 +217,7 @@ static MongoQueryableMethod()
215217
__singleOrDefaultAsync = ReflectionInfo.Method((IMongoQueryable<object> source, CancellationToken cancellationToken) => source.SingleOrDefaultAsync(cancellationToken));
216218
__singleOrDefaultWithPredicateAsync = ReflectionInfo.Method((IMongoQueryable<object> source, Expression<Func<object, bool>> predicate, CancellationToken cancellationToken) => source.SingleOrDefaultAsync(predicate, cancellationToken));
217219
__singleWithPredicateAsync = ReflectionInfo.Method((IMongoQueryable<object> source, Expression<Func<object, bool>> predicate, CancellationToken cancellationToken) => source.SingleAsync(predicate, cancellationToken));
220+
__skipWithLong = ReflectionInfo.Method((IMongoQueryable<object> source, long count) => source.Skip(count));
218221
__standardDeviationPopulationDecimal = ReflectionInfo.Method((IMongoQueryable<decimal> source) => source.StandardDeviationPopulation());
219222
__standardDeviationPopulationDecimalAsync = ReflectionInfo.Method((IMongoQueryable<decimal> source, CancellationToken cancellationToken) => source.StandardDeviationPopulationAsync(cancellationToken));
220223
__standardDeviationPopulationDecimalWithSelector = ReflectionInfo.Method((IMongoQueryable<object> source, Expression<Func<object, decimal>> selector) => source.StandardDeviationPopulation(selector));
@@ -315,6 +318,7 @@ static MongoQueryableMethod()
315318
__sumNullableSingleWithSelectorAsync = ReflectionInfo.Method((IMongoQueryable<object> source, Expression<Func<object, float?>> selector, CancellationToken cancellationToken) => source.SumAsync(selector, cancellationToken));
316319
__sumSingleAsync = ReflectionInfo.Method((IMongoQueryable<float> source, CancellationToken cancellationToken) => source.SumAsync(cancellationToken));
317320
__sumSingleWithSelectorAsync = ReflectionInfo.Method((IMongoQueryable<object> source, Expression<Func<object, float>> selector, CancellationToken cancellationToken) => source.SumAsync(selector, cancellationToken));
321+
__takeWithLong = ReflectionInfo.Method((IMongoQueryable<object> source, long count) => source.Take(count));
318322
}
319323

320324
// public properties
@@ -361,6 +365,7 @@ static MongoQueryableMethod()
361365
public static MethodInfo SingleOrDefaultAsync => __singleOrDefaultAsync;
362366
public static MethodInfo SingleOrDefaultWithPredicateAsync => __singleOrDefaultWithPredicateAsync;
363367
public static MethodInfo SingleWithPredicateAsync => __singleWithPredicateAsync;
368+
public static MethodInfo SkipWithLong => __skipWithLong;
364369
public static MethodInfo StandardDeviationPopulationDecimal => __standardDeviationPopulationDecimal;
365370
public static MethodInfo StandardDeviationPopulationDecimalAsync => __standardDeviationPopulationDecimalAsync;
366371
public static MethodInfo StandardDeviationPopulationDecimalWithSelector => __standardDeviationPopulationDecimalWithSelector;
@@ -461,5 +466,6 @@ static MongoQueryableMethod()
461466
public static MethodInfo SumNullableSingleWithSelectorAsync => __sumNullableSingleWithSelectorAsync;
462467
public static MethodInfo SumSingleAsync => __sumSingleAsync;
463468
public static MethodInfo SumSingleWithSelectorAsync => __sumSingleWithSelectorAsync;
469+
public static MethodInfo TakeWithLong => __takeWithLong;
464470
}
465471
}

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/SkipMethodToPipelineTranslator.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@ public static AstPipeline Translate(TranslationContext context, MethodCallExpres
3030
var method = expression.Method;
3131
var arguments = expression.Arguments;
3232

33-
if (method.Is(QueryableMethod.Skip))
33+
if (method.IsOneOf(QueryableMethod.Skip, MongoQueryableMethod.SkipWithLong))
3434
{
3535
var sourceExpression = arguments[0];
36+
if (method.Is(MongoQueryableMethod.SkipWithLong))
37+
{
38+
sourceExpression = ConvertHelper.RemoveConvertToMongoQueryable(arguments[0]);
39+
}
3640
var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression);
3741

3842
var countExpression = arguments[1];
39-
var count = countExpression.GetConstantValue<int>(containingExpression: expression);
43+
var count = method.Is(MongoQueryableMethod.SkipWithLong) ?
44+
countExpression.GetConstantValue<long>(containingExpression: expression) :
45+
countExpression.GetConstantValue<int>(containingExpression: expression);
4046

4147
pipeline = pipeline.AddStages(
4248
pipeline.OutputSerializer,

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/TakeMethodToPipelineTranslator.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@ public static AstPipeline Translate(TranslationContext context, MethodCallExpres
3030
var method = expression.Method;
3131
var arguments = expression.Arguments;
3232

33-
if (method.Is(QueryableMethod.Take))
33+
if (method.IsOneOf(QueryableMethod.Take, MongoQueryableMethod.TakeWithLong))
3434
{
3535
var sourceExpression = arguments[0];
36+
if (method.Is(MongoQueryableMethod.TakeWithLong))
37+
{
38+
sourceExpression = ConvertHelper.RemoveConvertToMongoQueryable(arguments[0]);
39+
}
3640
var pipeline = ExpressionToPipelineTranslator.Translate(context, sourceExpression);
3741

3842
var countExpression = arguments[1];
39-
var count = countExpression.GetConstantValue<int>(containingExpression: expression);
43+
var count = method.Is(MongoQueryableMethod.TakeWithLong) ?
44+
countExpression.GetConstantValue<long>(containingExpression: expression) :
45+
countExpression.GetConstantValue<int>(containingExpression: expression);
4046

4147
pipeline = pipeline.AddStages(
4248
pipeline.OutputSerializer,

src/MongoDB.Driver/Linq/MongoQueryable.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,27 @@ public static IMongoQueryable<TSource> Skip<TSource>(this IMongoQueryable<TSourc
12751275
return (IMongoQueryable<TSource>)Queryable.Skip(source, count);
12761276
}
12771277

1278+
/// <summary>
1279+
/// Bypasses a specified number of elements in a sequence and then returns the
1280+
/// remaining elements.
1281+
/// </summary>
1282+
/// <typeparam name="TSource">The type of the elements of source</typeparam>
1283+
/// <param name="source">An <see cref="IMongoQueryable{TSource}"/> to return elements from.</param>
1284+
/// <param name="count">The number of elements to skip before returning the remaining elements.</param>
1285+
/// <returns>
1286+
/// An <see cref="IMongoQueryable{TSource}"/> that contains elements that occur after the
1287+
/// specified index in the input sequence.
1288+
/// </returns>
1289+
public static IMongoQueryable<TSource> Skip<TSource>(this IMongoQueryable<TSource> source, long count)
1290+
{
1291+
return (IMongoQueryable<TSource>)source.Provider.CreateQuery<TSource>(
1292+
Expression.Call(
1293+
null,
1294+
GetMethodInfo(Skip, source, count),
1295+
Expression.Convert(source.Expression, typeof(IMongoQueryable<TSource>)),
1296+
Expression.Constant(count)));
1297+
}
1298+
12781299
/// <summary>
12791300
/// Computes the population standard deviation of a sequence of values.
12801301
/// </summary>
@@ -3302,6 +3323,26 @@ public static IMongoQueryable<TSource> Take<TSource>(this IMongoQueryable<TSourc
33023323
return (IMongoQueryable<TSource>)Queryable.Take(source, count);
33033324
}
33043325

3326+
/// <summary>
3327+
/// Returns a specified number of contiguous elements from the start of a sequence.
3328+
/// </summary>
3329+
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
3330+
/// <param name="source">The sequence to return elements from.</param>
3331+
/// <param name="count">The number of elements to return.</param>
3332+
/// <returns>
3333+
/// An <see cref="IMongoQueryable{TSource}"/> that contains the specified number of elements
3334+
/// from the start of source.
3335+
/// </returns>
3336+
public static IMongoQueryable<TSource> Take<TSource>(this IMongoQueryable<TSource> source, long count)
3337+
{
3338+
return (IMongoQueryable<TSource>)source.Provider.CreateQuery<TSource>(
3339+
Expression.Call(
3340+
null,
3341+
GetMethodInfo(Take, source, count),
3342+
Expression.Convert(source.Expression, typeof(IMongoQueryable<TSource>)),
3343+
Expression.Constant(count)));
3344+
}
3345+
33053346
/// <summary>
33063347
/// Performs a subsequent ordering of the elements in a sequence in ascending
33073348
/// order according to a key.

src/MongoDB.Driver/PipelineDefinitionBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ public static PipelineDefinition<TInput, TOutput> GroupForLinq3<TInput, TInterme
793793
/// </returns>
794794
public static PipelineDefinition<TInput, TOutput> Limit<TInput, TOutput>(
795795
this PipelineDefinition<TInput, TOutput> pipeline,
796-
int limit)
796+
long limit)
797797
{
798798
Ensure.IsNotNull(pipeline, nameof(pipeline));
799799
return pipeline.AppendStage(PipelineStageDefinitionBuilder.Limit<TOutput>(limit));
@@ -1299,7 +1299,7 @@ public static PipelineDefinition<TInput, BsonDocument> SetWindowFields<TInput, T
12991299
/// </returns>
13001300
public static PipelineDefinition<TInput, TOutput> Skip<TInput, TOutput>(
13011301
this PipelineDefinition<TInput, TOutput> pipeline,
1302-
int skip)
1302+
long skip)
13031303
{
13041304
Ensure.IsNotNull(pipeline, nameof(pipeline));
13051305
return pipeline.AppendStage(PipelineStageDefinitionBuilder.Skip<TOutput>(skip));

src/MongoDB.Driver/PipelineStageDefinitionBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,7 +898,7 @@ public static GroupForLinq3Result<TInput, TValue, TOutput> GroupForLinq3<TInput,
898898
/// <param name="limit">The limit.</param>
899899
/// <returns>The stage.</returns>
900900
public static PipelineStageDefinition<TInput, TInput> Limit<TInput>(
901-
int limit)
901+
long limit)
902902
{
903903
Ensure.IsGreaterThanZero(limit, nameof(limit));
904904
return new BsonDocumentPipelineStageDefinition<TInput, TInput>(new BsonDocument("$limit", limit));
@@ -1579,7 +1579,7 @@ public static PipelineStageDefinition<TInput, BsonDocument> SetWindowFields<TInp
15791579
/// <param name="skip">The skip.</param>
15801580
/// <returns>The stage.</returns>
15811581
public static PipelineStageDefinition<TInput, TInput> Skip<TInput>(
1582-
int skip)
1582+
long skip)
15831583
{
15841584
Ensure.IsGreaterThanOrEqualToZero(skip, nameof(skip));
15851585
return new BsonDocumentPipelineStageDefinition<TInput, TInput>(new BsonDocument("$skip", skip));

0 commit comments

Comments
 (0)