Skip to content

Commit a3d3d4f

Browse files
committed
CSHARP-5448: Refactor AstFilterField and AstPipeline to remove reference to serializers.
1 parent 3906bdc commit a3d3d4f

File tree

95 files changed

+503
-419
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+503
-419
lines changed

src/MongoDB.Driver/FilterDefinitionBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,7 +2165,7 @@ public override BsonDocument Render(RenderArgs<TDocument> args)
21652165
throw new NotSupportedException($"OfType requires that documents of type {BsonUtils.GetFriendlyTypeName(typeof(TDerived))} have a discriminator value.");
21662166
}
21672167

2168-
var discriminatorField = new AstFilterField(discriminatorConvention.ElementName, BsonValueSerializer.Instance);
2168+
var discriminatorField = new AstFilterField(discriminatorConvention.ElementName);
21692169
ofTypeFilter= discriminatorConvention switch
21702170
{
21712171
IHierarchicalDiscriminatorConvention hierarchicalDiscriminatorConvention => DiscriminatorAstFilter.TypeIs(discriminatorField, hierarchicalDiscriminatorConvention, nominalType, actualType),
@@ -2223,7 +2223,7 @@ public override BsonDocument Render(RenderArgs<TDocument> args)
22232223
}
22242224

22252225
var discriminatorElementName = renderedField.FieldName + "." + discriminatorConvention.ElementName;
2226-
var discriminatorField = new AstFilterField(discriminatorElementName, BsonValueSerializer.Instance);
2226+
var discriminatorField = new AstFilterField(discriminatorElementName);
22272227

