16
16
using MongoDB . Bson ;
17
17
using MongoDB . Driver . Linq . Linq3Implementation . Ast . Expressions ;
18
18
using MongoDB . Driver . Linq . Linq3Implementation . Ast . Filters ;
19
- using MongoDB . Driver . Linq . Linq3Implementation . Ast . Stages ;
20
19
using MongoDB . Driver . Linq . Linq3Implementation . Ast . Visitors ;
21
20
22
21
namespace MongoDB . Driver . Linq . Linq3Implementation . Ast . Optimizers
@@ -37,6 +36,48 @@ public static TNode SimplifyAndConvert<TNode>(TNode node)
37
36
}
38
37
#endregion
39
38
39
+ public override AstNode VisitCondExpression ( AstCondExpression node )
40
+ {
41
+ // { $cond : [{ $eq : [expr1, null] }, null, expr2] }
42
+ if ( node . If is AstBinaryExpression binaryIfpression &&
43
+ binaryIfpression . Operator == AstBinaryOperator . Eq &&
44
+ binaryIfpression . Arg1 is AstExpression expr1 &&
45
+ binaryIfpression . Arg2 is AstConstantExpression constantComparandExpression &&
46
+ constantComparandExpression . Value == BsonNull . Value &&
47
+ node . Then is AstConstantExpression constantThenExpression &&
48
+ constantThenExpression . Value == BsonNull . Value &&
49
+ node . Else is AstExpression expr2 )
50
+ {
51
+ // { $cond : [{ $eq : [expr, null] }, null, expr] } => expr
52
+ if ( expr1 == expr2 )
53
+ {
54
+ return Visit ( expr2 ) ;
55
+ }
56
+
57
+ // { $cond : [{ $eq : [expr, null] }, null, { $toT : expr }] } => { $toT : expr } for operators that map null to null
58
+ if ( expr2 is AstUnaryExpression unaryElseExpression &&
59
+ OperatorMapsNullToNull ( unaryElseExpression . Operator ) &&
60
+ unaryElseExpression . Arg == expr1 )
61
+ {
62
+ return Visit ( expr2 ) ;
63
+ }
64
+ }
65
+
66
+ return base . VisitCondExpression ( node ) ;
67
+
68
+ static bool OperatorMapsNullToNull ( AstUnaryOperator @operator )
69
+ {
70
+ return @operator switch
71
+ {
72
+ AstUnaryOperator . ToDecimal => true ,
73
+ AstUnaryOperator . ToDouble => true ,
74
+ AstUnaryOperator . ToInt => true ,
75
+ AstUnaryOperator . ToLong => true ,
76
+ _ => false
77
+ } ;
78
+ }
79
+ }
80
+
40
81
public override AstNode VisitFieldOperationFilter ( AstFieldOperationFilter node )
41
82
{
42
83
node = ( AstFieldOperationFilter ) base . VisitFieldOperationFilter ( node ) ;
@@ -281,6 +322,22 @@ bool TrySimplifyAsLet(AstGetFieldExpression node, out AstExpression simplified)
281
322
}
282
323
}
283
324
325
+ public override AstNode VisitLetExpression ( AstLetExpression node )
326
+ {
327
+ node = ( AstLetExpression ) base . VisitLetExpression ( node ) ;
328
+
329
+ // { $let : { vars : { var : expr }, in : "$$var" } } => expr
330
+ if ( node . Vars . Count == 1 &&
331
+ node . Vars [ 0 ] . Var . Name is string varName &&
332
+ node . In is AstVarExpression varExpression &&
333
+ varExpression . Name == varName )
334
+ {
335
+ return node . Vars [ 0 ] . Value ;
336
+ }
337
+
338
+ return node ;
339
+ }
340
+
284
341
public override AstNode VisitMapExpression ( AstMapExpression node )
285
342
{
286
343
// { $map : { input : <input>, as : "v", in : "$$v.x" } } => { $getField : { field : "x", input : <input> } }
0 commit comments