Skip to content

Commit 23db204

Browse files
authored
Don't generate DEFAULT 0 clause for AUTO_INCREMENT columns. (#1980)
1 parent b61cbbd commit 23db204

File tree

2 files changed

+219
-3
lines changed

2 files changed

+219
-3
lines changed

src/EFCore.MySql/Migrations/MySqlMigrationsSqlGenerator.cs

+14-3
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,8 @@ protected override void ColumnDefinition(
11911191

11921192
if (operation.ComputedColumnSql == null)
11931193
{
1194-
ColumnDefinitionWithCharSet(schema, table, name, operation, model, builder);
1194+
// AUTO_INCREMENT columns don't support DEFAULT values.
1195+
ColumnDefinitionWithCharSet(schema, table, name, operation, model, builder, withDefaultValue: !autoIncrement);
11951196

11961197
GenerateComment(operation.Comment, builder);
11971198

@@ -1305,7 +1306,14 @@ private void GenerateComment(string comment, MigrationCommandListBuilder builder
13051306
.Append(MySqlStringTypeMapping.EscapeSqlLiteralWithLineBreaks(comment, !_options.NoBackslashEscapes, false));
13061307
}
13071308

1308-
private void ColumnDefinitionWithCharSet(string schema, string table, string name, ColumnOperation operation, IModel model, MigrationCommandListBuilder builder)
1309+
private void ColumnDefinitionWithCharSet(
1310+
string schema,
1311+
string table,
1312+
string name,
1313+
ColumnOperation operation,
1314+
IModel model,
1315+
MigrationCommandListBuilder builder,
1316+
bool withDefaultValue)
13091317
{
13101318
if (operation.ComputedColumnSql != null)
13111319
{
@@ -1322,7 +1330,10 @@ private void ColumnDefinitionWithCharSet(string schema, string table, string nam
13221330

13231331
builder.Append(operation.IsNullable ? " NULL" : " NOT NULL");
13241332

1325-
DefaultValue(operation.DefaultValue, operation.DefaultValueSql, columnType, builder);
1333+
if (withDefaultValue)
1334+
{
1335+
DefaultValue(operation.DefaultValue, operation.DefaultValueSql, columnType, builder);
1336+
}
13261337

13271338
var srid = operation[MySqlAnnotationNames.SpatialReferenceSystemId];
13281339
if (srid is int &&

test/EFCore.MySql.FunctionalTests/FullMigrationsMySqlTest.cs

+205
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Text.RegularExpressions;
44
using Microsoft.EntityFrameworkCore;
55
using Microsoft.EntityFrameworkCore.Infrastructure;
6+
using Microsoft.EntityFrameworkCore.Metadata;
67
using Microsoft.EntityFrameworkCore.Migrations;
78
using Microsoft.EntityFrameworkCore.TestUtilities;
89
using Microsoft.Extensions.DependencyInjection;
@@ -362,6 +363,133 @@ IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '00000
362363
DROP PROCEDURE `POMELO_AFTER_ADD_PRIMARY_KEY`;
363364
364365
366+
""",
367+
Sql,
368+
ignoreLineEndingDifferences: true);
369+
}
370+
371+
[ConditionalFact]
372+
public virtual void Alter_column_change_primary_key_will_not_try_to_declare_default_value_in_sql()
373+
{
374+
using var db = Fixture.CreateContext<FullInfrastructureMigrationsFixture.MigrationPrimaryKeyChangeFromStringToIntContext>(
375+
new ServiceCollection()
376+
.AddScoped<IMigrator, MySqlTestMigrator>());
377+
378+
db.Database.EnsureDeleted();
379+
db.Database.EnsureCreated();
380+
381+
var migrator = (MySqlTestMigrator)db.GetService<IMigrator>();
382+
migrator.MigrationsSqlGenerationOptionsOverrider = options => options & ~MigrationsSqlGenerationOptions.Script;
383+
384+
SetSql(migrator.GenerateScript());
385+
386+
Assert.False(Sql.Contains("DEFAULT 0"));
387+
Assert.Equal(
388+
"""
389+
CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` (
390+
`MigrationId` varchar(150) CHARACTER SET utf8mb4 NOT NULL,
391+
`ProductVersion` varchar(32) CHARACTER SET utf8mb4 NOT NULL,
392+
CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`)
393+
) CHARACTER SET=utf8mb4;
394+
395+
START TRANSACTION;
396+
CREATE TABLE `IceCreams` (
397+
`Name` varchar(32) NOT NULL,
398+
CONSTRAINT `PK_IceCreams` PRIMARY KEY (`Name`)
399+
);
400+
401+
INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`)
402+
VALUES ('00000000000001_Migration1', '7.0.0-test');
403+
404+
DROP PROCEDURE IF EXISTS `POMELO_BEFORE_DROP_PRIMARY_KEY`;
405+
CREATE PROCEDURE `POMELO_BEFORE_DROP_PRIMARY_KEY`(IN `SCHEMA_NAME_ARGUMENT` VARCHAR(255), IN `TABLE_NAME_ARGUMENT` VARCHAR(255))
406+
BEGIN
407+
DECLARE HAS_AUTO_INCREMENT_ID TINYINT(1);
408+
DECLARE PRIMARY_KEY_COLUMN_NAME VARCHAR(255);
409+
DECLARE PRIMARY_KEY_TYPE VARCHAR(255);
410+
DECLARE SQL_EXP VARCHAR(1000);
411+
SELECT COUNT(*)
412+
INTO HAS_AUTO_INCREMENT_ID
413+
FROM `information_schema`.`COLUMNS`
414+
WHERE `TABLE_SCHEMA` = (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA()))
415+
AND `TABLE_NAME` = TABLE_NAME_ARGUMENT
416+
AND `Extra` = 'auto_increment'
417+
AND `COLUMN_KEY` = 'PRI'
418+
LIMIT 1;
419+
IF HAS_AUTO_INCREMENT_ID THEN
420+
SELECT `COLUMN_TYPE`
421+
INTO PRIMARY_KEY_TYPE
422+
FROM `information_schema`.`COLUMNS`
423+
WHERE `TABLE_SCHEMA` = (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA()))
424+
AND `TABLE_NAME` = TABLE_NAME_ARGUMENT
425+
AND `COLUMN_KEY` = 'PRI'
426+
LIMIT 1;
427+
SELECT `COLUMN_NAME`
428+
INTO PRIMARY_KEY_COLUMN_NAME
429+
FROM `information_schema`.`COLUMNS`
430+
WHERE `TABLE_SCHEMA` = (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA()))
431+
AND `TABLE_NAME` = TABLE_NAME_ARGUMENT
432+
AND `COLUMN_KEY` = 'PRI'
433+
LIMIT 1;
434+
SET SQL_EXP = CONCAT('ALTER TABLE `', (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA())), '`.`', TABLE_NAME_ARGUMENT, '` MODIFY COLUMN `', PRIMARY_KEY_COLUMN_NAME, '` ', PRIMARY_KEY_TYPE, ' NOT NULL;');
435+
SET @SQL_EXP = SQL_EXP;
436+
PREPARE SQL_EXP_EXECUTE FROM @SQL_EXP;
437+
EXECUTE SQL_EXP_EXECUTE;
438+
DEALLOCATE PREPARE SQL_EXP_EXECUTE;
439+
END IF;
440+
END;
441+
DROP PROCEDURE IF EXISTS `POMELO_AFTER_ADD_PRIMARY_KEY`;
442+
CREATE PROCEDURE `POMELO_AFTER_ADD_PRIMARY_KEY`(IN `SCHEMA_NAME_ARGUMENT` VARCHAR(255), IN `TABLE_NAME_ARGUMENT` VARCHAR(255), IN `COLUMN_NAME_ARGUMENT` VARCHAR(255))
443+
BEGIN
444+
DECLARE HAS_AUTO_INCREMENT_ID INT(11);
445+
DECLARE PRIMARY_KEY_COLUMN_NAME VARCHAR(255);
446+
DECLARE PRIMARY_KEY_TYPE VARCHAR(255);
447+
DECLARE SQL_EXP VARCHAR(1000);
448+
SELECT COUNT(*)
449+
INTO HAS_AUTO_INCREMENT_ID
450+
FROM `information_schema`.`COLUMNS`
451+
WHERE `TABLE_SCHEMA` = (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA()))
452+
AND `TABLE_NAME` = TABLE_NAME_ARGUMENT
453+
AND `COLUMN_NAME` = COLUMN_NAME_ARGUMENT
454+
AND `COLUMN_TYPE` LIKE '%int%'
455+
AND `COLUMN_KEY` = 'PRI';
456+
IF HAS_AUTO_INCREMENT_ID THEN
457+
SELECT `COLUMN_TYPE`
458+
INTO PRIMARY_KEY_TYPE
459+
FROM `information_schema`.`COLUMNS`
460+
WHERE `TABLE_SCHEMA` = (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA()))
461+
AND `TABLE_NAME` = TABLE_NAME_ARGUMENT
462+
AND `COLUMN_NAME` = COLUMN_NAME_ARGUMENT
463+
AND `COLUMN_TYPE` LIKE '%int%'
464+
AND `COLUMN_KEY` = 'PRI';
465+
SELECT `COLUMN_NAME`
466+
INTO PRIMARY_KEY_COLUMN_NAME
467+
FROM `information_schema`.`COLUMNS`
468+
WHERE `TABLE_SCHEMA` = (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA()))
469+
AND `TABLE_NAME` = TABLE_NAME_ARGUMENT
470+
AND `COLUMN_NAME` = COLUMN_NAME_ARGUMENT
471+
AND `COLUMN_TYPE` LIKE '%int%'
472+
AND `COLUMN_KEY` = 'PRI';
473+
SET SQL_EXP = CONCAT('ALTER TABLE `', (SELECT IFNULL(SCHEMA_NAME_ARGUMENT, SCHEMA())), '`.`', TABLE_NAME_ARGUMENT, '` MODIFY COLUMN `', PRIMARY_KEY_COLUMN_NAME, '` ', PRIMARY_KEY_TYPE, ' NOT NULL AUTO_INCREMENT;');
474+
SET @SQL_EXP = SQL_EXP;
475+
PREPARE SQL_EXP_EXECUTE FROM @SQL_EXP;
476+
EXECUTE SQL_EXP_EXECUTE;
477+
DEALLOCATE PREPARE SQL_EXP_EXECUTE;
478+
END IF;
479+
END;
480+
CALL POMELO_BEFORE_DROP_PRIMARY_KEY(NULL, 'IceCreams');
481+
ALTER TABLE `IceCreams` DROP PRIMARY KEY;
482+
483+
ALTER TABLE `IceCreams` ADD `IceCreamId` int NOT NULL AUTO_INCREMENT;
484+
485+
INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`)
486+
VALUES ('00000000000002_Migration2', '7.0.0-test');
487+
488+
DROP PROCEDURE `POMELO_BEFORE_DROP_PRIMARY_KEY`;
489+
DROP PROCEDURE `POMELO_AFTER_ADD_PRIMARY_KEY`;
490+
COMMIT;
491+
492+
365493
""",
366494
Sql,
367495
ignoreLineEndingDifferences: true);
@@ -649,6 +777,83 @@ protected override void Down(MigrationBuilder migrationBuilder)
649777

650778
#endregion MigrationPrimaryKeyChange
651779

780+
public class MigrationPrimaryKeyChangeFromStringToIntContext : DbContext
781+
{
782+
public MigrationPrimaryKeyChangeFromStringToIntContext(DbContextOptions options)
783+
: base(options)
784+
{
785+
}
786+
787+
public static class Migrations
788+
{
789+
[DbContext(typeof(MigrationPrimaryKeyChangeFromStringToIntContext))]
790+
[Migration("00000000000001_Migration1")]
791+
private class Migration1 : Migration
792+
{
793+
protected override void Up(MigrationBuilder migrationBuilder)
794+
{
795+
MigrationsInfrastructureFixtureBase.ActiveProvider = migrationBuilder.ActiveProvider;
796+
797+
migrationBuilder
798+
.CreateTable(
799+
name: "IceCreams",
800+
columns: table => new
801+
{
802+
Name = table.Column<string>(type: "varchar(32)", maxLength: 32, nullable: false)
803+
},
804+
constraints: table =>
805+
{
806+
table.PrimaryKey("PK_IceCreams", x => x.Name);
807+
});
808+
}
809+
810+
protected override void Down(MigrationBuilder migrationBuilder)
811+
=> migrationBuilder.DropTable("IceCreams");
812+
}
813+
814+
[DbContext(typeof(MigrationPrimaryKeyChangeFromStringToIntContext))]
815+
[Migration("00000000000002_Migration2")]
816+
private class Migration2 : Migration
817+
{
818+
protected override void Up(MigrationBuilder migrationBuilder)
819+
{
820+
migrationBuilder.DropPrimaryKey(
821+
name: "PK_IceCreams",
822+
table: "IceCreams");
823+
824+
migrationBuilder.AddColumn<int>(
825+
name: "IceCreamId",
826+
table: "IceCreams",
827+
type: "int",
828+
nullable: false,
829+
defaultValue: 0)
830+
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn);
831+
832+
migrationBuilder.AddPrimaryKey(
833+
name: "PK_IceCreams",
834+
table: "IceCreams",
835+
column: "IceCreamId");
836+
}
837+
838+
protected override void Down(MigrationBuilder migrationBuilder)
839+
{
840+
migrationBuilder.DropPrimaryKey(
841+
name: "PK_IceCreams",
842+
table: "IceCreams");
843+
844+
migrationBuilder.DropColumn(
845+
name: "IceCreamId",
846+
table: "IceCreams");
847+
848+
migrationBuilder.AddPrimaryKey(
849+
name: "PK_IceCreams",
850+
table: "IceCreams",
851+
column: "Name");
852+
}
853+
}
854+
}
855+
}
856+
652857
#region MigrationDropPrimaryKeyWithRecreatingForeignKeys
653858

654859
public class MigrationDropPrimaryKeyWithRecreatingForeignKeysContext : PoolableDbContext

0 commit comments

Comments
 (0)