22282228
ofTypeFilter = discriminatorConvention switch
22292229
{

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/AstPipeline.cs

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*/
1515

1616
using MongoDB.Bson;
17-
using MongoDB.Bson.Serialization;
1817
using MongoDB.Driver.Core.Misc;
1918
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Stages;
2019
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Visitors;
@@ -27,68 +26,39 @@ namespace MongoDB.Driver.Linq.Linq3Implementation.Ast
2726
internal sealed class AstPipeline : AstNode
2827
{
2928
#region static
30-
public static AstPipeline Empty(IBsonSerializer outputSerializer)
31-
{
32-
return new AstPipeline(Enumerable.Empty<AstStage>(), outputSerializer);
33-
}
29+
private static readonly AstPipeline __empty = new AstPipeline([]);
30+
31+
public static AstPipeline Empty => __empty;
3432
#endregion
3533

36-
private IBsonSerializer _outputSerializer;
3734
private readonly IReadOnlyList<AstStage> _stages;
3835

39-
public AstPipeline(IEnumerable<AstStage> stages, IBsonSerializer outputSerializer)
36+
public AstPipeline(IEnumerable<AstStage> stages)
4037
{
4138
_stages = Ensure.IsNotNull(stages, nameof(stages)).AsReadOnlyList();
42-
_outputSerializer = Ensure.IsNotNull(outputSerializer, nameof(outputSerializer));
4339
}
4440

4541
public override AstNodeType NodeType => AstNodeType.Pipeline;
46-
public IBsonSerializer OutputSerializer => _outputSerializer;
4742
public IReadOnlyList<AstStage> Stages => _stages;
4843

4944
public override AstNode Accept(AstNodeVisitor visitor)
5045
{
5146
return visitor.VisitPipeline(this);
5247
}
5348

54-
public AstPipeline AddStages(
55-
IBsonSerializer newOutputSerializer,
56-
params AstStage[] newStages)
57-
{
58-
var stages = _stages.Concat(newStages);
59-
return new AstPipeline(stages, newOutputSerializer);
60-
}
61-
62-
public override BsonValue Render()
49+
public override BsonValue Render()
6350
{
6451
return new BsonArray(_stages.Select(s => s.Render()));
6552
}
6653

67-
public AstPipeline ReplaceLastStage(
68-
IBsonSerializer newOutputSerializer,
69-
AstStage newLastStage)
70-
{
71-
var stages = _stages.Take(_stages.Count - 1).Concat(new[] { newLastStage });
72-
return new AstPipeline(stages, newOutputSerializer);
73-
}
74-
75-
public AstPipeline ReplaceStagesAtEnd(
76-
IBsonSerializer newOutputSerializer,
77-
int numberOfStagesToReplace,
78-
params AstStage[] newStages)
79-
{
80-
var stages = _stages.Take(_stages.Count - numberOfStagesToReplace).Concat(newStages);
81-
return new AstPipeline(stages, newOutputSerializer);
82-
}
83-
8454
public AstPipeline Update(IEnumerable<AstStage> stages)
8555
{
8656
if (stages == _stages)
8757
{
8858
return this;
8959
}
9060

91-
return new AstPipeline(stages, _outputSerializer);
61+
return new AstPipeline(stages);
9262
}
9363
}
9464
}

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Filters/AstFieldOperationFilter.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,6 @@ public AstFieldOperationFilter(AstFilterField field, AstFilterOperation operatio
3131
_field = Ensure.IsNotNull(field, nameof(field));
3232
_operation = Ensure.IsNotNull(operation, nameof(operation));
3333

34-
if (operation.NodeType == AstNodeType.RegexFilterOperation &&
35-
field.Serializer is IRepresentationConfigurable representationConfigurable &&
36-
representationConfigurable.Representation != BsonType.String)
37-
{
38-
// normally an ExpressionNotSupported should have been thrown before reaching here
39-
throw new ArgumentException($"Field must be represented as a string for regex filter operations: {field.Path}", nameof(field));
40-
}
41-
4234
if (_field.Path == "@<current>")
4335
{
4436
throw new ExpressionNotSupportedException("Field path cannot be \"@<current>\" in AstFieldOperationFilter.");

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Filters/AstFilter.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,9 @@ public static AstFilter Expr(AstExpression expression)
134134
return new AstExprFilter(expression);
135135
}
136136

137-
public static AstFilterField Field(string path, IBsonSerializer serializer)
137+
public static AstFilterField Field(string path)
138138
{
139-
return new AstFilterField(path, serializer);
139+
return new AstFilterField(path);
140140
}
141141

142142
public static AstFieldOperationFilter In(AstFilterField field, IEnumerable<BsonValue> values)

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Filters/AstFilterField.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*/
1515

1616
using MongoDB.Bson;
17-
using MongoDB.Bson.Serialization;
1817
using MongoDB.Driver.Core.Misc;
1918
using MongoDB.Driver.Linq.Linq3Implementation.Ast.Visitors;
2019

@@ -23,34 +22,31 @@ namespace MongoDB.Driver.Linq.Linq3Implementation.Ast.Filters
2322
internal sealed class AstFilterField : AstNode
2423
{
2524
private string _path;
26-
private IBsonSerializer _serializer;
2725

28-
public AstFilterField(string path, IBsonSerializer serializer)
26+
public AstFilterField(string path)
2927
{
3028
_path = Ensure.IsNotNull(path, nameof(path));
31-
_serializer = Ensure.IsNotNull(serializer, nameof(serializer));
3229
}
3330

3431
public string Path => _path;
3532
public override AstNodeType NodeType => AstNodeType.FilterField;
36-
public IBsonSerializer Serializer => _serializer;
3733

3834
public override AstNode Accept(AstNodeVisitor visitor)
3935
{
4036
return visitor.VisitFilterField(this);
4137
}
4238

43-
public AstFilterField SubField(string subFieldName, IBsonSerializer subFieldSerializer)
39+
public AstFilterField SubField(string subFieldName)
4440
{
4541
Ensure.IsNotNull(subFieldName, nameof(subFieldName));
4642

4743
if (_path == "@<current>")
4844
{
49-
return new AstFilterField(subFieldName, subFieldSerializer);
45+
return new AstFilterField(subFieldName);
5046
}
5147
else
5248
{
53-
return new AstFilterField(_path + "." + subFieldName, subFieldSerializer);
49+
return new AstFilterField(_path + "." + subFieldName);
5450
}
5551
}
5652

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Optimizers/AstGroupingPipelineOptimizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ public override AstNode VisitFilterField(AstFilterField node)
340340
var accumulatorFieldName = _accumulators.AddAccumulatorExpression(accumulatorExpression);
341341
var restOfPath = node.Path.Substring("_elements.0.".Length);
342342
var rewrittenPath = $"{accumulatorFieldName}.{restOfPath}";
343-
return AstFilter.Field(rewrittenPath, node.Serializer);
343+
return AstFilter.Field(rewrittenPath);
344344
}
345345

346346
if (node.Path == "_elements" || node.Path.StartsWith("_elements."))

src/MongoDB.Driver/Linq/Linq3Implementation/GroupingWithOutputExpressionStageDefinitions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ private AstStage RenderProjectStage(
7373

7474
private IReadOnlyList<AstStage> OptimizeGroupingStages(AstStage groupingStage, AstStage projectStage, IBsonSerializer inputSerializer, IBsonSerializer outputSerializer)
7575
{
76-
var pipeline = AstPipeline.Empty(inputSerializer).AddStages(outputSerializer, groupingStage, projectStage);
76+
var pipeline = new AstPipeline([groupingStage, projectStage]);
7777
var optimizedPipeline = AstPipelineOptimizer.Optimize(pipeline);
7878
return optimizedPipeline.Stages;
7979
}

src/MongoDB.Driver/Linq/Linq3Implementation/Misc/ClientSideProjectionHelper.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ internal static class ClientSideProjectionHelper
2626
// public static methods
2727
public static void ThrowIfClientSideProjection(
2828
Expression expression,
29-
AstPipeline pipeline,
29+
TranslatedPipeline pipeline,
3030
MethodInfo method)
3131
{
3232
if (pipeline.OutputSerializer is IClientSideProjectionDeserializer)
@@ -37,7 +37,7 @@ public static void ThrowIfClientSideProjection(
3737

3838
public static void ThrowIfClientSideProjection(
3939
Expression expression,
40-
AstPipeline pipeline,
40+
TranslatedPipeline pipeline,
4141
MethodInfo method,
4242
string methodOverload)
4343
{

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/DiscriminatorAstFilter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public static AstFilter TypeEquals(AstFilterField discriminatorField, IHierarchi
3737
}
3838
else
3939
{
40-
var discriminatorFieldItemZero = discriminatorField.SubField("0", BsonValueSerializer.Instance);
40+
var discriminatorFieldItemZero = discriminatorField.SubField("0");
4141
return AstFilter.And(
4242
AstFilter.NotExists(discriminatorFieldItemZero), // required to avoid false matches on subclasses
4343
AstFilter.Eq(discriminatorField, discriminator));

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToExecutableQueryTranslators/ContainsMethodToExecutableQueryTranslator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public static ExecutableQuery<TDocument, bool> Translate<TDocument>(MongoQueryPr
7070
var itemValue = itemExpression.GetConstantValue<object>(containingExpression: expression);
7171
var serializedValue = SerializationHelper.SerializeValue(pipeline.OutputSerializer, itemValue);
7272

73-
AstFilter filter = AstFilter.Eq(AstFilter.Field("_v", valueSerializer), serializedValue);
73+
AstFilter filter = AstFilter.Eq(AstFilter.Field("_v"), serializedValue);
7474
pipeline = pipeline.AddStages(
7575
__outputSerializer,
7676
AstStage.Match(filter),

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToExecutableQueryTranslators/ExecutableQuery.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ internal static class ExecutableQuery
3939
{
4040
public static ExecutableQuery<TDocument, TOutput, TResult> Create<TDocument, TOutput, TResult>(
4141
MongoQueryProvider<TDocument> provider,
42-
AstPipeline unoptimizedPipeline,
42+
TranslatedPipeline unoptimizedPipeline,
4343
IExecutableQueryFinalizer<TOutput, TResult> finalizer)
4444
{
45-
var optimizedPipeline = AstPipelineOptimizer.Optimize(unoptimizedPipeline);
45+
var optimizedAstPipeline = AstPipelineOptimizer.Optimize(unoptimizedPipeline.Ast);
46+
var optimizedPipeline = new TranslatedPipeline(optimizedAstPipeline, unoptimizedPipeline.OutputSerializer);
4647
return provider.Collection == null ?
4748
new ExecutableQuery<TDocument, TOutput, TResult>(provider.Database, provider.Options, optimizedPipeline, finalizer) :
4849
new ExecutableQuery<TDocument, TOutput, TResult>(provider.Collection, provider.Options, optimizedPipeline, finalizer);
@@ -52,7 +53,7 @@ public static ExecutableQuery<TDocument, TOutput, TResult> Create<TDocument, TOu
5253
internal abstract class ExecutableQuery<TDocument>
5354
{
5455
public abstract BsonDocument[] LoggedStages { get; }
55-
public abstract AstPipeline Pipeline { get; }
56+
public abstract TranslatedPipeline Pipeline { get; }
5657
}
5758

5859
internal abstract class ExecutableQuery<TDocument, TResult> : ExecutableQuery<TDocument>
@@ -69,13 +70,13 @@ internal class ExecutableQuery<TDocument, TOutput, TResult> : ExecutableQuery<TD
6970
private readonly IExecutableQueryFinalizer<TOutput, TResult> _finalizer;
7071
private BsonDocument[] _loggedStages = null;
7172
private readonly AggregateOptions _options;
72-
private readonly AstPipeline _pipeline;
73+
private readonly TranslatedPipeline _pipeline;
7374

7475
// constructors
7576
public ExecutableQuery(
7677
IMongoCollection<TDocument> collection,
7778
AggregateOptions options,
78-
AstPipeline pipeline,
79+
TranslatedPipeline pipeline,
7980
IExecutableQueryFinalizer<TOutput, TResult> finalizer)
8081
: this(options, pipeline, finalizer)
8182
{
@@ -85,7 +86,7 @@ public ExecutableQuery(
8586
public ExecutableQuery(
8687
IMongoDatabase database,
8788
AggregateOptions options,
88-
AstPipeline pipeline,
89+
TranslatedPipeline pipeline,
8990
IExecutableQueryFinalizer<TOutput, TResult> finalizer)
9091
: this(options, pipeline, finalizer)
9192
{
@@ -94,7 +95,7 @@ public ExecutableQuery(
9495

9596
private ExecutableQuery(
9697
AggregateOptions options,
97-
AstPipeline pipeline,
98+
TranslatedPipeline pipeline,
9899
IExecutableQueryFinalizer<TOutput, TResult> finalizer)
99100
{
100101
_options = options;
@@ -104,7 +105,7 @@ private ExecutableQuery(
104105

105106
// public properties
106107
public override BsonDocument[] LoggedStages => _loggedStages;
107-
public override AstPipeline Pipeline => _pipeline;
108+
public override TranslatedPipeline Pipeline => _pipeline;
108109

109110
// public methods
110111
public override TResult Execute(IClientSessionHandle session, CancellationToken cancellationToken)
@@ -156,7 +157,7 @@ private BsonDocumentStagePipelineDefinition<NoPipelineInput, TOutput> CreateData
156157

157158
private BsonDocument[] RenderPipeline()
158159
{
159-
return _pipeline.Render().AsBsonArray.Cast<BsonDocument>().ToArray();
160+
return _pipeline.Ast.Render().AsBsonArray.Cast<BsonDocument>().ToArray();
160161
}
161162

162163
private IBsonSerializer<TOutput> GetOutputSerializer()

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToFilterTranslators/ExpressionToFilterTranslator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ private static AstFilter TranslateUsingQueryOperators(TranslationContext context
118118

119119
if (expression.Type == typeof(bool))
120120
{
121-
var field = ExpressionToFilterFieldTranslator.Translate(context, expression);
122-
var serializedTrue = SerializationHelper.SerializeValue(field.Serializer, true);
123-
return AstFilter.Eq(field, serializedTrue);
121+
var fieldTranslation = ExpressionToFilterFieldTranslator.Translate(context, expression);
122+
var serializedTrue = SerializationHelper.SerializeValue(fieldTranslation.Serializer, true);
123+
return AstFilter.Eq(fieldTranslation.Ast, serializedTrue);
124124
}
125125

126126
throw new ExpressionNotSupportedException(expression);

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToFilterTranslators/ExpressionTranslators/ArrayLengthComparisonExpressionToFilterTranslator.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,36 +42,36 @@ public static AstFilter Translate(TranslationContext context, BinaryExpression e
4242
{
4343
if (arrayLengthExpression.NodeType == ExpressionType.ArrayLength)
4444
{
45-
var arrayExpression = arrayLengthExpression.Operand;
46-
var arrayField = ExpressionToFilterFieldTranslator.Translate(context, arrayExpression);
45+
var fieldExpression = arrayLengthExpression.Operand;
46+
var fieldTranslation = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);
4747
var size = sizeExpression.GetConstantValue<int>(containingExpression: expression);
4848

4949
switch (comparisonOperator)
5050
{
5151
case AstComparisonFilterOperator.Eq:
52-
return AstFilter.Size(arrayField, size);
52+
return AstFilter.Size(fieldTranslation.Ast, size);
5353

5454
case AstComparisonFilterOperator.Gt:
55-
return AstFilter.Exists(ItemField(arrayField, size));
55+
return AstFilter.Exists(ItemField(fieldTranslation.Ast, size));
5656

5757
case AstComparisonFilterOperator.Gte:
58-
return AstFilter.Exists(ItemField(arrayField, size - 1));
58+
return AstFilter.Exists(ItemField(fieldTranslation.Ast, size - 1));
5959

6060
case AstComparisonFilterOperator.Lt:
61-
return AstFilter.NotExists(ItemField(arrayField, size - 1));
61+
return AstFilter.NotExists(ItemField(fieldTranslation.Ast, size - 1));
6262

6363
case AstComparisonFilterOperator.Lte:
64-
return AstFilter.NotExists(ItemField(arrayField, size));
64+
return AstFilter.NotExists(ItemField(fieldTranslation.Ast, size));
6565

6666
case AstComparisonFilterOperator.Ne:
67-
return AstFilter.Not(AstFilter.Size(arrayField, size));
67+
return AstFilter.Not(AstFilter.Size(fieldTranslation.Ast, size));
6868
}
6969

7070
}
7171

7272
throw new ExpressionNotSupportedException(expression);
7373

74-
static AstFilterField ItemField(AstFilterField field, int index) => field.SubField(index.ToString(), BsonValueSerializer.Instance);
74+
static AstFilterField ItemField(AstFilterField field, int index) => field.SubField(index.ToString());
7575
}
7676
}
7777
}

0 commit comments

Comments
 (0)