Skip to content

Commit

Permalink
fix(MigrateColumn):declared different type without length (#5465)
Browse files Browse the repository at this point in the history
  • Loading branch information
a631807682 committed Jun 29, 2022
1 parent 3e6ab99 commit 235c093
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 4 deletions.
11 changes: 7 additions & 4 deletions migrator/migrator.go
Expand Up @@ -15,7 +15,6 @@ import (
)

var (
regRealDataType = regexp.MustCompile(`[^\d](\d+)[^\d]?`)
regFullDataType = regexp.MustCompile(`[^\d]*(\d+)[^\d]?`)
)

Expand Down Expand Up @@ -404,21 +403,25 @@ func (m Migrator) RenameColumn(value interface{}, oldName, newName string) error
// MigrateColumn migrate column
func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnType gorm.ColumnType) error {
// found, smart migrate
fullDataType := strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL)
fullDataType := strings.TrimSpace(strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL))
realDataType := strings.ToLower(columnType.DatabaseTypeName())

alterColumn := false

// check type
if !field.PrimaryKey && !strings.HasPrefix(fullDataType, realDataType) {
alterColumn = true
}

// check size
if length, ok := columnType.Length(); length != int64(field.Size) {
if length > 0 && field.Size > 0 {
alterColumn = true
} else {
// has size in data type and not equal
// Since the following code is frequently called in the for loop, reg optimization is needed here
matches := regRealDataType.FindAllStringSubmatch(realDataType, -1)
matches2 := regFullDataType.FindAllStringSubmatch(fullDataType, -1)
if (len(matches) == 1 && matches[0][1] != fmt.Sprint(field.Size) || !field.PrimaryKey) &&
if !field.PrimaryKey &&
(len(matches2) == 1 && matches2[0][1] != fmt.Sprint(length) && ok) {
alterColumn = true
}
Expand Down
39 changes: 39 additions & 0 deletions tests/migrate_test.go
Expand Up @@ -884,3 +884,42 @@ func TestInvalidCachedPlan(t *testing.T) {
t.Errorf("AutoMigrate err:%v", err)
}
}

func TestDifferentTypeWithoutDeclaredLength(t *testing.T) {
type DiffType struct {
ID uint
Name string `gorm:"type:varchar(20)"`
}

type DiffType1 struct {
ID uint
Name string `gorm:"type:text"`
}

var err error
DB.Migrator().DropTable(&DiffType{})

err = DB.AutoMigrate(&DiffType{})
if err != nil {
t.Errorf("AutoMigrate err:%v", err)
}

ct, err := findColumnType(&DiffType{}, "name")
if err != nil {
t.Errorf("findColumnType err:%v", err)
}

AssertEqual(t, "varchar", strings.ToLower(ct.DatabaseTypeName()))

err = DB.Table("diff_types").AutoMigrate(&DiffType1{})
if err != nil {
t.Errorf("AutoMigrate err:%v", err)
}

ct, err = findColumnType(&DiffType{}, "name")
if err != nil {
t.Errorf("findColumnType err:%v", err)
}

AssertEqual(t, "text", strings.ToLower(ct.DatabaseTypeName()))
}

0 comments on commit 235c093

Please sign in to comment.