Skip to content
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

[release/9.0] Fix conditional test evaluation in funcletizer #34886

Merged
merged 1 commit into from
Oct 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions EFCore.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ The .NET Foundation licenses this file to you under the MIT license.
<s:Boolean x:Key="/Default/UserDictionary/Words/=fallbacks/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Formattable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=funcletization/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=funcletize/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Funcletizer/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Includable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=initializers/@EntryIndexedValue">True</s:Boolean>
Expand Down
4 changes: 2 additions & 2 deletions src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ protected override Expression VisitConditional(ConditionalExpression conditional
var test = Visit(conditional.Test, out var testState);

// If the test evaluates, simplify the conditional away by bubbling up the leg that remains
if (testState.IsEvaluatable && Evaluate(conditional.Test) is bool testBoolValue)
if (testState.IsEvaluatable && Evaluate(test) is bool testBoolValue)
{
return testBoolValue
? Visit(conditional.IfTrue, out _state)
Expand Down Expand Up @@ -905,7 +905,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCall)
var method = methodCall.Method;

// Handle some special, well-known functions
// If this is a call to EF.Constant(), or EF.Parameter(), then examine the operand; it it's isn't evaluatable (i.e. contains a
// If this is a call to EF.Constant(), or EF.Parameter(), then examine the operand; if it isn't evaluatable (i.e. contains a
// reference to a database table), throw immediately. Otherwise, evaluate the operand (either as a constant or as a parameter) and
// return that.
if (method.DeclaringType == typeof(EF))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4547,11 +4547,25 @@ public override Task MemberInitExpression_NewExpression_is_funcletized_even_when
async, async a =>
{
await base.MemberInitExpression_NewExpression_is_funcletized_even_when_bindings_are_not_evaluatable(a);

AssertSql(
"""
SELECT VALUE c["id"]
FROM root c
WHERE STARTSWITH(c["id"], "A")
""");
});

public override Task Funcletize_conditional_with_evaluatable_test(bool async)
=> Fixture.NoSyncTest(
async, async a =>
{
await base.Funcletize_conditional_with_evaluatable_test(a);

AssertSql(
"""
SELECT VALUE c
FROM root c
""");
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5150,6 +5150,16 @@ private class Dto(string value)
public Dto NestedDto { get; set; }
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Funcletize_conditional_with_evaluatable_test(bool async)
=> AssertQuery(
async,
ss => ss.Set<Customer>().Where(c => (AlwaysFalse() && c.CustomerID == "ALFKI" ? "yes" : "no") == "no"));

private static bool AlwaysFalse()
=> false;

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task Null_parameter_name_works(bool async)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5657,6 +5657,17 @@ WHERE [c].[CustomerID] LIKE N'A%'
""");
}

public override async Task Funcletize_conditional_with_evaluatable_test(bool async)
{
await base.Funcletize_conditional_with_evaluatable_test(async);

AssertSql(
"""
SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region]
FROM [Customers] AS [c]
""");
}

public override async Task Projecting_collection_split(bool async)
{
await base.Projecting_collection_split(async);
Expand Down