Skip to content

Invalid optimization of CASE op WHEN expressions #33867

@ranma42

Description

@ranma42

The SqlNullabilityProcessor performs invalid optimizations of CASE operand WHEN expressions.

Specifically, the testIsCondition flag is not properly taken into account and

CASE x
  WHEN TRUE THEN y
END

(and some variants) are incorrectly treated as if the operand was not specified and optimized to just y.

An example program that showcases the bug is:

using System;
using System.Data;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;

using var db = new BloggingContext();

db.Database.EnsureDeleted();
db.Database.EnsureCreated();

db.Blogs
    .Select(x => db.Switch(
        x.BlogId > 20,
        false, 1,
        true, 2,
        3
    ))
    .ToList();

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

    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options
            .LogTo(Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information)
            .UseSqlite($"Data Source=test.db");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder
            .HasDbFunction(typeof(BloggingContext).GetMethod(nameof(Switch))!)
            .HasTranslation(args =>
                new CaseExpression(
					args[0],
					[
						new CaseWhenClause(args[1], args[2]),
						new CaseWhenClause(args[3], args[4]),
					],
					args[5])
            );
    }

    public int Switch(bool o, bool t1, int v1, bool t2, int v2, int v3)
        => throw new NotSupportedException();
}

public class Blog
{
    public int BlogId { get; set; }
}

Include provider and version information

EF Core version: 8.0.6
Database provider: Microsoft.EntityFrameworkCore.Sqlite
Target framework: .NET 8.0
Operating system: Linux (/WSL)
IDE: Visual Studio Code 1.89.1

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions