Numeric storage parameters are formatted with the current culture, so migrations emit 0,01 instead of 0.01
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 30/100
調査の方向性
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.
索引モデルが issue の本文から書いたものです。
説明
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():
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.
- 主要言語
- C#
- スター
- 1.8k
- フォーク
- 268
- 平均マージ
- 2時間 35分
- マージ済み PR(30日)
- 136
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
npgsql/efcore.pg のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
NTS: the M ordinate is dropped from geometry SQL literals and from geometries stored in JSON対応中かも @Ahmed7991 が 5 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
npgsql/efcore.pg#4093 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
`TimeSpan`/`Duration` component members: negative values are floored, and intervals computed in SQL are read field by field対応中かも @jeremy-morren が 11 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
`Contains` on a JSON primitive collection compares JSON text, so `DateTime` and `TimeOnly` items never match対応中かも @Mr444-dev が 7 日前に担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
npgsql/efcore.pg#4099 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Array translations: chained `Skip`/`Take` return an empty array, `int.MaxValue` bounds overflow, and `Intersect().Any()` ignores NULL elements再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 30/100
メンテナーはふだん 1 日以内に返信
npgsql/efcore.pg の issue をすべて見る
似ている issue
-
Issue-Bug Needs-Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 2 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
JiaFeiMiao-K-Cat/DiscImageStudio#281 ·
メンテナーはふだん 1 日以内に返信
-
area/access-management Frontend onboarding candidate :handshake:
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
Altinn/altinn-auth#4941 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
aws/aws-sdk-net#4586 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
Kryptos-FR/MarkView.Avalonia#269 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信