`ExecuteUpdate` copying an out-of-range JSON array element sets the whole JSON column to NULL
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 70/100
Direzione di ricerca
Start in src/EFCore.PG/Query/Internal/NpgsqlQueryableMethodTranslatingExpressionVisitor.cs at the setter (lines 1405-1416) and the element nullability checks (lines 926-931, 1490). Run the C# repro from the issue to observe the JSON column becoming NULL. Done means an out-of-range JSON array index in ExecuteUpdate sets the target property to null, not the whole document to NULL.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
| Environment | |
|---|---|
| PostgreSQL | 18.6 (postgres:18), session TimeZone Etc/UTC |
| .NET 10 | runtime 10.0.11, Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3, EF Core 10.0.4 |
| .NET 11 | runtime 11.0.0-rc.2, Npgsql.EntityFrameworkCore.PostgreSQL 11.0.0-rc.2, EF Core 11.0.0-rc.2 |
| Also | Npgsql 10.0.3 on both lines, macOS arm64 |
Both lines print the same output. main at 150011d has the same code.
// Doc is {"Age": 1, "Name": "keep-me", "Nums": [1, 2]}, so Nums[5] is out of range
await context.Rows.ExecuteUpdateAsync(s => s.SetProperty(r => r.Doc!.Age, r => (int?)r.Doc!.Nums[5]));
UPDATE "Rows" AS r
SET "Doc" = jsonb_set(r."Doc", '{Age}', r."Doc" #> '{Nums,5}')
r."Doc" #> '{Nums,5}' is NULL, and jsonb_set(doc, path, NULL) returns NULL, so the whole document is gone. At worst, Age should become null.
Repro
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
await using var context = new TestContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
context.Rows.Add(new Row { Doc = new Doc { Name = "keep-me", Age = 1, Nums = [1, 2] } });
await context.SaveChangesAsync();
// Nums has two elements, so Nums[5] is out of range: Age should become null, at worst
await context.Rows.ExecuteUpdateAsync(s => s.SetProperty(r => r.Doc!.Age, r => (int?)r.Doc!.Nums[5]));
Console.WriteLine($"Document after the update: {await context.Database.SqlQueryRaw<string>("""SELECT coalesce("Doc"::text, 'NULL') AS "Value" FROM "Rows" """).SingleAsync()}");
public class TestContext : DbContext
{
public DbSet<Row> Rows => Set<Row>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(Environment.GetEnvironmentVariable("Test__Npgsql__DefaultConnection"))
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Row>().ComplexProperty(r => r.Doc, d => d.ToJson());
}
public class Row
{
public int Id { get; set; }
public Doc? Doc { get; set; }
}
public class Doc
{
public string Name { get; set; } = "";
public int? Age { get; set; }
public List<int> Nums { get; set; } = [];
}
Output, the same on both lines:
Document after the update: NULL
The element access is created as non-nullable (isElementNullable, NpgsqlQueryableMethodTranslatingExpressionVisitor.cs#L926-L931), so MayReturnNull (NpgsqlQueryableMethodTranslatingExpressionVisitor.cs#L1490) says no, and the setter (NpgsqlQueryableMethodTranslatingExpressionVisitor.cs#L1405-L1416) uses plain jsonb_set, without COALESCE(..., 'null') and without jsonb_set_lax. #3850 fixed the sources that are visibly nullable; an out-of-range index is still unprotected. Treating JSON element access as nullable in the setter would close this.
- 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
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
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
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