Skip to content

Commit

Permalink
fix : fail to alter existing boolean column from smallint with defaul…
Browse files Browse the repository at this point in the history
…t value to boolean in postgres (#180) (#181)

* fix : fail to alter column from smallint to boolean

* fix : fail to alter column from smallint to boolean

* fix : fail to alter column from string to boolean

* fix : fail to alter column from string to boolean if the value is "false" in string

* move using conversion expression to func

* move using expression to func

* fix : fail to alter existing boolean column from smallint with default value to boolean in postgres (#180)

* isUncastableDefaultValue

* ModifyColumn & DropDefaultValue

* ModifyColumn + DropDefaultValue > modifyColumn
  • Loading branch information
jeffry-luqman authored May 28, 2023
1 parent 38ebed0 commit 64c0de1
Showing 1 changed file with 19 additions and 7 deletions.
26 changes: 19 additions & 7 deletions migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,7 @@ func (m Migrator) AlterColumn(value interface{}, field string) error {
return err
}
} else {
if err := m.DB.Exec("ALTER TABLE ? ALTER COLUMN ? TYPE ?"+m.genUsingExpression(fileType.SQL, fieldColumnType.DatabaseTypeName()),
m.CurrentTable(stmt), clause.Column{Name: field.DBName}, fileType, clause.Column{Name: field.DBName}, fileType).Error; err != nil {
if err := m.modifyColumn(stmt, field, fileType, fieldColumnType); err != nil {
return err
}
}
Expand Down Expand Up @@ -387,14 +386,27 @@ func (m Migrator) AlterColumn(value interface{}, field string) error {
return nil
}

func (m Migrator) genUsingExpression(targetType, sourceType string) string {
if targetType == "boolean" {
switch sourceType {
func (m Migrator) modifyColumn(stmt *gorm.Statement, field *schema.Field, targetType clause.Expr, existingColumn *migrator.ColumnType) error {
alterSQL := "ALTER TABLE ? ALTER COLUMN ? TYPE ? USING ?::?"
isUncastableDefaultValue := false

if targetType.SQL == "boolean" {
switch existingColumn.DatabaseTypeName() {
case "int2", "int8", "numeric":
return " USING ?::INT::?"
alterSQL = "ALTER TABLE ? ALTER COLUMN ? TYPE ? USING ?::int::?"
}
isUncastableDefaultValue = true
}

if dv, _ := existingColumn.DefaultValue(); dv != "" && isUncastableDefaultValue {
if err := m.DB.Exec("ALTER TABLE ? ALTER COLUMN ? DROP DEFAULT", m.CurrentTable(stmt), clause.Column{Name: field.DBName}).Error; err != nil {
return err
}
}
return " USING ?::?"
if err := m.DB.Exec(alterSQL, m.CurrentTable(stmt), clause.Column{Name: field.DBName}, targetType, clause.Column{Name: field.DBName}, targetType).Error; err != nil {
return err
}
return nil
}

func (m Migrator) HasConstraint(value interface{}, name string) bool {
Expand Down

0 comments on commit 64c0de1

Please sign in to comment.