Skip to content

Commit a588fc7

Browse files
committed
Clean up PR dotnet#22497
1 parent 6e5b3f8 commit a588fc7

File tree

7 files changed

+70
-20
lines changed

7 files changed

+70
-20
lines changed

src/EFCore.Sqlite.Core/Query/Internal/SqliteMethodCallTranslatorProvider.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public SqliteMethodCallTranslatorProvider([NotNull] RelationalMethodCallTranslat
3131
new SqliteByteArrayMethodTranslator(sqlExpressionFactory),
3232
new SqliteDateTimeAddTranslator(sqlExpressionFactory),
3333
new SqliteMathTranslator(sqlExpressionFactory),
34-
new SqliteRegexTranslator(sqlExpressionFactory),
34+
new SqliteRegexMethodTranslator(sqlExpressionFactory),
3535
new SqliteStringMethodTranslator(sqlExpressionFactory)
3636
});
3737
}

src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexTranslator.cs renamed to src/EFCore.Sqlite.Core/Query/Internal/SqliteRegexMethodTranslator.cs

+25-12
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,34 @@ namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
1919
/// any release. You should only use it directly in your code with extreme caution and knowing that
2020
/// doing so can result in application failures when updating to a new Entity Framework Core release.
2121
/// </summary>
22-
public class SqliteRegexTranslator : IMethodCallTranslator
22+
public class SqliteRegexMethodTranslator : IMethodCallTranslator
2323
{
24+
private readonly static MethodInfo _regexIsMatchMethodInfo
25+
= typeof(Regex).GetRuntimeMethod(nameof(Regex.IsMatch), new Type[] { typeof(string), typeof(string) });
26+
2427
private readonly ISqlExpressionFactory _sqlExpressionFactory;
25-
private readonly static MethodInfo regexIsMatchMethod = typeof(Regex).GetMethod(nameof(Regex.IsMatch), new Type[] { typeof(string), typeof(string) });
2628

2729
/// <summary>
2830
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
2931
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
3032
/// any release. You should only use it directly in your code with extreme caution and knowing that
3133
/// doing so can result in application failures when updating to a new Entity Framework Core release.
3234
/// </summary>
33-
public SqliteRegexTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory)
35+
public SqliteRegexMethodTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory)
3436
{
37+
Check.NotNull(sqlExpressionFactory, nameof(sqlExpressionFactory));
38+
3539
_sqlExpressionFactory = sqlExpressionFactory;
3640
}
41+
3742
/// <summary>
3843
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
3944
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
4045
/// any release. You should only use it directly in your code with extreme caution and knowing that
4146
/// doing so can result in application failures when updating to a new Entity Framework Core release.
4247
/// </summary>
43-
public virtual SqlExpression Translate(SqlExpression instance,
48+
public virtual SqlExpression Translate(
49+
SqlExpression instance,
4450
MethodInfo method,
4551
IReadOnlyList<SqlExpression> arguments,
4652
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
@@ -49,15 +55,22 @@ public virtual SqlExpression Translate(SqlExpression instance,
4955
Check.NotNull(arguments, nameof(arguments));
5056
Check.NotNull(logger, nameof(logger));
5157

52-
53-
if (method.Equals(regexIsMatchMethod))
58+
if (method.Equals(_regexIsMatchMethodInfo))
5459
{
55-
return _sqlExpressionFactory.Function("regexp",
56-
new[] { arguments[1], arguments[0] },
57-
false,
58-
new[] { false, false },
59-
typeof(bool),
60-
arguments[0].TypeMapping);
60+
var input = arguments[0];
61+
var pattern = arguments[1];
62+
var stringTypeMapping = ExpressionExtensions.InferTypeMapping(input, pattern);
63+
64+
return _sqlExpressionFactory.Function(
65+
"regexp",
66+
new[]
67+
{
68+
_sqlExpressionFactory.ApplyTypeMapping(pattern, stringTypeMapping),
69+
_sqlExpressionFactory.ApplyTypeMapping(input, stringTypeMapping)
70+
},
71+
nullable: true,
72+
argumentsPropagateNullability: new[] { true, true },
73+
typeof(bool));
6174
}
6275

6376
return null;

src/EFCore.Sqlite.Core/Storage/Internal/SqliteRelationalConnection.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,14 @@ private void InitializeDbConnection(DbConnection connection)
115115
sqliteConnection.DefaultTimeout = _commandTimeout.Value;
116116
}
117117

118-
sqliteConnection.CreateFunction<string, string, bool>(
118+
sqliteConnection.CreateFunction<string, string, bool?>(
119119
"regexp",
120120
(pattern, input) =>
121121
{
122-
if (input == null || pattern == null)
122+
if (input == null
123+
|| pattern == null)
123124
{
124-
return false;
125+
return null;
125126
}
126127

127128
return Regex.IsMatch(input, pattern);
@@ -146,7 +147,8 @@ private void InitializeDbConnection(DbConnection connection)
146147

147148
return Convert.ToDouble(dividend, CultureInfo.InvariantCulture)
148149
% Convert.ToDouble(divisor, CultureInfo.InvariantCulture);
149-
});
150+
},
151+
isDeterministic: true);
150152

151153
sqliteConnection.CreateFunction(
152154
name: "ef_add",
@@ -176,7 +178,6 @@ private void InitializeDbConnection(DbConnection connection)
176178
isDeterministic: true);
177179
}
178180
else
179-
180181
{
181182
_logger.UnexpectedConnectionTypeWarning(connection.GetType());
182183
}

