dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.8k stars 3.19k forks source link

Adding a new (non-nullable) JSON column populates it with an empty string (invalid JSON) #32353

Closed roji closed 1 year ago

roji commented 1 year ago

When adding a new column, we add it with a column DEFAULT for the CLR default of the type (see this code in MigrationsModelDiffer); this means that the JSON column default is an empty string:

ALTER TABLE [Blogs] ADD [JsonDetails] nvarchar(max) NOT NULL DEFAULT N'';

For PostgreSQL, this fails since the column is typed as jsonb, and an empty string isn't a valid JSON document. I've worked around this in the migrations SQL generator (PR), but that's not the right place for this - it notably leaves the empty string in the scaffolded migration code.

This doesn't error on e.g. SQL Server because the column type is nvarchar(max), but we end up with invalid data in the column. I'm not sure if this can cause a real bug, but it certainly could.

Note relationship with #28596.

/cc @maumar

roji commented 1 year ago

Note that to work around this in Npgsql, I considered temporarily overriding MigrationsModelDiffer to do #32354 in the provider. But tons of stuff there is private, so it wasn't possible to override that particular code within copying in really large quantities of the differ. That isn't great, since removing the migrations SQL generator hack I did in https://github.com/npgsql/efcore.pg/pull/2967 would be a breaking change (people will already have scaffolded migrations with an empty string as the default).