Skip to content

Commit cc9a895

Browse files
rstamBorisDog
authored andcommitted
CSHARP-4445: Support 64-bit values for Skip and Limit/Take.
1 parent 5ce4903 commit cc9a895

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
@@ -147,7 +147,7 @@ public override IAggregateFluent<TNewResult> Group<TNewResult>(ProjectionDefinit
147147
return WithPipeline(_pipeline.Group(group));
148148
}
149149

150-
public override IAggregateFluent<TResult> Limit(int limit)
150+
public override IAggregateFluent<TResult> Limit(long limit)
151151
{
152152
return WithPipeline(_pipeline.Limit(limit));
153153
}
@@ -278,7 +278,7 @@ public override IAggregateFluent<BsonDocument> SetWindowFields<TPartitionBy, TWi
278278
return WithPipeline(_pipeline.SetWindowFields(partitionBy, sortBy, output));
279279
}
280280

281-
public override IAggregateFluent<TResult> Skip(int skip)
281+
public override IAggregateFluent<TResult> Skip(long skip)
282282
{
283283
return WithPipeline(_pipeline.Skip(skip));
284284
}

src/MongoDB.Driver/AggregateFluentBase.cs

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

144144
/// <inheritdoc />
145-
public abstract IAggregateFluent<TResult> Limit(int limit);
145+
public abstract IAggregateFluent<TResult> Limit(long limit);
146146

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

263263
/// <inheritdoc />
264-
public abstract IAggregateFluent<TResult> Skip(int skip);
264+
public abstract IAggregateFluent<TResult> Skip(long skip);
265265

266266
/// <inheritdoc />
267267
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
@@ -216,7 +216,7 @@ IAggregateFluent<TNewResult> GraphLookup<TFrom, TConnectFrom, TConnectTo, TStart
216216
/// </summary>
217217
/// <param name="limit">The limit.</param>
218218
/// <returns>The fluent aggregate interface.</returns>
219-
IAggregateFluent<TResult> Limit(int limit);
219+
IAggregateFluent<TResult> Limit(long limit);
220220

221221
/// <summary>
222222
/// Appends a lookup stage to the pipeline.
@@ -416,7 +416,7 @@ IAggregateFluent<BsonDocument> SetWindowFields<TPartitionBy, TWindowFields>(
416416
/// </summary>
417417
/// <param name="skip">The number of documents to skip.</param>
418418
/// <returns>The fluent aggregate interface.</returns>
419-
IAggregateFluent<TResult> Skip(int skip);
419+
IAggregateFluent<TResult> Skip(long skip);
420420

421421
/// <summary>
422422
/// 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
@@ -1302,6 +1302,27 @@ public static IMongoQueryable<TSource> Skip<TSource>(this IMongoQueryable<TSourc
13021302
return (IMongoQueryable<TSource>)Queryable.Skip(source, count);
13031303
}
13041304

1305+
/// <summary>
1306+
/// Bypasses a specified number of elements in a sequence and then returns the
1307+
/// remaining elements.
1308+
/// </summary>
1309+
/// <typeparam name="TSource">The type of the elements of source</typeparam>
1310+
/// <param name="source">An <see cref="IMongoQueryable{TSource}"/> to return elements from.</param>
1311+
/// <param name="count">The number of elements to skip before returning the remaining elements.</param>
1312+
/// <returns>
1313+
/// An <see cref="IMongoQueryable{TSource}"/> that contains elements that occur after the
1314+
/// specified index in the input sequence.
1315+
/// </returns>
1316+
public static IMongoQueryable<TSource> Skip<TSource>(this IMongoQueryable<TSource> source, long count)
1317+
{
1318+
return (IMongoQueryable<TSource>)source.Provider.CreateQuery<TSource>(
1319+
Expression.Call(
1320+
null,
1321+
GetMethodInfo(Skip, source, count),
1322+
Expression.Convert(source.Expression, typeof(IMongoQueryable<TSource>)),
1323+
Expression.Constant(count)));
1324+
}
1325+
13051326
/// <summary>
13061327
/// Computes the population standard deviation of a sequence of values.
13071328
/// </summary>
@@ -3329,6 +3350,26 @@ public static IMongoQueryable<TSource> Take<TSource>(this IMongoQueryable<TSourc
33293350
return (IMongoQueryable<TSource>)Queryable.Take(source, count);
33303351
}
33313352

3353+
/// <summary>
3354+
/// Returns a specified number of contiguous elements from the start of a sequence.
3355+
/// </summary>
3356+
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
3357+
/// <param name="source">The sequence to return elements from.</param>
3358+
/// <param name="count">The number of elements to return.</param>
3359+
/// <returns>
3360+
/// An <see cref="IMongoQueryable{TSource}"/> that contains the specified number of elements
3361+
/// from the start of source.
3362+
/// </returns>
3363+
public static IMongoQueryable<TSource> Take<TSource>(this IMongoQueryable<TSource> source, long count)
3364+
{
3365+
return (IMongoQueryable<TSource>)source.Provider.CreateQuery<TSource>(
3366+
Expression.Call(
3367+
null,
3368+
GetMethodInfo(Take, source, count),
3369+
Expression.Convert(source.Expression, typeof(IMongoQueryable<TSource>)),
3370+
Expression.Constant(count)));
3371+
}
3372+
33323373
/// <summary>
33333374
/// Performs a subsequent ordering of the elements in a sequence in ascending
33343375
/// order according to a key.

src/MongoDB.Driver/PipelineDefinitionBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ public static PipelineDefinition<TInput, TOutput> GroupForLinq3<TInput, TInterme
794794
/// </returns>
795795
public static PipelineDefinition<TInput, TOutput> Limit<TInput, TOutput>(
796796
this PipelineDefinition<TInput, TOutput> pipeline,
797-
int limit)
797+
long limit)
798798
{
799799
Ensure.IsNotNull(pipeline, nameof(pipeline));
800800
return pipeline.AppendStage(PipelineStageDefinitionBuilder.Limit<TOutput>(limit));
@@ -1351,7 +1351,7 @@ public static PipelineDefinition<TInput, BsonDocument> SetWindowFields<TInput, T
13511351
/// </returns>
13521352
public static PipelineDefinition<TInput, TOutput> Skip<TInput, TOutput>(
13531353
this PipelineDefinition<TInput, TOutput> pipeline,
1354-
int skip)
1354+
long skip)
13551355
{
13561356
Ensure.IsNotNull(pipeline, nameof(pipeline));
13571357
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));
@@ -1653,7 +1653,7 @@ public static PipelineStageDefinition<TInput, BsonDocument> SetWindowFields<TInp
16531653
/// <param name="skip">The skip.</param>
16541654
/// <returns>The stage.</returns>
16551655
public static PipelineStageDefinition<TInput, TInput> Skip<TInput>(
1656-
int skip)
1656+
long skip)
16571657
{
16581658
Ensure.IsGreaterThanOrEqualToZero(skip, nameof(skip));
16591659
return new BsonDocumentPipelineStageDefinition<TInput, TInput>(new BsonDocument("$skip", skip));

0 commit comments

Comments
 (0)