Skip to content

SqlNullabilityProcessor ignores Contains item visitation #32208

@shvmgpt116

Description

@shvmgpt116

I am running GIT test QueryBugsTest.Nested_contains_with_enum. The test is executing following LINQ-

var query = context.Todos
    .Where(x => keys.Contains(todoTypes.Contains(x.Type) ? key : key))
    .ToList();

The test was working fine with Oracle EFCore 7 provider. However it seems there is some regression issue introduced from the relational layer in EFCore 8 daily label, due to which the test is failing.

Here is my observation.

SqlServer EFCore 7 provider used to generate following query for it-

SELECT [t].[Id], [t].[Type]
FROM [Todos] AS [t]
WHERE CASE
    WHEN [t].[Type] = 0 THEN @__key_2
    ELSE @__key_2
END IN ('0a47bcb7-a1cb-4345-8944-c58f82d6aac7', '5f221fb9-66f4-442a-92c9-d97ed5989cc7')

However in EFCore 8 provider, the query has been changed to-

SELECT [t].[Id], [t].[Type]
FROM [Todos] AS [t]
WHERE CASE
    WHEN [t].[Type] = 0 THEN @__key_2
    ELSE @__key_2
END IN (
    SELECT [k].[value]
    FROM OPENJSON(@__keys_0) WITH ([value] uniqueidentifier '$') AS [k]
)

For the database providers which don't support OPENJSON or similar functionality, they may want to keep on generating the query which was getting generated with EFCore 7 provider.

For Ex:- Oracle EFCore 7 provider generates following query for the test-

SELECT "t"."Id", "t"."Type"
FROM "Todos" "t"
WHERE CASE
    WHEN "t"."Type" = 0 THEN :key_2
    ELSE :key_2
END IN ('B7BC470ACBA145438944C58F82D6AAC7', 'B91F225FF4662A4492C9D97ED5989CC7')

However in EFCore 8 the query has been changed to-

SELECT "t"."Id", "t"."Type"
FROM "Todos" "t"
WHERE CASE
WHEN "t"."Type" IN ( ) THEN :key_2
ELSE :key_2
END IN ('B7BC470ACBA145438944C58F82D6AAC7', 'B91F225FF4662A4492C9D97ED5989CC7')

While debugging the relational layer code (Method SqlNullabilityProcessor.VisitIn) . It seems EFCore 7 used to convert certain InExpression to SqlBinaryExpression.
For Ex:- There will be two InExpression for the above LINQ but the inner one will be converted to SqlBinaryExpression and the provider will generate [t].[Type] = 0 corresponding to the SqlBinaryExpression.
However in EFCore 8 provider, the converted SqlBinaryExpression isn't used to generate the SQL if InExpression.SubQuery is null.

Is this expected? If yes, then InExpression.Value field shouldn't be null (which is the case as of now). The InExpression which is used to generate SQL "t"."Type" IN ( ) has null value.

This seems to be an issue from the relational layer. Please could someone clarify.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions