Skip to content

Commit ad0ea4a

Browse files
committed
CSHARP-6017: Merge LeftJoin translation into JoinMethodToPipelineTranslator
1 parent 7b5f277 commit ad0ea4a

3 files changed

Lines changed: 36 additions & 134 deletions

File tree

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ public static TranslatedPipeline Translate(TranslationContext context, Expressio
5151
case "GroupJoin":
5252
return GroupJoinMethodToPipelineTranslator.Translate(context, methodCallExpression);
5353
case "Join":
54-
return JoinMethodToPipelineTranslator.Translate(context, methodCallExpression);
5554
case "LeftJoin":
56-
return LeftJoinMethodToPipelineTranslator.Translate(context, methodCallExpression);
55+
return JoinMethodToPipelineTranslator.Translate(context, methodCallExpression);
5756
case "Lookup":
5857
return LookupMethodToPipelineTranslator.Translate(context, methodCallExpression);
5958
case "OfType":

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright 2010-present MongoDB Inc.
1+
/* Copyright 2010-present MongoDB Inc.
22
*
33
* Licensed under the Apache License, Version 2.0 (the "License");
44
* you may not use this file except in compliance with the License.
@@ -13,6 +13,8 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System.Collections.Generic;
17+
using System.Linq;
1618
using System.Linq.Expressions;
1719
using MongoDB.Bson.Serialization;
1820
using MongoDB.Driver.Linq.Linq3Implementation.Ast;
@@ -34,7 +36,8 @@ public static TranslatedPipeline Translate(TranslationContext context, MethodCal
3436
var method = expression.Method;
3537
var arguments = expression.Arguments;
3638

37-
if (method.Is(QueryableMethod.Join))
39+
var isLeftJoin = method.IsOneOf(MongoQueryableMethod.LeftJoin, QueryableMethod.LeftJoin);
40+
if (isLeftJoin || method.Is(QueryableMethod.Join))
3841
{
3942
var outerExpression = arguments[0];
4043
var innerExpression = arguments[1];
@@ -58,6 +61,11 @@ public static TranslatedPipeline Translate(TranslationContext context, MethodCal
5861
outerSerializer = pipeline.OutputSerializer;
5962
}
6063

64+
if (isLeftJoin)
65+
{
66+
ThrowIfReservedFieldNames(expression, outerSerializer);
67+
}
68+
6169
var wrapOuterStage = AstStage.Project(
6270
AstProject.Set("_outer", outerAst),
6371
AstProject.Exclude("_id"));
@@ -73,7 +81,7 @@ public static TranslatedPipeline Translate(TranslationContext context, MethodCal
7381
foreignField,
7482
@as: "_inner");
7583

76-
var unwindStage = AstStage.Unwind("_inner");
84+
var unwindStage = AstStage.Unwind("_inner", preserveNullAndEmptyArrays: isLeftJoin);
7785

7886
var outerParameter = resultSelectorLambda.Parameters[0];
7987
var outerField = AstExpression.GetField(AstExpression.RootVar, "_outer");
@@ -97,5 +105,29 @@ public static TranslatedPipeline Translate(TranslationContext context, MethodCal
97105

98106
throw new ExpressionNotSupportedException(expression);
99107
}
108+
109+
private static readonly HashSet<string> __reservedFieldNames = new HashSet<string> { "_outer", "_inner" };
110+
111+
private static void ThrowIfReservedFieldNames(MethodCallExpression expression, IBsonSerializer serializer)
112+
{
113+
if (serializer is not IBsonDocumentSerializer documentSerializer)
114+
return;
115+
116+
var conflicting = new List<string>();
117+
foreach (var member in serializer.ValueType.GetMembers())
118+
{
119+
if (documentSerializer.TryGetMemberSerializationInfo(member.Name, out var info) &&
120+
__reservedFieldNames.Contains(info.ElementName))
121+
{
122+
conflicting.Add(info.ElementName);
123+
}
124+
}
125+
126+
if (conflicting.Count > 0)
127+
{
128+
throw new ExpressionNotSupportedException(expression,
129+
because: $"the outer document type uses reserved field name(s) {string.Join(", ", conflicting.Select(n => $"'{n}'"))} which are used internally by LeftJoin");
130+
}
131+
}
100132
}
101133
}

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

Lines changed: 0 additions & 129 deletions
This file was deleted.

0 commit comments

Comments
 (0)