forked from mirror/gorm
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) {
|
||||||
|
|
|
@ -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…
Reference in New Issue