test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs

+10
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,16 @@ public override Task Int_Compare_to_simple_zero(bool async)
10491049
return base.Int_Compare_to_simple_zero(async);
10501050
}
10511051

1052+
public override Task Regex_IsMatch_MethodCall(bool async)
1053+
{
1054+
return AssertTranslationFailed(() => base.Regex_IsMatch_MethodCall(async));
1055+
}
1056+
1057+
public override Task Regex_IsMatch_MethodCall_constant_input(bool async)
1058+
{
1059+
return AssertTranslationFailed(() => base.Regex_IsMatch_MethodCall_constant_input(async));
1060+
}
1061+
10521062
private void AssertSql(params string[] expected)
10531063
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
10541064

test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1590,9 +1590,20 @@ public virtual Task Projecting_Math_Truncate_and_ordering_by_it_twice3(bool asyn
15901590
[MemberData(nameof(IsAsyncData))]
15911591
public virtual Task Regex_IsMatch_MethodCall(bool async)
15921592
{
1593-
return AssertQuery(async,
1594-
ss => ss.Set<Customer>().Where(o => Regex.IsMatch(o.CustomerID, @"^T")),
1593+
return AssertQuery(
1594+
async,
1595+
ss => ss.Set<Customer>().Where(o => Regex.IsMatch(o.CustomerID, "^T")),
15951596
entryCount: 6);
15961597
}
1598+
1599+
[ConditionalTheory]
1600+
[MemberData(nameof(IsAsyncData))]
1601+
public virtual Task Regex_IsMatch_MethodCall_constant_input(bool async)
1602+
{
1603+
return AssertQuery(
1604+
async,
1605+
ss => ss.Set<Customer>().Where(o => Regex.IsMatch("ALFKI", o.CustomerID)),
1606+
entryCount: 1);
1607+
}
15971608
}
15981609
}

test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs

+6
Original file line numberDiff line numberDiff line change
@@ -1548,11 +1548,17 @@ public override async Task Projecting_Math_Truncate_and_ordering_by_it_twice3(bo
15481548
//WHERE [o].[OrderID] < 10250
15491549
//ORDER BY [A] DESC");
15501550
}
1551+
15511552
public override Task Regex_IsMatch_MethodCall(bool async)
15521553
{
15531554
return AssertTranslationFailed(() => base.Regex_IsMatch_MethodCall(async));
15541555
}
15551556

1557+
public override Task Regex_IsMatch_MethodCall_constant_input(bool async)
1558+
{
1559+
return AssertTranslationFailed(() => base.Regex_IsMatch_MethodCall_constant_input(async));
1560+
}
1561+
15561562
private void AssertSql(params string[] expected)
15571563
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
15581564

test/EFCore.Sqlite.FunctionalTests/Query/NorthwindFunctionsQuerySqliteTest.cs

+9
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,15 @@ public override async Task Regex_IsMatch_MethodCall(bool async)
520520
WHERE regexp('^T', ""c"".""CustomerID"")");
521521
}
522522

523+
public override async Task Regex_IsMatch_MethodCall_constant_input(bool async)
524+
{
525+
await base.Regex_IsMatch_MethodCall_constant_input(async);
526+
527+
AssertSql(@"SELECT ""c"".""CustomerID"", ""c"".""Address"", ""c"".""City"", ""c"".""CompanyName"", ""c"".""ContactName"", ""c"".""ContactTitle"", ""c"".""Country"", ""c"".""Fax"", ""c"".""Phone"", ""c"".""PostalCode"", ""c"".""Region""
528+
FROM ""Customers"" AS ""c""
529+
WHERE regexp(""c"".""CustomerID"", 'ALFKI')");
530+
}
531+
523532
private void AssertSql(params string[] expected)
524533
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
525534
}

0 commit comments

Comments
 (0)