Skip to content

Commit f49a090

Browse files
authored
Merge pull request #38 from oracle-samples/migrate_nullable_fix
Migrate nullable fix
2 parents ede94ac + 90353cb commit f49a090

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

oracle/migrator.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,15 +308,47 @@ func (m Migrator) DropColumn(value interface{}, name string) error {
308308
func (m Migrator) AlterColumn(value interface{}, field string) error {
309309
return m.RunWithValue(value, func(stmt *gorm.Statement) error {
310310
if stmt.Schema != nil {
311-
if field := stmt.Schema.LookUpField(field); field != nil {
312-
fileType := m.FullDataTypeOf(field)
311+
if f := stmt.Schema.LookUpField(field); f != nil {
312+
columnTypes, err := m.ColumnTypes(value)
313+
if err != nil {
314+
return err
315+
}
316+
317+
var currentNullable bool
318+
var currentType string
319+
for _, col := range columnTypes {
320+
if strings.EqualFold(col.Name(), f.DBName) {
321+
currentNullable, _ = col.Nullable()
322+
currentType = strings.ToUpper(col.DatabaseTypeName())
323+
break
324+
}
325+
}
326+
327+
desiredNullable := !f.NotNull
328+
desiredType := strings.ToUpper(m.DataTypeOf(f))
329+
330+
// nullable → non-nullable → skip
331+
if currentNullable && !desiredNullable {
332+
return nil
333+
}
334+
335+
// same type + same nullability → skip
336+
if currentNullable == desiredNullable && strings.Contains(currentType, desiredType) {
337+
return nil
338+
}
339+
340+
sql := "ALTER TABLE ? MODIFY ? " + m.DataTypeOf(f)
341+
if f.NotNull {
342+
sql += " NOT NULL"
343+
} else if !currentNullable && desiredNullable {
344+
sql += " NULL"
345+
}
346+
313347
return m.DB.Exec(
314-
"ALTER TABLE ? MODIFY ? ?",
348+
sql,
315349
clause.Table{Name: stmt.Schema.Table},
316-
clause.Column{Name: field.DBName},
317-
fileType,
350+
clause.Column{Name: f.DBName},
318351
).Error
319-
320352
}
321353
}
322354
return fmt.Errorf("failed to look up field with name: %s", field)

tests/migrate_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,6 @@ func TestAutoMigrateSelfReferential(t *testing.T) {
186186
}
187187

188188
func TestAutoMigrateNullable(t *testing.T) {
189-
t.Skip()
190189
type MigrateNullableColumn struct {
191190
ID uint
192191
Bonus float64 `gorm:"not null"`
@@ -1397,7 +1396,7 @@ func TestMigrateExistingBoolColumnPG(t *testing.T) {
13971396

13981397
func TestMigrateWithUniqueIndexAndUnique(t *testing.T) {
13991398
t.Skip()
1400-
1399+
14011400
const table = "unique_struct"
14021401

14031402
checkField := func(model interface{}, fieldName string, unique bool, uniqueIndex string) {

tests/query_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -725,7 +725,7 @@ func (v *Int64) Scan(val interface{}) error {
725725
switch x := val.(type) {
726726
case int64:
727727
*v = Int64(x + 1)
728-
return nil
728+
return nil
729729
case godror.Number:
730730
i, err := strconv.ParseInt(string(x), 10, 64)
731731
if err != nil {

0 commit comments

Comments
 (0)