From fa0bf7ef2cdd675dec6e46cef01a90258c566888 Mon Sep 17 00:00:00 2001 From: Shay Rojansky Date: Fri, 28 Feb 2025 17:24:00 +0200 Subject: [PATCH] Preserve collation when changing column type Fixes #3476 --- .../NpgsqlMigrationsSqlGenerator.cs | 10 ++++++++-- .../Migrations/MigrationsNpgsqlTest.cs | 20 +++++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs index 6e09ed6be..fccab7d18 100644 --- a/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs +++ b/src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs @@ -456,9 +456,15 @@ protected override void Generate(AlterColumnOperation operation, IModel? model, .Append("TYPE ") .Append(type); - if (newCollation != oldCollation) + if (newCollation is not null) { - builder.Append(" COLLATE ").Append(DelimitIdentifier(newCollation ?? "default")); + builder.Append(" COLLATE ").Append(DelimitIdentifier(newCollation)); + } + else if (type == oldType) + { + // If the type is the same, make it more explicit that we're just resetting the collation to the default + // (this isn't really required) + builder.Append(" COLLATE ").Append(DelimitIdentifier("default")); } builder.AppendLine(";"); diff --git a/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs index 9d813d56f..c4ebc7bc3 100644 --- a/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Migrations/MigrationsNpgsqlTest.cs @@ -964,9 +964,25 @@ await Test( public override async Task Alter_column_change_type() { - await base.Alter_column_change_type(); + await Test( + builder => builder.Entity("People").Property("Id"), + builder => builder.Entity("People").Property("SomeColumn") + .HasColumnType("varchar") + .UseCollation(NonDefaultCollation), + builder => builder.Entity("People").Property("SomeColumn") + .HasColumnType("text") + .UseCollation(NonDefaultCollation), + model => + { + var table = Assert.Single(model.Tables); + var column = Assert.Single(table.Columns, c => c.Name == "SomeColumn"); + Assert.Equal(NonDefaultCollation, column.Collation); + }); - AssertSql("""ALTER TABLE "People" ALTER COLUMN "SomeColumn" TYPE bigint;"""); + AssertSql( + """ +ALTER TABLE "People" ALTER COLUMN "SomeColumn" TYPE text COLLATE "POSIX"; +"""); } public override async Task Alter_column_make_required()