From 16a272209adc54ef6623824dccde90b9f843a4d0 Mon Sep 17 00:00:00 2001 From: Haibo Date: Sun, 1 Jan 2023 22:14:28 +0800 Subject: [PATCH] fix(migrator): Tag default:'null' always causes field migration #5953 (#5954) * fix(migrator): Tag default:'null' always causes field migration #5953 * Update migrate_test.go * Update migrate_test.go * Update migrate_test.go Co-authored-by: Jinzhu --- migrator/migrator.go | 2 +- tests/migrate_test.go | 66 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/migrator/migrator.go b/migrator/migrator.go index ebd9bc12..90fbb461 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -493,7 +493,7 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy // check default value if !field.PrimaryKey { - currentDefaultNotNull := field.HasDefaultValue && !strings.EqualFold(field.DefaultValue, "NULL") + currentDefaultNotNull := field.HasDefaultValue && (field.DefaultValueInterface != nil || !strings.EqualFold(field.DefaultValue, "NULL")) dv, dvNotNull := columnType.DefaultValue() if dvNotNull && !currentDefaultNotNull { // defalut value -> null diff --git a/tests/migrate_test.go b/tests/migrate_test.go index d5d129a8..7560faca 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -1204,6 +1204,72 @@ func TestMigrateSameEmbeddedFieldName(t *testing.T) { AssertEqual(t, nil, err) } +func TestMigrateDefaultNullString(t *testing.T) { + if DB.Dialector.Name() == "sqlserver" { + // sqlserver driver treats NULL and 'NULL' the same + t.Skip("skip sqlserver") + } + + type NullModel struct { + ID uint + Content string `gorm:"default:null"` + } + + type NullStringModel struct { + ID uint + Content string `gorm:"default:'null'"` + } + + tableName := "null_string_model" + + DB.Migrator().DropTable(tableName) + + err := DB.Table(tableName).AutoMigrate(&NullModel{}) + AssertEqual(t, err, nil) + + // default null -> 'null' + err = DB.Table(tableName).AutoMigrate(&NullStringModel{}) + AssertEqual(t, err, nil) + + columnType, err := findColumnType(tableName, "content") + AssertEqual(t, err, nil) + + defVal, ok := columnType.DefaultValue() + AssertEqual(t, defVal, "null") + AssertEqual(t, ok, true) + + // default 'null' -> 'null' + session := DB.Session(&gorm.Session{Logger: Tracer{ + Logger: DB.Config.Logger, + Test: func(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { + sql, _ := fc() + if strings.HasPrefix(sql, "ALTER TABLE") { + t.Errorf("shouldn't execute: sql=%s", sql) + } + }, + }}) + err = session.Table(tableName).AutoMigrate(&NullStringModel{}) + AssertEqual(t, err, nil) + + columnType, err = findColumnType(tableName, "content") + AssertEqual(t, err, nil) + + defVal, ok = columnType.DefaultValue() + AssertEqual(t, defVal, "null") + AssertEqual(t, ok, true) + + // default 'null' -> null + err = DB.Table(tableName).AutoMigrate(&NullModel{}) + AssertEqual(t, err, nil) + + columnType, err = findColumnType(tableName, "content") + AssertEqual(t, err, nil) + + defVal, ok = columnType.DefaultValue() + AssertEqual(t, defVal, "") + AssertEqual(t, ok, false) +} + func TestMigrateIgnoreRelations(t *testing.T) { type RelationModel1 struct { ID uint