Skip to content

Commit

Permalink
Handle transition from SERIAL to IDENTITY in idempotent migrations
Browse files Browse the repository at this point in the history
Fixes #1157
  • Loading branch information
roji committed Aug 29, 2020
1 parent caf568f commit ab663ab
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/EFCore.PG/Migrations/NpgsqlMigrationsSqlGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,10 @@ protected override void Generate(AlterColumnOperation operation, IModel model, M
.AppendLine($"ALTER SEQUENCE {sequence} RENAME TO {oldSequenceWithoutSchema};")
.AppendLine($"{alterBase}DROP DEFAULT;")
.AppendLine($"{alterBase}ADD GENERATED {identityTypeClause} AS IDENTITY;")
.AppendLine($"SELECT * FROM setval('{sequence}', nextval('{oldSequence}'), false);")
// When generating idempotent scripts, migration DDL is enclosed in anonymous DO blocks,
// where PERFORM must be used instead of SELECT
.Append(Options.HasFlag(MigrationsSqlGenerationOptions.Idempotent) ? "PERFORM" : "SELECT")
.AppendLine($" * FROM setval('{sequence}', nextval('{oldSequence}'), false);")
.AppendLine($"DROP SEQUENCE {oldSequence};");
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Microsoft.Extensions.DependencyInjection;
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
Expand Down Expand Up @@ -425,6 +426,46 @@ public void CreateIndexOperation_collation()
");
}

[Theory]
[InlineData(MigrationsSqlGenerationOptions.Default)]
[InlineData(MigrationsSqlGenerationOptions.Idempotent)]
public void Alter_column_change_serial_to_identity_idempotent(MigrationsSqlGenerationOptions options)
{
Generate(
modelBuilder => modelBuilder.Entity<Person>().Property<int>("Id").UseSerialColumn(),
new[]
{
new AlterColumnOperation
{
Table = "Person",
Name = "Id",
ClrType = typeof(int),
[NpgsqlAnnotationNames.ValueGenerationStrategy] =
NpgsqlValueGenerationStrategy.IdentityByDefaultColumn,

OldColumn = new AddColumnOperation
{
Table = "Person",
Name = "Id",
ClrType = typeof(int),
[NpgsqlAnnotationNames.ValueGenerationStrategy] =
NpgsqlValueGenerationStrategy.SerialColumn,
}
}
},
options);

AssertSql(
$@"ALTER TABLE ""Person"" ALTER COLUMN ""Id"" TYPE integer;
ALTER TABLE ""Person"" ALTER COLUMN ""Id"" SET NOT NULL;
ALTER SEQUENCE ""Person_Id_seq"" RENAME TO ""Person_Id_old_seq"";
ALTER TABLE ""Person"" ALTER COLUMN ""Id"" DROP DEFAULT;
ALTER TABLE ""Person"" ALTER COLUMN ""Id"" ADD GENERATED BY DEFAULT AS IDENTITY;
{(options == MigrationsSqlGenerationOptions.Idempotent ? "PERFORM" : "SELECT")} * FROM setval('""Person_Id_seq""', nextval('""Person_Id_old_seq""'), false);
DROP SEQUENCE ""Person_Id_old_seq"";
");
}

#region CockroachDB interleave-in-parent

// Note that we don't run tests against actual CockroachDB instances, so these are unit tests asserting on SQL
Expand Down

0 comments on commit ab663ab

Please sign in to comment.