Conversions to text: a `char` space is lost, `Convert.ToString(bool)` gives `true`, and `string.Join` with a null separator returns NULL
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 3/5
- Temps estimé
- 1-2 jours
- Accessibilité débutants
- 80/100
Piste de recherche
Start from NpgsqlStringMethodTranslator.cs (lines 217-225, 274-279) and NpgsqlObjectToStringTranslator.cs (102-107) to pad char values with rpad(x,1); in NpgsqlConvertTranslator.cs (36) use a CASE for bool like bool.ToString. Mimic #4001's rpad fix. Run the issue's repro and confirm the generated SQL matches .NET output (space kept, Convert.ToString(bool) gives True, null separator coalesced).
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
| 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 |
The first repro prints the same output on both lines; the IndexOf one differs by line, as shown. main at 150011d has the same code.
| LINQ | Row | .NET | PostgreSQL | SQL |
|---|---|---|---|---|
string.Join(sep, r.Tags), char sep = ' ' |
{a,b} |
a b |
ab |
array_to_string(r."Tags", @sep, '') |
r.Text.PadRight(4, sep), char sep = ' ' |
abc |
abc␠ |
abc |
rpad(r."Text", 4, @sep) |
r.Space.ToString() |
char column ' ' |
" " |
"" |
r."Space"::text |
r.Text.IndexOf(r.Space), 10.x only |
a b, ' ' |
1 | 0 | strpos(r."Text", r."Space") - 1 |
Convert.ToString(r.Flag) |
true |
True |
true |
r."Flag"::text |
string.Join(r.Separator, r.Tags) |
separator NULL | ab |
NULL | array_to_string(r."Tags", r."Separator", '') |
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 { Tags = ["a", "b"], Space = ' ', Flag = true, Separator = null, Text = "abc" });
await context.SaveChangesAsync();
var row = await context.Rows.AsNoTracking().SingleAsync();
var sep = ' ';
// 1. A space in character(1) is lost when it becomes text
Console.WriteLine($"string.Join(' ' parameter, Tags): .NET {string.Join(sep, row.Tags)}|, database {await context.Rows.Select(r => string.Join(sep, r.Tags)).SingleAsync()}|");
Console.WriteLine($"Text.PadRight(4, ' ' parameter): .NET {row.Text.PadRight(4, sep)}|, database {await context.Rows.Select(r => r.Text.PadRight(4, sep)).SingleAsync()}|");
Console.WriteLine($"Space.ToString(): .NET {row.Space.ToString()}|, database {await context.Rows.Select(r => r.Space.ToString()).SingleAsync()}|");
// 2. bool to text
Console.WriteLine($"Convert.ToString(Flag): .NET {Convert.ToString(row.Flag)}, database {await context.Rows.Select(r => Convert.ToString(r.Flag)).SingleAsync()}");
// 3. string.Join treats a null separator as ""
Console.WriteLine($"string.Join(null separator, Tags): .NET {string.Join(row.Separator, row.Tags)}, database {await context.Rows.Select(r => string.Join(r.Separator, r.Tags)).SingleAsync() ?? "NULL"}");
public class TestContext : DbContext
{
public DbSet<Row> Rows => Set<Row>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(Environment.GetEnvironmentVariable("Test__Npgsql__DefaultConnection"), o => o.UseNodaTime())
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public class Row
{
public int Id { get; set; }
public string[] Tags { get; set; } = [];
public char Space { get; set; }
public bool Flag { get; set; }
public string? Separator { get; set; }
public string Text { get; set; } = "";
}
Output (the | marks the end of each value), the same on both lines:
string.Join(' ' parameter, Tags): .NET a b|, database ab|
Text.PadRight(4, ' ' parameter): .NET abc |, database abc|
Space.ToString(): .NET |, database |
Convert.ToString(Flag): .NET True, database true
string.Join(null separator, Tags): .NET ab, database NULL
Repro (`IndexOf` with a char column, 10.x)
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 { Text = "a b", Space = ' ' });
await context.SaveChangesAsync();
var row = await context.Rows.AsNoTracking().SingleAsync();
Console.WriteLine($"Text.IndexOf(Space): .NET {row.Text.IndexOf(row.Space)}, database {await context.Rows.Select(r => r.Text.IndexOf(r.Space)).SingleAsync()}");
public class TestContext : DbContext
{
public DbSet<Row> Rows => Set<Row>();
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseNpgsql(Environment.GetEnvironmentVariable("Test__Npgsql__DefaultConnection"), o => o.UseNodaTime())
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public class Row
{
public int Id { get; set; }
public string Text { get; set; } = "";
public char Space { get; set; }
}
Output:
.NET 10, 10.0.3: Text.IndexOf(Space): .NET 1, database 0
.NET 11, 11.0.0-rc.2: Text.IndexOf(Space): .NET 1, database 1
charspaces.charcolumns and parameters arecharacter(1), and castingcharacter(n)totextstrips trailing spaces, so' 'becomes''. #4001 handled this forIndexOfonmainby padding withrpad(x, 1). Three places still lose it:string.Join(NpgsqlStringMethodTranslator.cs#L274-L279),PadLeft/PadRight(NpgsqlStringMethodTranslator.cs#L217-L225) andToString()(NpgsqlObjectToStringTranslator.cs#L102-L107). #4001 came with the new char-argument translations and isn't onhotfix/10.0.4, soIndexOf(char column)stays wrong on 10.x.Convert.ToString(bool)is::text(NpgsqlConvertTranslator.cs#L36).bool.ToString()already uses a CASE that givesTrue/False.string.Jointreats a null separator as empty.array_to_string(..., NULL, '')is NULL, soCOALESCE(separator, '')would match.
- Langage dominant
- C#
- Étoiles
- 1.8k
- Forks
- 268
- Merge moyen
- 2 h 35 min
- PR mergées (30 j)
- 136
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de npgsql/efcore.pg
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Les mainteneurs répondent en général sous 1 jour
-
NTS: the M ordinate is dropped from geometry SQL literals and from geometries stored in JSONPeut-être pris @Ahmed7991 l’a pris il y a 5 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 85/100
npgsql/efcore.pg#4093 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
`TimeSpan`/`Duration` component members: negative values are floored, and intervals computed in SQL are read field by fieldPeut-être pris @jeremy-morren l’a pris il y a 11 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
Les mainteneurs répondent en général sous 1 jour
-
Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01Peut-être pris @Sorbitol l’a pris il y a 12 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 30/100
Les mainteneurs répondent en général sous 1 jour
-
`Contains` on a JSON primitive collection compares JSON text, so `DateTime` and `TimeOnly` items never matchPeut-être pris @Mr444-dev l’a pris il y a 7 jours. Ouverte
Difficulté 4/5 3-5 jours Accessibilité débutants 45/100
npgsql/efcore.pg#4099 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de npgsql/efcore.pg
Issues similaires
-
Issue-Bug Needs-Triage
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
Les mainteneurs répondent en général sous 2 jours
-
Difficulté 2/5 1-3 heures Accessibilité débutants 66/100
JiaFeiMiao-K-Cat/DiscImageStudio#281 ·
Les mainteneurs répondent en général sous 1 jour
-
area/access-management Frontend onboarding candidate :handshake:
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
Altinn/altinn-auth#4941 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
aws/aws-sdk-net#4586 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 82/100
Kryptos-FR/MarkView.Avalonia#269 · 1 réaction ·
Les mainteneurs répondent en général sous 1 jour