Hello! I believe I've encountered a regression while upgrading Npgsql.EntityFrameworkCore.PostgreSQL from 9.0.4 to 10.0.2.
arrayColumn.Contains(element) used to translate into [arrayColumn @> ARRAY[element]] as stated in docs.
But now it translates into element = ANY(arrayColumn). This can be critical since element = ANY(arrayColumn) operator is not supported by GIN index. Now my query seq scans the table.
Minimal repro code
using Microsoft.EntityFrameworkCore;
using Npgsql;
var dataSource = new NpgsqlDataSourceBuilder("Host=localhost")
.Build();
var options = new DbContextOptionsBuilder<TestContext>()
.UseNpgsql(dataSource)
.EnableSensitiveDataLogging()
.Options;
await using var ctx = new TestContext(options);
var query = ctx.Items.Where(i => i.Names.Contains("Test"));
Console.WriteLine(query.ToQueryString());
public class TestContext : DbContext
{
public TestContext(DbContextOptions<TestContext> options) : base(options)
{
}
public DbSet<Item> Items => Set<Item>();
}
public class Item
{
public int Id { get; set; }
public string[] Names { get; set; } = Array.Empty<string>();
public int[] Numbers { get; set; } = Array.Empty<int>();
}
This repro code produces:
SELECT i."Id", i."Names", i."Numbers"
FROM "Items" AS i
WHERE 'Test' = ANY (i."Names")
I've tested various expressions and I can't make it produce @> as it used to before. All variations produce WHERE 'Test' = ANY (i."Names"). To name a few I've tried:
- var query = ctx.Items.Where(i => i.Names.AsEnumerable().Contains("Test"));
- var query = ctx.Items.Where(i => i.Names.ToList().Contains("Test"));
- var query = ctx.Items.Where(i => i.Names.Any(n => n == "test"));
With Npgsql.EntityFrameworkCore.PostgreSQL 9.0.4 all those variations translate to:
SELECT i."Id", i."Names", i."Numbers"
FROM "Items" AS i
WHERE i."Names" @> ARRAY['test']::text[]
This query is supported by GIN index and I believe it is the correct translation.
P.S. - this feels related to a C# 14 breaking change of overload resolution with span parameters. That was my original thought but adding AsEnumerable() or downgrading to C# 10 didn't help. Maybe this change somehow affected the library itself but I am probably very wrong here.
Environment
| Component |
Version |
| .NET |
10.0 |
| C# |
14 (also fails on 10) |
| Microsoft.EntityFrameworkCore |
10.0.9 |
| Npgsql.EntityFrameworkCore.PostgreSQL |
10.0.2 |
Hello! I believe I've encountered a regression while upgrading Npgsql.EntityFrameworkCore.PostgreSQL from 9.0.4 to 10.0.2.
arrayColumn.Contains(element)used to translate into[arrayColumn @> ARRAY[element]]as stated in docs.But now it translates into
element = ANY(arrayColumn). This can be critical sinceelement = ANY(arrayColumn)operator is not supported by GIN index. Now my query seq scans the table.Minimal repro code
This repro code produces:
I've tested various expressions and I can't make it produce
@>as it used to before. All variations produceWHERE 'Test' = ANY (i."Names"). To name a few I've tried:With Npgsql.EntityFrameworkCore.PostgreSQL 9.0.4 all those variations translate to:
This query is supported by GIN index and I believe it is the correct translation.
P.S. - this feels related to a C# 14 breaking change of overload resolution with span parameters. That was my original thought but adding AsEnumerable() or downgrading to C# 10 didn't help. Maybe this change somehow affected the library itself but I am probably very wrong here.
Environment