Skip to content

Commit 9ee2eef

Browse files
CSHARP-3075: Collection Aggregation Merge Default Value Throws an Exception
1 parent 2001ded commit 9ee2eef

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

src/MongoDB.Driver/MongoCollectionImpl.cs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -806,19 +806,34 @@ private FindOperation<TResult> CreateAggregateToCollectionFindOperation<TResult>
806806
break;
807807
case "$merge":
808808
{
809-
var mergeArguments = outStage[0].AsBsonDocument;
809+
var mergeArguments = outStage[0];
810810
DatabaseNamespace outputDatabaseNamespace;
811811
string outputCollectionName;
812-
var into = mergeArguments["into"];
813-
if (into.IsString)
812+
if (mergeArguments.IsString)
814813
{
815814
outputDatabaseNamespace = _collectionNamespace.DatabaseNamespace;
816-
outputCollectionName = into.AsString;
815+
outputCollectionName = mergeArguments.AsString;
817816
}
818817
else
819818
{
820-
outputDatabaseNamespace = new DatabaseNamespace(into["db"].AsString);
821-
outputCollectionName = into["coll"].AsString;
819+
var into = mergeArguments.AsBsonDocument["into"];
820+
if (into.IsString)
821+
{
822+
outputDatabaseNamespace = _collectionNamespace.DatabaseNamespace;
823+
outputCollectionName = into.AsString;
824+
}
825+
else
826+
{
827+
if (into.AsBsonDocument.Contains("db"))
828+
{
829+
outputDatabaseNamespace = new DatabaseNamespace(into["db"].AsString);
830+
}
831+
else
832+
{
833+
outputDatabaseNamespace = _collectionNamespace.DatabaseNamespace;
834+
}
835+
outputCollectionName = into["coll"].AsString;
836+
}
822837
}
823838
outputCollectionNamespace = new CollectionNamespace(outputDatabaseNamespace, outputCollectionName);
824839
}

tests/MongoDB.Driver.Tests/MongoCollectionImplTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,62 @@ public void Aggregate_should_execute_an_AggregateToCollectionOperation_and_a_Fin
258258
findOperation.Sort.Should().BeNull();
259259
}
260260

261+
[Theory]
262+
[InlineData("{ $merge : \"outputcollection\" }", null, "outputcollection", false)]
263+
[InlineData("{ $merge : \"outputcollection\" }", null, "outputcollection", true)]
264+
[InlineData("{ $merge : { into : \"outputcollection\" } }", null, "outputcollection", false)]
265+
[InlineData("{ $merge : { into : \"outputcollection\" } }", null, "outputcollection", true)]
266+
[InlineData("{ $merge : { into : { coll : \"outputcollection\" } } }", null, "outputcollection", false)]
267+
[InlineData("{ $merge : { into : { coll : \"outputcollection\" } } }", null, "outputcollection", true)]
268+
[InlineData("{ $merge : { into : { db: \"outputdatabase\", coll : \"outputcollection\" } } }", "outputdatabase", "outputcollection", false)]
269+
[InlineData("{ $merge : { into : { db: \"outputdatabase\", coll : \"outputcollection\" } } }", "outputdatabase", "outputcollection", true)]
270+
public void Aggregate_should_recognize_merge_collection_argument(
271+
string stageDefinitionString,
272+
string expectedDatabaseName,
273+
string expectedCollectionName,
274+
bool async)
275+
{
276+
var subject = CreateSubject<BsonDocument>();
277+
var stageDefinition = BsonDocument.Parse(stageDefinitionString);
278+
var expectedCollectionNamespace = new CollectionNamespace(
279+
expectedDatabaseName ?? subject.CollectionNamespace.DatabaseNamespace.DatabaseName,
280+
expectedCollectionName);
281+
282+
var pipeline = new EmptyPipelineDefinition<BsonDocument>()
283+
.AppendStage<BsonDocument, BsonDocument, BsonDocument>(stageDefinition);
284+
var expectedPipeline = new List<BsonDocument>(RenderPipeline(subject, pipeline).Documents);
285+
286+
IAsyncCursor<BsonDocument> result;
287+
if (async)
288+
{
289+
result = subject.AggregateAsync(pipeline).GetAwaiter().GetResult();
290+
}
291+
else
292+
{
293+
result = subject.Aggregate(pipeline);
294+
}
295+
var aggregateCall = _operationExecutor.GetWriteCall<BsonDocument>();
296+
297+
var aggregateOperation = aggregateCall.Operation.Should().BeOfType<AggregateToCollectionOperation>().Subject;
298+
aggregateOperation.CollectionNamespace.Should().Be(subject.CollectionNamespace);
299+
aggregateOperation.Pipeline.Should().Equal(expectedPipeline);
300+
301+
var mockCursor = new Mock<IAsyncCursor<BsonDocument>>();
302+
_operationExecutor.EnqueueResult(mockCursor.Object);
303+
if (async)
304+
{
305+
result.MoveNextAsync().GetAwaiter().GetResult();
306+
}
307+
else
308+
{
309+
result.MoveNext();
310+
}
311+
var findCall = _operationExecutor.GetReadCall<IAsyncCursor<BsonDocument>>();
312+
313+
var findOperation = findCall.Operation.Should().BeOfType<FindOperation<BsonDocument>>().Subject;
314+
findOperation.CollectionNamespace.Should().Be(expectedCollectionNamespace);
315+
}
316+
261317
[Theory]
262318
[ParameterAttributeData]
263319
public void AggregateToCollection_should_execute_an_AggregateToCollectionOperation(

0 commit comments

Comments
 (0)