Skip to content

Commit c687884

Browse files
committed
CSHARP-2471: Add support for trig functions in LINQ3.
1 parent 502a427 commit c687884

File tree

9 files changed

+412
-14
lines changed

9 files changed

+412
-14
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstBinaryOperator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions
2020
internal enum AstBinaryOperator
2121
{
2222
ArrayElemAt,
23-
ATan2,
23+
Atan2,
2424
Cmp,
2525
Divide,
2626
Eq,
@@ -50,7 +50,7 @@ public static string Render(this AstBinaryOperator @operator)
5050
return @operator switch
5151
{
5252
AstBinaryOperator.ArrayElemAt => "$arrayElemAt",
53-
AstBinaryOperator.ATan2 => "$atan2",
53+
AstBinaryOperator.Atan2 => "$atan2",
5454
AstBinaryOperator.Cmp => "$cmp",
5555
AstBinaryOperator.Divide => "$divide",
5656
AstBinaryOperator.Eq => "$eq",

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstExpression.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ public static AstExpression Avg(AstExpression array)
152152
return new AstUnaryExpression(AstUnaryOperator.Avg, array);
153153
}
154154

155+
public static AstExpression Binary(AstBinaryOperator @operator, AstExpression arg1, AstExpression arg2)
156+
{
157+
return new AstBinaryExpression(@operator, arg1, arg2);
158+
}
159+
155160
public static AstExpression BinaryWindowExpression(AstBinaryWindowOperator @operator, AstExpression arg1, AstExpression arg2, AstWindow window)
156161
{
157162
return new AstBinaryWindowExpression(@operator, arg1, arg2, window);

src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstUnaryOperator.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,22 @@ namespace MongoDB.Driver.Linq.Linq3Implementation.Ast.Expressions
2020
internal enum AstUnaryOperator
2121
{
2222
Abs,
23-
ACos,
24-
ACosh,
23+
Acos,
24+
Acosh,
2525
AddToSet,
2626
AllElementsTrue,
2727
AnyElementTrue,
2828
ArrayToObject,
29-
ASin,
30-
ASinh,
31-
ATan,
32-
ATanh,
29+
Asin,
30+
Asinh,
31+
Atan,
32+
Atanh,
3333
Avg,
3434
BinarySize,
3535
BsonSize,
3636
Ceil,
3737
Cos,
38+
Cosh,
3839
DegreesToRadians,
3940
Exp,
4041
First,
@@ -56,6 +57,7 @@ internal enum AstUnaryOperator
5657
ReverseArray,
5758
Round,
5859
Sin,
60+
Sinh,
5961
Size,
6062
Sqrt,
6163
StdDevPop,
@@ -64,6 +66,7 @@ internal enum AstUnaryOperator
6466
StrLenCP,
6567
Sum,
6668
Tan,
69+
Tanh,
6770
ToBool,
6871
ToDate,
6972
ToDecimal,
@@ -103,21 +106,22 @@ public static string Render(this AstUnaryOperator @operator)
103106
return @operator switch
104107
{
105108
AstUnaryOperator.Abs => "$abs",
106-
AstUnaryOperator.ACos => "$acos",
107-
AstUnaryOperator.ACosh => "$acosh",
109+
AstUnaryOperator.Acos => "$acos",
110+
AstUnaryOperator.Acosh => "$acosh",
108111
AstUnaryOperator.AddToSet => "$addToSet",
109112
AstUnaryOperator.AllElementsTrue => "$allElementsTrue",
110113
AstUnaryOperator.AnyElementTrue => "$anyElementTrue",
111114
AstUnaryOperator.ArrayToObject => "$arrayToObject",
112-
AstUnaryOperator.ASin => "$asin",
113-
AstUnaryOperator.ASinh => "$asinh",
114-
AstUnaryOperator.ATan => "$atan",
115-
AstUnaryOperator.ATanh => "$atanh",
115+
AstUnaryOperator.Asin => "$asin",
116+
AstUnaryOperator.Asinh => "$asinh",
117+
AstUnaryOperator.Atan => "$atan",
118+
AstUnaryOperator.Atanh => "$atanh",
116119
AstUnaryOperator.Avg => "$avg",
117120
AstUnaryOperator.BinarySize => "$binarySize",
118121
AstUnaryOperator.BsonSize => "$bsonSize",
119122
AstUnaryOperator.Ceil => "$ceil",
120123
AstUnaryOperator.Cos => "$cos",
124+
AstUnaryOperator.Cosh => "$cosh",
121125
AstUnaryOperator.DegreesToRadians => "$degreesToRadians",
122126
AstUnaryOperator.Exp => "$exp",
123127
AstUnaryOperator.First => "$first",
@@ -139,6 +143,7 @@ public static string Render(this AstUnaryOperator @operator)
139143
AstUnaryOperator.ReverseArray => "$reverseArray",
140144
AstUnaryOperator.Round => "$round",
141145
AstUnaryOperator.Sin => "$sin",
146+
AstUnaryOperator.Sinh => "$sinh",
142147
AstUnaryOperator.Size => "$size",
143148
AstUnaryOperator.Sqrt => "$sqrt",
144149
AstUnaryOperator.StdDevPop => "$stdDevPop",
@@ -147,6 +152,7 @@ public static string Render(this AstUnaryOperator @operator)
147152
AstUnaryOperator.StrLenCP => "$strLenCP",
148153
AstUnaryOperator.Sum => "$sum",
149154
AstUnaryOperator.Tan => "$tan",
155+
AstUnaryOperator.Tanh => "$tanh",
150156
AstUnaryOperator.ToBool => "$toBool",
151157
AstUnaryOperator.ToDate => "$toDate",
152158
AstUnaryOperator.ToDecimal => "$toDecimal",

src/MongoDB.Driver/Linq/Linq3Implementation/Reflection/MathMethod.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,29 @@ internal static class MathMethod
2828
private static readonly MethodInfo __absInt64;
2929
private static readonly MethodInfo __absSByte;
3030
private static readonly MethodInfo __absSingle;
31+
private static readonly MethodInfo __acos;
32+
private static readonly MethodInfo __acosh = null; // null when target framework does not have this method
33+
private static readonly MethodInfo __asin;
34+
private static readonly MethodInfo __asinh = null; // null when target framework does not have this method
35+
private static readonly MethodInfo __atan;
36+
private static readonly MethodInfo __atan2;
37+
private static readonly MethodInfo __atanh = null; // null when target framework does not have this method
3138
private static readonly MethodInfo __ceilingWithDecimal;
3239
private static readonly MethodInfo __ceilingWithDouble;
40+
private static readonly MethodInfo __cos;
41+
private static readonly MethodInfo __cosh;
3342
private static readonly MethodInfo __exp;
3443
private static readonly MethodInfo __floorWithDecimal;
3544
private static readonly MethodInfo __floorWithDouble;
3645
private static readonly MethodInfo __log;
3746
private static readonly MethodInfo __logWithNewBase;
3847
private static readonly MethodInfo __log10;
3948
private static readonly MethodInfo __pow;
49+
private static readonly MethodInfo __sin;
50+
private static readonly MethodInfo __sinh;
4051
private static readonly MethodInfo __sqrt;
52+
private static readonly MethodInfo __tan;
53+
private static readonly MethodInfo __tanh;
4154
private static readonly MethodInfo __truncateDecimal;
4255
private static readonly MethodInfo __truncateDouble;
4356

@@ -51,16 +64,35 @@ static MathMethod()
5164
__absInt64 = ReflectionInfo.Method((long value) => Math.Abs(value));
5265
__absSByte = ReflectionInfo.Method((sbyte value) => Math.Abs(value));
5366
__absSingle = ReflectionInfo.Method((float value) => Math.Abs(value));
67+
__acos = ReflectionInfo.Method((double d) => Math.Acos(d));
68+
#if NETSTANDARD2_1_OR_GREATER
69+
__acosh = ReflectionInfo.Method((double d) => Math.Acosh(d));
70+
#endif
71+
__asin = ReflectionInfo.Method((double d) => Math.Asin(d));
72+
#if NETSTANDARD2_1_OR_GREATER
73+
__asinh = ReflectionInfo.Method((double d) => Math.Asinh(d));
74+
#endif
75+
__atan = ReflectionInfo.Method((double d) => Math.Atan(d));
76+
__atan2 = ReflectionInfo.Method((double x, double y) => Math.Atan2(x, y));
77+
#if NETSTANDARD2_1_OR_GREATER
78+
__atanh = ReflectionInfo.Method((double d) => Math.Atanh(d));
79+
#endif
5480
__ceilingWithDecimal = ReflectionInfo.Method((decimal d) => Math.Ceiling(d));
5581
__ceilingWithDouble = ReflectionInfo.Method((double a) => Math.Ceiling(a));
82+
__cos = ReflectionInfo.Method((double d) => Math.Cos(d));
83+
__cosh = ReflectionInfo.Method((double a) => Math.Cosh(a));
5684
__exp = ReflectionInfo.Method((double d) => Math.Exp(d));
5785
__floorWithDecimal = ReflectionInfo.Method((decimal d) => Math.Floor(d));
5886
__floorWithDouble = ReflectionInfo.Method((double d) => Math.Floor(d));
5987
__log = ReflectionInfo.Method((double d) => Math.Log(d));
6088
__logWithNewBase = ReflectionInfo.Method((double a, double newBase) => Math.Log(a, newBase));
6189
__log10 = ReflectionInfo.Method((double d) => Math.Log10(d));
6290
__pow = ReflectionInfo.Method((double x, double y) => Math.Pow(x, y));
91+
__sin = ReflectionInfo.Method((double a) => Math.Sin(a));
92+
__sinh = ReflectionInfo.Method((double a) => Math.Sinh(a));
6393
__sqrt = ReflectionInfo.Method((double d) => Math.Sqrt(d));
94+
__tan = ReflectionInfo.Method((double a) => Math.Tan(a));
95+
__tanh = ReflectionInfo.Method((double a) => Math.Tanh(a));
6496
__truncateDecimal = ReflectionInfo.Method((decimal d) => Math.Truncate(d));
6597
__truncateDouble = ReflectionInfo.Method((double d) => Math.Truncate(d));
6698
}
@@ -73,16 +105,29 @@ static MathMethod()
73105
public static MethodInfo AbsInt64 => __absInt64;
74106
public static MethodInfo AbsSByte => __absSByte;
75107
public static MethodInfo AbsSingle => __absSingle;
108+
public static MethodInfo Acos => __acos;
109+
public static MethodInfo Acosh => __acosh;
110+
public static MethodInfo Asin => __asin;
111+
public static MethodInfo Asinh => __asinh;
112+
public static MethodInfo Atan => __atan;
113+
public static MethodInfo Atan2 => __atan2;
114+
public static MethodInfo Atanh => __atanh;
76115
public static MethodInfo CeilingWithDecimal => __ceilingWithDecimal;
77116
public static MethodInfo CeilingWithDouble => __ceilingWithDouble;
117+
public static MethodInfo Cos => __cos;
118+
public static MethodInfo Cosh => __cosh;
78119
public static MethodInfo Exp => __exp;
79120
public static MethodInfo FloorWithDecimal => __floorWithDecimal;
80121
public static MethodInfo FloorWithDouble => __floorWithDouble;
81122
public static MethodInfo Log => __log;
82123
public static MethodInfo LogWithNewBase => __logWithNewBase;
83124
public static MethodInfo Log10 => __log10;
84125
public static MethodInfo Pow => __pow;
126+
public static MethodInfo Sin => __sin;
127+
public static MethodInfo Sinh => __sinh;
85128
public static MethodInfo Sqrt => __sqrt;
129+
public static MethodInfo Tan => __tan;
130+
public static MethodInfo Tanh => __tanh;
86131
public static MethodInfo TruncateDecimal => __truncateDecimal;
87132
public static MethodInfo TruncateDouble => __truncateDouble;
88133
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Reflection;
17+
18+
namespace MongoDB.Driver.Linq.Linq3Implementation.Reflection
19+
{
20+
internal static class MongoDBMathMethod
21+
{
22+
// private static fields
23+
private static readonly MethodInfo __degreesToRadians;
24+
private static readonly MethodInfo __radiansToDegrees;
25+
26+
// static constructor
27+
static MongoDBMathMethod()
28+
{
29+
__degreesToRadians = ReflectionInfo.Method((double degrees) => MongoDBMath.DegreesToRadians(degrees));
30+
__radiansToDegrees = ReflectionInfo.Method((double radians) => MongoDBMath.RadiansToDegrees(radians));
31+
}
32+
33+
// public properties
34+
public static MethodInfo DegreesToRadians => __degreesToRadians;
35+
public static MethodInfo RadiansToDegrees => __radiansToDegrees;
36+
}
37+
}

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/MethodCallExpressionToAggregationExpressionTranslator.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,23 @@ public static AggregationExpression Translate(TranslationContext context, Method
7777
case "Union": return UnionMethodToAggregationExpressionTranslator.Translate(context, expression);
7878
case "Zip": return ZipMethodToAggregationExpressionTranslator.Translate(context, expression);
7979

80+
case "Acos":
81+
case "Acosh":
82+
case "Asin":
83+
case "Asinh":
84+
case "Atan":
85+
case "Atan2":
86+
case "Atanh":
87+
case "Cos":
88+
case "Cosh":
89+
case "DegreesToRadians":
90+
case "RadiansToDegrees":
91+
case "Sin":
92+
case "Sinh":
93+
case "Tan":
94+
case "Tanh":
95+
return TrigMethodToAggregationExpressionTranslator.Translate(context, expression);
96+
8097
case "AddDays":
8198
case "AddHours":
8299
case "AddMilliseconds":

0 commit comments

Comments
 (0)