From f95084369d8b2ba237d59d92b880715216c51c49 Mon Sep 17 00:00:00 2001 From: Nomango Date: Fri, 30 Dec 2022 15:38:16 +0800 Subject: [PATCH 1/4] fix(migrator): Tag default:'null' always causes field migration #5953 --- migrator/migrator.go | 2 +- tests/migrate_test.go | 71 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/migrator/migrator.go b/migrator/migrator.go index eafe7bb29..f1340f9c2 100644 --- a/migrator/migrator.go +++ b/migrator/migrator.go @@ -487,7 +487,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 9df626fd2..33862ec33 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -1203,3 +1203,74 @@ func TestMigrateSameEmbeddedFieldName(t *testing.T) { _, err = findColumnType(&GameUser{}, "rate_ground_rb_ground_destory_count") AssertEqual(t, nil, err) } + +func TestMigrateDefaultNullString(t *testing.T) { + if DB.Dialector.Name() == "sqlite" || DB.Dialector.Name() == "sqlserver" { + // sqlite and sqlserver driver treats NULL and 'NULL' the same + t.Skip("skip sqlite and 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) + + if DB.Dialector.Name() == "postgres" { + // TODO postgres migrator.AlterColumn has a bug that it treats 'NULL' and NULL the same + // see https://github.com/go-gorm/postgres/blob/915abc3969652fd88d6f4133edaba9af2894e3b2/migrator.go#L329 + return + } + defVal, ok = columnType.DefaultValue() + AssertEqual(t, defVal, "") + AssertEqual(t, ok, false) +} From 2f714db29a6034dfa5d67cf61f74563cbc0ef6bc Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 1 Jan 2023 21:42:14 +0800 Subject: [PATCH 2/4] Update migrate_test.go --- tests/migrate_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/migrate_test.go b/tests/migrate_test.go index 33862ec33..fda949e8e 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -1265,11 +1265,6 @@ func TestMigrateDefaultNullString(t *testing.T) { columnType, err = findColumnType(tableName, "content") AssertEqual(t, err, nil) - if DB.Dialector.Name() == "postgres" { - // TODO postgres migrator.AlterColumn has a bug that it treats 'NULL' and NULL the same - // see https://github.com/go-gorm/postgres/blob/915abc3969652fd88d6f4133edaba9af2894e3b2/migrator.go#L329 - return - } defVal, ok = columnType.DefaultValue() AssertEqual(t, defVal, "") AssertEqual(t, ok, false) From bac0e43501132c484ff48027096b460fa46ae36e Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 1 Jan 2023 21:57:37 +0800 Subject: [PATCH 3/4] Update migrate_test.go --- tests/migrate_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/migrate_test.go b/tests/migrate_test.go index 0d7fa445d..7692f838c 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -1205,8 +1205,8 @@ func TestMigrateSameEmbeddedFieldName(t *testing.T) { } func TestMigrateDefaultNullString(t *testing.T) { - if DB.Dialector.Name() == "sqlite" || DB.Dialector.Name() == "sqlserver" { - // sqlite and sqlserver driver treats NULL and 'NULL' the same + if DB.Dialector.Name() == "sqlserver" { + // sqlserver driver treats NULL and 'NULL' the same t.Skip("skip sqlite and sqlserver") } From 6da192778c59bc5495af75a321677d5d5238df66 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Sun, 1 Jan 2023 22:09:25 +0800 Subject: [PATCH 4/4] Update migrate_test.go --- tests/migrate_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/migrate_test.go b/tests/migrate_test.go index 7692f838c..7560faca2 100644 --- a/tests/migrate_test.go +++ b/tests/migrate_test.go @@ -1207,7 +1207,7 @@ func TestMigrateSameEmbeddedFieldName(t *testing.T) { func TestMigrateDefaultNullString(t *testing.T) { if DB.Dialector.Name() == "sqlserver" { // sqlserver driver treats NULL and 'NULL' the same - t.Skip("skip sqlite and sqlserver") + t.Skip("skip sqlserver") } type NullModel struct {