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

Translate Min/Max over inline collection via LEAST/GREATEST #32332

Closed
roji opened this issue Nov 17, 2023 · 4 comments · Fixed by #32338
Closed

Translate Min/Max over inline collection via LEAST/GREATEST #32332

roji opened this issue Nov 17, 2023 · 4 comments · Fixed by #32338
Assignees
Labels
area-query breaking-change closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-enhancement
Milestone

Comments

@roji
Copy link
Member

roji commented Nov 17, 2023

Given the following query:

_ = context.Blogs
    .Select(b => new[] { b.Updated, b.Updated2 }.Max())
    .ToList();
Full code
await using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();

_ = context.Blogs
    .Select(b => new[] { b.Updated, b.Updated2 }.Max())
    .ToList();

public class BlogContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer(@"Server=localhost;Database=test;User=SA;Password=Abcd5678;Connect Timeout=60;ConnectRetryCount=0;Encrypt=false")
            .LogTo(Console.WriteLine, LogLevel.Information)
            .EnableSensitiveDataLogging();
}

public class Blog
{
    public int Id { get; set; }
    public DateTime Updated { get; set; }
    public DateTime Updated2 { get; set; }
    public List<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public DateTime Updated { get; set; }

    public Blog Blog { get; set; }
}

EF 8.0 generates the following SQL:

SELECT (
    SELECT MAX([v].[Value])
    FROM (VALUES ([b].[Updated]), ([b].[Updated2])) AS [v]([Value]))
FROM [Blogs] AS [b]

We should recognize Min/Max over an inline collection, and just translate to LEAST/GREATEST:

SELECT GREATEST([b].[Updated], [b].[Updated2])
FROM [Blogs] AS [b]

Note that #31681 already tracks adding EF.Functions.{Least,Greatest} for users to invoke directly; this issue tracks changing the Min/Max translation.

@roji roji self-assigned this Nov 18, 2023
roji added a commit to roji/efcore that referenced this issue Nov 18, 2023
roji added a commit to roji/efcore that referenced this issue Nov 18, 2023
roji added a commit to roji/efcore that referenced this issue Nov 18, 2023
roji added a commit to roji/efcore that referenced this issue Nov 18, 2023
roji added a commit to roji/efcore that referenced this issue Nov 18, 2023
roji added a commit to roji/efcore that referenced this issue Nov 27, 2023
roji added a commit that referenced this issue Nov 28, 2023
@roji roji added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Nov 28, 2023
@roji roji added this to the 9.0.0 milestone Nov 28, 2023
@roji
Copy link
Member Author

roji commented Nov 28, 2023

As per team decision, EF will always assume the latest SQL Server is being used; this means this is a breaking change, as queries using Max() over inline collections will start breaking for users.

@ErikEJ
Copy link
Contributor

ErikEJ commented Nov 28, 2023

@roji Interestingly, this also works on a SQL Server 2022 with a database a compat level 100:

SELECT GREATEST('6.62', 3.1415, N'7') AS GreatestVal;

@roji
Copy link
Member Author

roji commented Nov 28, 2023

Huh, yeah, that's a bit odd...!

@ErikEJ
Copy link
Contributor

ErikEJ commented Nov 28, 2023

I think it is by design - https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-compatibility-level?view=sql-server-ver16#differences-between-compatibility-levels

"New Transact-SQL syntax isn't gated by database compatibility level, except when they can break existing applications by creating a conflict with user Transact-SQL code. These exceptions are documented in the next sections of this article that outline the differences between specific compatibility levels."

Probably OPENJSON is an exception: https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-ver16

@ajcvickers ajcvickers modified the milestones: 9.0.0, 9.0.0-preview1 Jan 31, 2024
@roji roji modified the milestones: 9.0.0-preview1, 9.0.0 Oct 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query breaking-change closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants