-
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
#10955 - Using queries within a checked context #19593
Conversation
Merge from Base Repo
Part of #14572 (VB turns checking on by default) |
Overall problem with this approach is that we strip out all convert nodes. Instead, (per EF Team design decision mentioned by @ajcvickers ) we should only be ignoring convert nodes that are not client-evaluated. So, this code should be part of translation ( [ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Checked_context_with_addition_does_not_fail_client_eval(bool isAsync)
{
checked
{
return AssertQueryScalar(
isAsync,
ss => ss.Set<LocustLeader>().Select(w => w.ThreatLevel >= ((int)(long?)5 + (long?)ClientMethod(w.ThreatLevel))));
}
}
public static short ClientMethod(short arg) => arg; With the current approach, this produces the following query plan:
Convert nodes around ClientMethod should be checked |
wrt testing approach, I think using |
test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Outdated
Show resolved
Hide resolved
test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Outdated
Show resolved
Hide resolved
@maumar re: testing for client-eval, what would be the best way test specifically that in a client eval scenario we don't remove the checked nodes? I will transition this back to RelationalTranslator - I had this originally (by simply treating checked nodes as their unchecked equivalent) but decided to pull it out. I wasn't (and still am not to be honest) where the boundary is between the SQL and non-SQL translation elements. |
@svengeance only place we allow client eval is projection, so you can create a client method, call it in the Select, make sure that the method takes some column value as argument, so that it doesn't get funletized out. The result of the function can be whatever, so you can just return a constant that would overflow when convert (or other relevant operation) is applied on it. You can then make sure that correct exception is thrown by using Assert.ThrowsAsync |
I've moved the IgnoreChecked visitor to the relational level and am observing the desired effects. To be frank I still haven't fully grasped the pipeline for translation yet and this was a..hopefully intelligent shot in the dark for placement. My thoughts are that the method I used ( Appreciate your guidance/patience and followup. |
src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs
Outdated
Show resolved
Hide resolved
5812751
to
a690996
Compare
test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Outdated
Show resolved
Hide resolved
@svengeance changes look good! Please squash-rebase on current master and it should be ready to commit. |
src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
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.
Also update Cosmos & InMemory providers
Given that the InMem provider is usually true to C#'s standards as opposed to relational standards, is this checked->unchecked behavior desired there? Or did you mean something different? I will update Cosmos and add the appropriate test coverage. |
8fee49c
to
128a2a2
Compare
With adding tests to cosmos - from what I'm gathering reading other issues regarding testing this provider it seems you run a cosmos emulator? Is there any documentation on how to set this up and working with EF here so I can write the same few tests, or should I just write a bit blindly and let the CI tackle it? 😄 |
d3ce728
to
913cf9a
Compare
@svengeance - Hold off for InMemory, I will ask team in the meeting on Friday to decide where to go. |
I got the emulator functioning, however I'm having difficulties with proving out functionality. Maybe related to #17246? Issue aside, I can't find any code supporting server-side conversion on VisitUnary like I have the code placed in Cosmos mirroring sql server. Given that conversion seems unsupported yet (or again, I could be missing where?), how should I proceed? |
@svengeance - For in memory we won't do anything special. If it throws on server side, let it be. Cosmos does not have server side convert so Convert client eval or throws. ConvertChecked would follow the same. Binary operators would follow similarity with relational. |
…latingExpressionVisitor
…ir unchecked equivalents
5151090
to
6cb109c
Compare
Added the cosmos test to verify checked binary is unchecked, I managed to figure out a use-case for the VisitUnary where I believe everything should be completed now, if I'm not concerned about in-memory operations here. I've went ahead and rebased as well. |
Merged to master in #19862 |
Definitely thank you for the guidance on this one, and the introduction to cosmos. |
Fixes #10955
This should be fairly straightforward. I followed advice from @smitpatel on the Issue and created a visitor in the query compilation preprocessor to convert all checked expressions to their unchecked equivalent.
I could use some advice on making the tests more thorough. Given that the intention is to make checked/unchecked translations equivalent (minus client evaluation), it'd be nice to evaluate the
AssertQuery
in both a checked and unchecked context, but I didn't find a pattern for that kind of thing within the GearsOfWar test suite.As an aside, I tested this implementation by switching all projects to use assembly-wide overflow checking. The only resultant failures were due to client-side overflow evaluation (i.e. passing -1 to a
ulong
), but all queries passed otherwise.Cheers