Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01

Ouverte
#4,114 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@Sorbitol y travaille déjà.

Depuis le 29/10/2026.

  • #4115 par @Sorbitol — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
30/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
À l'abandon
Stack technique
csharp, postgresql
Domaine
databases

Piste de recherche

Start in src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs, at GetStorageParameters, where non-boolean and non-string values are formatted. Check the migration SQL generator tests for storage parameters and add coverage for a decimal value under a comma-decimal culture. Done means generated CREATE TABLE, CREATE INDEX, and ALTER TABLE storage parameter SQL uses a dot decimal separator; pull request #4115 is already open.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Description

A non-integer numeric storage parameter (double, float, decimal) is written into DDL with the current culture's decimal separator. Under sv-SE, de-DE, fr-FR and other comma cultures, HasStorageParameter("autovacuum_vacuum_scale_factor", 0.01) generates autovacuum_vacuum_scale_factor=0,01, which breaks CREATE TABLE … WITH (…) and ALTER TABLE … SET (…) (and CREATE INDEX … WITH (…), which shares the same helper): the statement fails with a syntax error.

Model Culture Generated SQL
HasStorageParameter("autovacuum_vacuum_scale_factor", 0.01) en-US …(autovacuum_vacuum_scale_factor=0.01) ✅
same sv-SE …(autovacuum_vacuum_scale_factor=0,01) ❌
Environment
  • PostgreSQL 18.6 (only to confirm the error; the repro itself needs no database)
  • .NET SDK 10.0.403 / runtime 10.0.14, Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3, EF Core 10.0.4, Npgsql 10.0.3
  • Windows 11, current culture sv-SE
Repro
using System.Globalization;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

foreach (var culture in new[] { "en-US", "sv-SE" })
{
    CultureInfo.CurrentCulture = new CultureInfo(culture);
    Console.WriteLine($"--- {culture} ---");

    using var context = new TestContext();
    var generator = context.GetService<IMigrationsSqlGenerator>();
    var differ = context.GetService<IMigrationsModelDiffer>();
    var model = context.GetService<IDesignTimeModel>().Model.GetRelationalModel();

    var operations = differ.GetDifferences(null, model);
    foreach (var command in generator.Generate(operations, context.Model))
        Console.WriteLine(command.CommandText);
}

public class TestContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder options)
        => options.UseNpgsql("Host=unused");

    protected override void OnModelCreating(ModelBuilder modelBuilder)
        => modelBuilder.Entity<Row>().HasStorageParameter("autovacuum_vacuum_scale_factor", 0.01);
}

public class Row
{
    public int Id { get; set; }
}

Output (Npgsql.EntityFrameworkCore.PostgreSQL 10.0.3):

--- en-US ---
CREATE TABLE "Row" (
    "Id" integer GENERATED BY DEFAULT AS IDENTITY,
    CONSTRAINT "PK_Row" PRIMARY KEY ("Id")
)
WITH (autovacuum_vacuum_scale_factor=0.01);

--- sv-SE ---
CREATE TABLE "Row" (
    "Id" integer GENERATED BY DEFAULT AS IDENTITY,
    CONSTRAINT "PK_Row" PRIMARY KEY ("Id")
)
WITH (autovacuum_vacuum_scale_factor=0,01);

Diffing a model with 0.2 against one with 0.01 gives, under sv-SE: ALTER TABLE "Row" SET (autovacuum_vacuum_scale_factor=0,01); (en-US: =0.01). de-DE and fr-FR produce the same 0,01.

PostgreSQL 18 rejects the sv-SE statement:

ERROR:  syntax error at or near "01"
LINE 5: WITH (autovacuum_vacuum_scale_factor=0,01);
                                               ^
Source reference

GetStorageParameters formats every value other than bool and string with a plain ToString():

https://github.com/npgsql/efcore.pg/blob/cd8b7f9ac6e37deb2bd7ea18d318b6c25fd1b5c1/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs#L2280-L2290

Its result is used by WITH (…) (emitted for both CREATE TABLE and CREATE INDEX) and by ALTER TABLE … SET (…), while other numeric DDL in the same file already uses CultureInfo.InvariantCulture (RESTART WITH, INCREMENT BY). A likely fix is Convert.ToString(a.Value, CultureInfo.InvariantCulture)! on line 2289.

(Links are to main; the code is identical in v10.0.3, L2066–L2075, and still present on hotfix/10.0.4.)

Similar to #787 (invariant culture for DateTime literals).

Workaround: pass the value as a string ("0.01"), which the generator quotes and PostgreSQL accepts.

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

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de npgsql/efcore.pg

Toutes les issues de npgsql/efcore.pg

Issues similaires

Plus d'issues C#

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.