= ANY with an AND/OR item omits parentheses, returning wrong results
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 82/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- csharp, postgresql
- Ambito
- backend-api-design, database
Direzione di ricerca
Inizia in src/EFCore.PG/Query/Internal/NpgsqlQuerySqlGenerator.cs, nell’implementazione di VisitArrayAny intorno alla riga 890, poi controlla la gestione esistente della precedenza e i relativi test. Riproduci il problema con la query Contains fornita e verifica che l’SQL generato raggruppi l’espressione AND prima di = ANY; aggiungi o aggiorna un test di regressione per confermare che la query restituisca le righe previste.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
VisitArrayAny writes the item without parentheses. When the item is an AND/OR expression, = binds tighter than AND, so Postgres applies = ANY to the last operand only. The query runs without error and returns the wrong rows.
bool[] availability = [false];
var unavailable = db.Products
.Where(p => availability.Contains(p.IsListed && p.InStock));
| SQL | Result | |
|---|---|---|
| Expected | WHERE (p."IsListed" AND p."InStock") = ANY (@availability) |
Banana, Cherry, Date |
| Actual | WHERE p."IsListed" AND p."InStock" = ANY (@availability) |
Banana |
Seed: Apple listed and in stock, Banana listed and out of stock, Cherry not listed and in stock, Date neither.
Full repro
using Microsoft.EntityFrameworkCore;
await using var db = new ShopContext();
await db.Database.EnsureDeletedAsync();
await db.Database.EnsureCreatedAsync();
db.Products.AddRange(
new Product { Name = "Apple", IsListed = true, InStock = true },
new Product { Name = "Banana", IsListed = true, InStock = false },
new Product { Name = "Cherry", IsListed = false, InStock = true },
new Product { Name = "Date", IsListed = false, InStock = false });
await db.SaveChangesAsync();
bool[] availability = [false];
var query = db.Products
.Where(p => availability.Contains(p.IsListed && p.InStock))
.Select(p => p.Name);
Console.WriteLine(query.ToQueryString());
Console.WriteLine(string.Join(", ", await query.ToListAsync()));
public class ShopContext : DbContext
{
public DbSet<Product> Products => Set<Product>();
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseNpgsql("Host=localhost;Username=postgres;Password=postgres;Database=any_repro");
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = "";
public bool IsListed { get; set; }
public bool InStock { get; set; }
}
Cause: NpgsqlQuerySqlGenerator.cs#L890 calls Visit(expression.Item) with no precedence check. The precedence table already ranks PgAnyExpression at 800 and AndAlso/OrElse at 500 (L1636).
Suggested fix, the same pattern as npgsql/npgsql#3927:
var requiresParentheses = RequiresParentheses(expression, expression.Item);
if (requiresParentheses)
{
Sql.Append("(");
}
Visit(expression.Item);
if (requiresParentheses)
{
Sql.Append(")");
}
Workaround: with a single picked value, filter on the expression or its negation (p.IsListed && p.InStock or !(p.IsListed && p.InStock)) in place of Contains.
Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3, PostgreSQL 17. Happy to send a PR if that helps.
- Lingua principale
- C#
- Stelle
- 1.8k
- Fork
- 268
- Merge medio
- 2h 35m
- PR unite (30g)
- 136
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di npgsql/efcore.pg
-
NTS: the M ordinate is dropped from geometry SQL literals and from geometries stored in JSONForse già presa @Ahmed7991 l’ha presa 5 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
npgsql/efcore.pg#4093 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
`TimeSpan`/`Duration` component members: negative values are floored, and intervals computed in SQL are read field by fieldForse già presa @jeremy-morren l’ha presa 11 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 1 giorno
-
Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01Forse già presa @Sorbitol l’ha presa 12 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 30/100
I maintainer di solito rispondono entro 1 giorno
-
`Contains` on a JSON primitive collection compares JSON text, so `DateTime` and `TimeOnly` items never matchForse già presa @Mr444-dev l’ha presa 7 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
npgsql/efcore.pg#4099 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Array translations: chained `Skip`/`Take` return an empty array, `int.MaxValue` bounds overflow, and `Intersect().Any()` ignores NULL elementsForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 30/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di npgsql/efcore.pg
Issue simili
-
Issue-Bug Needs-Triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
JiaFeiMiao-K-Cat/DiscImageStudio#281 ·
I maintainer di solito rispondono entro 1 giorno
-
area/access-management Frontend onboarding candidate :handshake:
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
Altinn/altinn-auth#4941 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
aws/aws-sdk-net#4586 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
Kryptos-FR/MarkView.Avalonia#269 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno