fix: migrate column default value (#5359)
Co-authored-by: Jinzhu <wosmvp@gmail.com>
This commit is contained in:
parent
dc1ae394f3
commit
93986de8e4
@ -448,10 +448,20 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check default value
|
// check default value
|
||||||
if v, ok := columnType.DefaultValue(); ok && v != field.DefaultValue {
|
if !field.PrimaryKey {
|
||||||
// not primary key
|
dv, dvNotNull := columnType.DefaultValue()
|
||||||
if !field.PrimaryKey {
|
if dvNotNull && field.DefaultValueInterface == nil {
|
||||||
|
// defalut value -> null
|
||||||
alterColumn = true
|
alterColumn = true
|
||||||
|
} else if !dvNotNull && field.DefaultValueInterface != nil {
|
||||||
|
// null -> default value
|
||||||
|
alterColumn = true
|
||||||
|
} else if dv != field.DefaultValue {
|
||||||
|
// default value not equal
|
||||||
|
// not both null
|
||||||
|
if !(field.DefaultValueInterface == nil && !dvNotNull) {
|
||||||
|
alterColumn = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package tests_test
|
package tests_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
@ -714,6 +715,141 @@ func TestPrimarykeyID(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUniqueColumn(t *testing.T) {
|
||||||
|
if DB.Dialector.Name() != "mysql" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type UniqueTest struct {
|
||||||
|
ID string `gorm:"primary_key"`
|
||||||
|
Name string `gorm:"unique"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UniqueTest2 struct {
|
||||||
|
ID string `gorm:"primary_key"`
|
||||||
|
Name string `gorm:"unique;default:NULL"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UniqueTest3 struct {
|
||||||
|
ID string `gorm:"primary_key"`
|
||||||
|
Name string `gorm:"unique;default:''"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UniqueTest4 struct {
|
||||||
|
ID string `gorm:"primary_key"`
|
||||||
|
Name string `gorm:"unique;default:'123'"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
err = DB.Migrator().DropTable(&UniqueTest{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("DropTable err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = DB.AutoMigrate(&UniqueTest{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// null -> null
|
||||||
|
err = DB.AutoMigrate(&UniqueTest{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ct, err := findColumnType(&UniqueTest{}, "name")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("findColumnType err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok := ct.DefaultValue()
|
||||||
|
AssertEqual(t, "", value)
|
||||||
|
AssertEqual(t, false, ok)
|
||||||
|
|
||||||
|
// null -> null
|
||||||
|
err = DB.Table("unique_tests").AutoMigrate(&UniqueTest2{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// not trigger alert column
|
||||||
|
AssertEqual(t, true, DB.Migrator().HasIndex(&UniqueTest{}, "name"))
|
||||||
|
AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name_1"))
|
||||||
|
AssertEqual(t, false, DB.Migrator().HasIndex(&UniqueTest{}, "name_2"))
|
||||||
|
|
||||||
|
ct, err = findColumnType(&UniqueTest{}, "name")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("findColumnType err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok = ct.DefaultValue()
|
||||||
|
AssertEqual(t, "", value)
|
||||||
|
AssertEqual(t, false, ok)
|
||||||
|
|
||||||
|
// null -> empty string
|
||||||
|
err = DB.Table("unique_tests").AutoMigrate(&UniqueTest3{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ct, err = findColumnType(&UniqueTest{}, "name")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("findColumnType err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok = ct.DefaultValue()
|
||||||
|
AssertEqual(t, "", value)
|
||||||
|
AssertEqual(t, true, ok)
|
||||||
|
|
||||||
|
// empty string -> 123
|
||||||
|
err = DB.Table("unique_tests").AutoMigrate(&UniqueTest4{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ct, err = findColumnType(&UniqueTest{}, "name")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("findColumnType err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok = ct.DefaultValue()
|
||||||
|
AssertEqual(t, "123", value)
|
||||||
|
AssertEqual(t, true, ok)
|
||||||
|
|
||||||
|
// 123 -> null
|
||||||
|
err = DB.Table("unique_tests").AutoMigrate(&UniqueTest2{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("AutoMigrate err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ct, err = findColumnType(&UniqueTest{}, "name")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("findColumnType err:%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
value, ok = ct.DefaultValue()
|
||||||
|
AssertEqual(t, "", value)
|
||||||
|
AssertEqual(t, false, ok)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func findColumnType(dest interface{}, columnName string) (
|
||||||
|
foundColumn gorm.ColumnType, err error) {
|
||||||
|
columnTypes, err := DB.Migrator().ColumnTypes(dest)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("ColumnTypes err:%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range columnTypes {
|
||||||
|
if c.Name() == columnName {
|
||||||
|
foundColumn = c
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func TestInvalidCachedPlan(t *testing.T) {
|
func TestInvalidCachedPlan(t *testing.T) {
|
||||||
if DB.Dialector.Name() != "postgres" {
|
if DB.Dialector.Name() != "postgres" {
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user