Skip to content

Commit f7e74d3

Browse files
committed
Backport from master: Update Compilers for VB and new ones for FSharp
1 parent 2da2909 commit f7e74d3

7 files changed

Lines changed: 526 additions & 12 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright (C) 2026 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
4+
5+
using System.Reflection;
6+
using Xtensive.Sql.Dml;
7+
8+
namespace Xtensive.Orm.Providers
9+
{
10+
#pragma warning disable IDE0060 // Remove unused parameter
11+
[CompilerContainer(typeof(SqlExpression))]
12+
internal static class FSharpConversionsCompilers
13+
{
14+
#if NET8_0_OR_GREATER
15+
private const string FSharpOperators = "Microsoft.FSharp.Core.Operators, FSharp.Core, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
16+
#elif NET7_0
17+
private const string FSharpOperators = "Microsoft.FSharp.Core.Operators, FSharp.Core, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
18+
#else
19+
private const string FSharpOperators = "Microsoft.FSharp.Core.Operators, FSharp.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
20+
#endif
21+
22+
[Compiler(FSharpOperators, "ToChar", TargetKind.Static | TargetKind.Method, 1)]
23+
public static SqlExpression ToCharGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
24+
{
25+
return ExpressionTranslationHelpers.ToChar(stringExpression);
26+
}
27+
28+
[Compiler(FSharpOperators, "ToByte", TargetKind.Static | TargetKind.Method, 1)]
29+
public static SqlExpression ToByteGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
30+
{
31+
return ExpressionTranslationHelpers.ToByte(stringExpression);
32+
}
33+
34+
[Compiler(FSharpOperators, "ToSByte", TargetKind.Static | TargetKind.Method, 1)]
35+
public static SqlExpression ToSByteGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
36+
{
37+
return ExpressionTranslationHelpers.ToSbyte(stringExpression);
38+
}
39+
40+
[Compiler(FSharpOperators, "ToInt16", TargetKind.Static | TargetKind.Method, 1)]
41+
public static SqlExpression ToShortGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
42+
{
43+
return ExpressionTranslationHelpers.ToShort(stringExpression);
44+
}
45+
46+
[Compiler(FSharpOperators, "ToUInt16", TargetKind.Static | TargetKind.Method, 1)]
47+
public static SqlExpression ToUShortGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
48+
{
49+
return ExpressionTranslationHelpers.ToUshort(stringExpression);
50+
}
51+
52+
[Compiler(FSharpOperators, "ToInt", TargetKind.Static | TargetKind.Method, 1)]
53+
public static SqlExpression ToIntGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
54+
{
55+
return ExpressionTranslationHelpers.ToInt(stringExpression);
56+
}
57+
58+
[Compiler(FSharpOperators, "ToInt32", TargetKind.Static | TargetKind.Method, 1)]
59+
public static SqlExpression ToInt32Generic(MemberInfo memberInfo, SqlExpression stringExpression)
60+
{
61+
return ExpressionTranslationHelpers.ToInt(stringExpression);
62+
}
63+
64+
[Compiler(FSharpOperators, "ToUInt32", TargetKind.Static | TargetKind.Method, 1)]
65+
public static SqlExpression ToUInt32Generic(MemberInfo memberInfo, SqlExpression stringExpression)
66+
{
67+
return ExpressionTranslationHelpers.ToUint(stringExpression);
68+
}
69+
70+
[Compiler(FSharpOperators, "ToInt64", TargetKind.Static | TargetKind.Method, 1)]
71+
public static SqlExpression ToInt64Generic(MemberInfo memberInfo, SqlExpression stringExpression)
72+
{
73+
return ExpressionTranslationHelpers.ToLong(stringExpression);
74+
}
75+
76+
[Compiler(FSharpOperators, "ToUInt64", TargetKind.Static | TargetKind.Method, 1)]
77+
public static SqlExpression ToUInt64Generic(MemberInfo memberInfo, SqlExpression stringExpression)
78+
{
79+
return ExpressionTranslationHelpers.ToUlong(stringExpression);
80+
}
81+
82+
[Compiler(FSharpOperators, "ToSingle", TargetKind.Static | TargetKind.Method, 1)]
83+
public static SqlExpression ToSingleGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
84+
{
85+
return ExpressionTranslationHelpers.ToFloat(stringExpression);
86+
}
87+
88+
[Compiler(FSharpOperators, "ToDouble", TargetKind.Static | TargetKind.Method, 1)]
89+
public static SqlExpression ToDoubleGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
90+
{
91+
return ExpressionTranslationHelpers.ToDouble(stringExpression);
92+
}
93+
94+
[Compiler(FSharpOperators, "ToDecimal", TargetKind.Static | TargetKind.Method, 1)]
95+
public static SqlExpression ToDecimalGeneric(MemberInfo memberInfo, SqlExpression stringExpression)
96+
{
97+
return ExpressionTranslationHelpers.ToDecimal(stringExpression);
98+
}
99+
100+
[Compiler(FSharpOperators, "ToString", TargetKind.Static | TargetKind.Method, 1)]
101+
public static SqlExpression ToStringGeneric(MemberInfo memberInfo, SqlExpression expression)
102+
103+
{
104+
return ExpressionTranslationHelpers.ToString(expression);
105+
}
106+
}
107+
#pragma warning restore IDE0060 // Remove unused parameter
108+
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// Copyright (C) 2026 Xtensive LLC.
2+
// This code is distributed under MIT license terms.
3+
// See the License.txt file in the project root for more information.
4+
5+
using System;
6+
using System.Reflection;
7+
using Xtensive.Reflection;
8+
using Xtensive.Sql;
9+
using Xtensive.Sql.Dml;
10+
11+
namespace Xtensive.Orm.Providers
12+
{
13+
#pragma warning disable IDE0060 // Remove unused parameter
14+
[CompilerContainer(typeof(SqlExpression))]
15+
internal static class FSharpMathOperationsCompilers
16+
{
17+
#if NET8_0_OR_GREATER
18+
private const string FSharpOperators = "Microsoft.FSharp.Core.Operators, FSharp.Core, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
19+
#elif NET7_0
20+
private const string FSharpOperators = "Microsoft.FSharp.Core.Operators, FSharp.Core, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
21+
#else
22+
private const string FSharpOperators = "Microsoft.FSharp.Core.Operators, FSharp.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a";
23+
#endif
24+
25+
[Compiler(FSharpOperators, "Abs", TargetKind.Static | TargetKind.Method, 1)]
26+
public static SqlExpression AbsGeneric(MemberInfo member, SqlExpression operand)
27+
{
28+
return SqlDml.Abs(operand);
29+
}
30+
31+
[Compiler(FSharpOperators, "Sign", TargetKind.Static | TargetKind.Method, 1)]
32+
public static SqlExpression SignGeneric(MemberInfo member, SqlExpression operand)
33+
{
34+
return ExpressionTranslationHelpers.ToInt(SqlDml.Sign(operand));
35+
}
36+
37+
[Compiler(FSharpOperators, "Acos", TargetKind.Static | TargetKind.Method, 1)]
38+
public static SqlExpression AcosGeneric(MemberInfo member, SqlExpression x)
39+
{
40+
return SqlDml.Acos(x);
41+
}
42+
43+
[Compiler(FSharpOperators, "Asin", TargetKind.Static | TargetKind.Method, 1)]
44+
public static SqlExpression AsinGeneric(MemberInfo member, SqlExpression x)
45+
{
46+
return SqlDml.Asin(x);
47+
}
48+
49+
[Compiler(FSharpOperators, "Atan", TargetKind.Static | TargetKind.Method, 1)]
50+
public static SqlExpression AtanGeneric(MemberInfo member, SqlExpression x)
51+
{
52+
return SqlDml.Atan(x);
53+
}
54+
55+
[Compiler(FSharpOperators, "Atan2", TargetKind.Static | TargetKind.Method, 2)]
56+
public static SqlExpression Atan2Generic(MemberInfo member, SqlExpression x, SqlExpression y)
57+
{
58+
return SqlDml.Atan2(x, y);
59+
}
60+
61+
[Compiler(FSharpOperators, "Ceiling", TargetKind.Static | TargetKind.Method, 1)]
62+
public static SqlExpression CeilingGeneric(MemberInfo member, SqlExpression x)
63+
{
64+
return SqlDml.Ceiling(x);
65+
}
66+
67+
[Compiler(FSharpOperators, "Cos", TargetKind.Static | TargetKind.Method, 1)]
68+
public static SqlExpression CosGeneric(MemberInfo member, SqlExpression x)
69+
{
70+
return SqlDml.Cos(x);
71+
}
72+
73+
[Compiler(FSharpOperators, "Cosh", TargetKind.Static | TargetKind.Method, 1)]
74+
public static SqlExpression CoshGeneric(MemberInfo member, SqlExpression x)
75+
{
76+
return (SqlDml.Exp(x) + SqlDml.Exp(-x)) / SqlDml.Literal(2);
77+
}
78+
79+
[Compiler(FSharpOperators, "Exp", TargetKind.Static | TargetKind.Method, 1)]
80+
public static SqlExpression ExpGeneric(MemberInfo member, SqlExpression x)
81+
{
82+
return SqlDml.Exp(x);
83+
}
84+
85+
[Compiler(FSharpOperators, "Floor", TargetKind.Static | TargetKind.Method, 1)]
86+
public static SqlExpression FloorGeneric(MemberInfo member, SqlExpression x)
87+
{
88+
return SqlDml.Floor(x);
89+
}
90+
91+
[Compiler(FSharpOperators, "Log", TargetKind.Static | TargetKind.Method, 1)]
92+
public static SqlExpression LogGeneric(MemberInfo member, SqlExpression x)
93+
{
94+
return SqlDml.Log(x);
95+
}
96+
97+
[Compiler(FSharpOperators, "Log10", TargetKind.Static | TargetKind.Method, 1)]
98+
public static SqlExpression Log10Generic(MemberInfo member, SqlExpression x)
99+
{
100+
return SqlDml.Log10(x);
101+
}
102+
103+
[Compiler(FSharpOperators, "Max", TargetKind.Static | TargetKind.Method, 1)]
104+
public static SqlExpression MaxGeneric(MemberInfo member, SqlExpression left, SqlExpression right)
105+
{
106+
var result = SqlDml.Case();
107+
_ = result.Add(left > right, left);
108+
result.Else = right;
109+
return result;
110+
}
111+
112+
[Compiler(FSharpOperators, "Min", TargetKind.Static | TargetKind.Method, 1)]
113+
public static SqlExpression MinGeneric(MemberInfo member, SqlExpression left, SqlExpression right)
114+
{
115+
var result = SqlDml.Case();
116+
_ = result.Add(left < right, left);
117+
result.Else = right;
118+
return result;
119+
}
120+
121+
[Compiler(FSharpOperators, "Round", TargetKind.Static | TargetKind.Method, 1)]
122+
public static SqlExpression RoundGeneric(MemberInfo member, SqlExpression x)
123+
{
124+
return BankersRound(x, null, (member as MethodInfo).GetGenericArguments()[0] == WellKnownTypes.Decimal);
125+
}
126+
127+
private static SqlExpression BankersRound(SqlExpression value, SqlExpression digits, bool isDecimal)
128+
{
129+
if (!isDecimal) {
130+
return SqlDml.Round(value, digits, TypeCode.Double, MidpointRounding.ToEven);
131+
}
132+
if (digits == null) {
133+
return TryCastToDecimalPS(SqlDml.Round(value, digits, TypeCode.Decimal, MidpointRounding.ToEven), 28, 0);
134+
}
135+
if (!(digits is SqlLiteral<int> scale)) {
136+
throw new NotSupportedException();
137+
}
138+
return TryCastToDecimalPS(SqlDml.Round(value, digits, TypeCode.Decimal, MidpointRounding.ToEven), 28, Convert.ToInt16(scale.Value));
139+
}
140+
141+
private static SqlExpression TryCastToDecimalPS(SqlExpression value, short precision, short scale)
142+
{
143+
var context = ExpressionTranslationContext.Current;
144+
var provider = context.ProviderInfo.ProviderName;
145+
if (provider.Equals(WellKnown.Provider.PostgreSql, StringComparison.Ordinal)
146+
|| provider.Equals(WellKnown.Provider.Oracle, StringComparison.Ordinal)) {
147+
// to fit result into .Net decimal since Npgsql client libarary does not provide a way to make in on reading
148+
return SqlDml.Cast(value, SqlType.Decimal, precision, scale);
149+
}
150+
return value;
151+
}
152+
153+
154+
[Compiler(FSharpOperators, "Sin", TargetKind.Static | TargetKind.Method, 1)]
155+
public static SqlExpression SinGeneric(MemberInfo member, SqlExpression x)
156+
{
157+
return SqlDml.Sin(x);
158+
}
159+
160+
[Compiler(FSharpOperators, "Sinh", TargetKind.Static | TargetKind.Method, 1)]
161+
public static SqlExpression SinhGeneric(MemberInfo member, SqlExpression x)
162+
{
163+
return (SqlDml.Exp(x) - SqlDml.Exp(-x)) / SqlDml.Literal(2);
164+
}
165+
166+
[Compiler(FSharpOperators, "Sqrt", TargetKind.Static | TargetKind.Method, 2)]
167+
public static SqlExpression SqrtGeneric(MemberInfo member, SqlExpression x)
168+
{
169+
return SqlDml.Sqrt(x);
170+
}
171+
172+
[Compiler(FSharpOperators, "Tan", TargetKind.Static | TargetKind.Method, 1)]
173+
public static SqlExpression TanGeneric(MemberInfo member, SqlExpression x)
174+
{
175+
return SqlDml.Tan(x);
176+
}
177+
178+
[Compiler(FSharpOperators, "Tanh", TargetKind.Static | TargetKind.Method, 1)]
179+
public static SqlExpression TanhGeneric(MemberInfo member, SqlExpression x)
180+
{
181+
var exp2d = SqlDml.Exp(SqlDml.Literal(2) * x);
182+
var one = SqlDml.Literal(1);
183+
184+
return (exp2d - one) / (exp2d + one);
185+
}
186+
187+
[Compiler(FSharpOperators, "Truncate", TargetKind.Static | TargetKind.Method, 1)]
188+
public static SqlExpression TruncateGeneric(MemberInfo member, SqlExpression x)
189+
{
190+
if ((member as MethodInfo).GetGenericArguments()[0] == WellKnownTypes.Decimal)
191+
return TryCastToDecimalPS(SqlDml.Truncate(x), 28, 0);
192+
return SqlDml.Truncate(x);
193+
}
194+
}
195+
#pragma warning restore IDE0060 // Remove unused parameter
196+
}

0 commit comments

Comments
 (0)