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
The
SqlNullabilityProcessorperforms invalid optimizations ofCASE operand WHENexpressions.Specifically, the
testIsConditionflag is not properly taken into account and(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:
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