-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Translate x.parse #28337
base: main
Are you sure you want to change the base?
Translate x.parse #28337
Conversation
src/EFCore.SqlServer/Query/Internal/SqlServerMethodCallTranslatorProvider.cs
Outdated
Show resolved
Hide resolved
test/EFCore.Cosmos.FunctionalTests/Query/NorthwindFunctionsQueryCosmosTest.cs
Outdated
Show resolved
Hide resolved
src/EFCore.SqlServer/Query/Internal/SqlServerParseTranslator.cs
Outdated
Show resolved
Hide resolved
Can we also get tests which converts from actual string values. Also some negative tests where the string is not exactly parse-able and we verify database behavior. |
Added tests against overflow. Added tests against bad format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes. This looks almost ready, see below for some nits and test cleanup.
src/EFCore.SqlServer/Query/Internal/SqlServerParseTranslator.cs
Outdated
Show resolved
Hide resolved
{ | ||
await AssertQuery( | ||
async, | ||
ss => ss.Set<Order>().Where(o => o.CustomerID == "ALFKI") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merge the two Where clauses (here and below). Also consider removing the check for CustomerID - is there any reason to restrict to those rows only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some rows are not parse-able, making them not suitable for this test.
.Where(o => byte.Parse(Convert.ToString(o.OrderID % 1)) >= 0), | ||
entryCount: 6); | ||
|
||
await AssertQuery( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason for the 2nd test query? I can see this below as well - the point here generally isn't to check that the database operation works (we don't test the database, only EF), so I'm not sure what this one checks beyond the above.
Unless the extra queries add coverage for EF specifically, I think it's better to just do one query per test.
test/EFCore.Specification.Tests/Query/NorthwindFunctionsQueryTestBase.cs
Outdated
Show resolved
Hide resolved
nameof instead of string. Merge the Where clauses.
@roji Is there anything else? |
any updates on this @roji ? |
@MaRK0960 sorry for not giving this any attention - the 7.0 release (and resulting bugfixes) are have taken up most of my time. I'll do my best to look at this again in the next couple of weeks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MaRK0960 apologies for letting this sit for so long without reviewing. Aside from one important note (the one about type inference), I think this is more or less ready; I'm happy to also take over this (as we haven't responded for so long), let me know what you want to do.
async, | ||
ss => ss.Set<Customer>() | ||
.Where(c => c.CustomerID == "ALFKI") | ||
.Select(c => byte.Parse(c.CustomerID))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's never a good idea to put the tested invocation in the top-most select, because providers that don't have a translation for it will go into client evaluation. Ideally, these tests would simply have Parse in the Where clause instead.
@@ -14,4 +14,56 @@ public class NorthwindFunctionsQueryInMemoryTest : NorthwindFunctionsQueryTestBa | |||
{ | |||
//TestLoggerFactory.TestOutputHelper = testOutputHelper; | |||
} | |||
|
|||
public override Task Byte_Parse_Non_Numeric_Bad_Format(bool async) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not great to force all providers to override and catch an exception... But on the other hand it's true that the exception type itself varies from provider to provider. It may be enough to simply verify that an exception is caught in the base implementation without asserting which kind it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a test in SqlServer that checks if all tests are overridden:
efcore/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindFunctionsQuerySqlServerTest.cs
Lines 26 to 28 in 3f10651
[ConditionalFact] | |
public virtual void Check_all_tests_overridden() | |
=> TestHelpers.AssertAllMethodsOverridden(GetType()); |
And if the assertion is done in the base class, we can't override it.
IDiagnosticsLogger<DbLoggerCategory.Query> logger) | ||
=> SupportedMethods.Contains(method) | ||
? _sqlExpressionFactory.Function( | ||
"CONVERT", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a subtle problem here, where the type mapping coming out of the conversion is fixed and depends only on the CLR type; this doesn't allow for type inference to apply a type mapping from the other side of e.g. a comarison.
For example, let's assume you do int.Parse(decimalParam) == b.SomeDecimalColumn
, where SomeColumn has a type mapping of decimal(5,2)
. Your translation of int.Parse
would convert decimalParam to decimal(18,2)
, because that's the fixed value in the table above; but it should allow the column type mapping to be inferred from the other side instead.
The right way to do this would be to simply use _sqlExpressionFactory.Convert()
, specifying only the CLR type and not the type mapping. This produces CAST(x AS y)
instead of CONVERT
, and since the type mapping is null, it can be inferred from the other side.
No problem, I will continue working on it. |
@MaRK0960 ok great, let me know if you run out of time or something, otherwise you can ask for another review after you've made changes etc. |
@roji: ping |
I refactored the tests to their new suites, and removed the error tests because they seemed irrelevant to testing EF. |
Fixes #28287