add test: TestAutoMigrateInt8PG: shouldn't execute ALTER COLUMN TYPE smallint, close #5762
This commit is contained in:
		
							parent
							
								
									a0f4d3f7d2
								
							
						
					
					
						commit
						62593cfad0
					
				| @ -406,17 +406,14 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy | |||||||
| 	fullDataType := strings.TrimSpace(strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL)) | 	fullDataType := strings.TrimSpace(strings.ToLower(m.DB.Migrator().FullDataTypeOf(field).SQL)) | ||||||
| 	realDataType := strings.ToLower(columnType.DatabaseTypeName()) | 	realDataType := strings.ToLower(columnType.DatabaseTypeName()) | ||||||
| 
 | 
 | ||||||
| 	alterColumn := false | 	var ( | ||||||
|  | 		alterColumn, isSameType bool | ||||||
|  | 	) | ||||||
| 
 | 
 | ||||||
| 	if !field.PrimaryKey { | 	if !field.PrimaryKey { | ||||||
| 		// check type
 | 		// check type
 | ||||||
| 		var isSameType bool | 		if !strings.HasPrefix(fullDataType, realDataType) { | ||||||
| 		if strings.HasPrefix(fullDataType, realDataType) { |  | ||||||
| 			isSameType = true |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 			// check type aliases
 | 			// check type aliases
 | ||||||
| 		if !isSameType { |  | ||||||
| 			aliases := m.DB.Migrator().GetTypeAliases(realDataType) | 			aliases := m.DB.Migrator().GetTypeAliases(realDataType) | ||||||
| 			for _, alias := range aliases { | 			for _, alias := range aliases { | ||||||
| 				if strings.HasPrefix(fullDataType, alias) { | 				if strings.HasPrefix(fullDataType, alias) { | ||||||
| @ -424,13 +421,14 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy | |||||||
| 					break | 					break | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 			if !isSameType { | 			if !isSameType { | ||||||
| 				alterColumn = true | 				alterColumn = true | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if !isSameType { | ||||||
| 		// check size
 | 		// check size
 | ||||||
| 		if length, ok := columnType.Length(); length != int64(field.Size) { | 		if length, ok := columnType.Length(); length != int64(field.Size) { | ||||||
| 			if length > 0 && field.Size > 0 { | 			if length > 0 && field.Size > 0 { | ||||||
| @ -452,6 +450,7 @@ func (m Migrator) MigrateColumn(value interface{}, field *schema.Field, columnTy | |||||||
| 				alterColumn = true | 				alterColumn = true | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	// check nullable
 | 	// check nullable
 | ||||||
| 	if nullable, ok := columnType.Nullable(); ok && nullable == field.NotNull { | 	if nullable, ok := columnType.Nullable(); ok && nullable == field.NotNull { | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| package tests_test | package tests_test | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/rand" | 	"math/rand" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| @ -9,6 +10,7 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"gorm.io/driver/postgres" | 	"gorm.io/driver/postgres" | ||||||
|  | 
 | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
| 	"gorm.io/gorm/schema" | 	"gorm.io/gorm/schema" | ||||||
| 	. "gorm.io/gorm/utils/tests" | 	. "gorm.io/gorm/utils/tests" | ||||||
| @ -72,6 +74,44 @@ func TestMigrate(t *testing.T) { | |||||||
| 			t.Fatalf("Failed to find index for many2many for %v %v", indexes[0], indexes[1]) | 			t.Fatalf("Failed to find index for many2many for %v %v", indexes[0], indexes[1]) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestAutoMigrateInt8PG(t *testing.T) { | ||||||
|  | 	if DB.Dialector.Name() != "postgres" { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	type Smallint int8 | ||||||
|  | 
 | ||||||
|  | 	type MigrateInt struct { | ||||||
|  | 		Int8 Smallint | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tracer := 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 \"migrate_ints\" ALTER COLUMN \"int8\" TYPE smallint") { | ||||||
|  | 				t.Fatalf("shouldn't execute ALTER COLUMN TYPE if such type is already existed in DB schema: sql: %s", sql) | ||||||
|  | 			} | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	DB.Migrator().DropTable(&MigrateInt{}) | ||||||
|  | 
 | ||||||
|  | 	// The first AutoMigrate to make table with field with correct type
 | ||||||
|  | 	if err := DB.AutoMigrate(&MigrateInt{}); err != nil { | ||||||
|  | 		t.Fatalf("Failed to auto migrate: error: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// make new session to set custom logger tracer
 | ||||||
|  | 	session := DB.Session(&gorm.Session{Logger: tracer}) | ||||||
|  | 
 | ||||||
|  | 	// The second AutoMigrate to catch an error
 | ||||||
|  | 	if err := session.AutoMigrate(&MigrateInt{}); err != nil { | ||||||
|  | 		t.Fatalf("Failed to auto migrate: error: %v", err) | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestAutoMigrateSelfReferential(t *testing.T) { | func TestAutoMigrateSelfReferential(t *testing.T) { | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								tests/tracer_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tests/tracer_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | package tests_test | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"gorm.io/gorm/logger" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Tracer struct { | ||||||
|  | 	Logger logger.Interface | ||||||
|  | 	Test   func(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (S Tracer) LogMode(level logger.LogLevel) logger.Interface { | ||||||
|  | 	return S.Logger.LogMode(level) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (S Tracer) Info(ctx context.Context, s string, i ...interface{}) { | ||||||
|  | 	S.Logger.Info(ctx, s, i...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (S Tracer) Warn(ctx context.Context, s string, i ...interface{}) { | ||||||
|  | 	S.Logger.Warn(ctx, s, i...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (S Tracer) Error(ctx context.Context, s string, i ...interface{}) { | ||||||
|  | 	S.Logger.Error(ctx, s, i...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (S Tracer) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) { | ||||||
|  | 	S.Logger.Trace(ctx, begin, fc, err) | ||||||
|  | 	S.Test(ctx, begin, fc, err) | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 viatoriche / Maxim Panfilov
						viatoriche / Maxim Panfilov