@@ -1987,3 +1987,112 @@ func TestMigrateWithUniqueIndexAndUnique(t *testing.T) {
1987
1987
}
1988
1988
}
1989
1989
}
1990
+
1991
+ func testAutoMigrateDecimal (t * testing.T , model1 , model2 any ) []string {
1992
+ tracer := Tracer {
1993
+ Logger : DB .Config .Logger ,
1994
+ Test : func (ctx context.Context , begin time.Time , fc func () (sql string , rowsAffected int64 ), err error ) {
1995
+ sql , _ := fc ()
1996
+ if strings .HasPrefix (sql , "ALTER TABLE " ) {
1997
+ t .Fatalf ("shouldn't execute ALTER COLUMN TYPE if decimal is not change: sql: %s" , sql )
1998
+ }
1999
+ },
2000
+ }
2001
+ session := DB .Session (& gorm.Session {Logger : tracer })
2002
+
2003
+ DB .Migrator ().DropTable (model1 )
2004
+ var modifySql []string
2005
+ if err := session .AutoMigrate (model1 ); err != nil {
2006
+ t .Fatalf ("failed to auto migrate, got error: %v" , err )
2007
+ }
2008
+ if err := session .AutoMigrate (model1 ); err != nil {
2009
+ t .Fatalf ("failed to auto migrate, got error: %v" , err )
2010
+ }
2011
+ tracer2 := Tracer {
2012
+ Logger : DB .Config .Logger ,
2013
+ Test : func (ctx context.Context , begin time.Time , fc func () (sql string , rowsAffected int64 ), err error ) {
2014
+ sql , _ := fc ()
2015
+ modifySql = append (modifySql , sql )
2016
+ },
2017
+ }
2018
+ session2 := DB .Session (& gorm.Session {Logger : tracer2 })
2019
+ err := session2 .Table ("migrate_decimal_columns" ).Migrator ().AutoMigrate (model2 )
2020
+ if err != nil {
2021
+ t .Fatalf ("failed to get column types, got error: %v" , err )
2022
+ }
2023
+ return modifySql
2024
+ }
2025
+ func decimalColumnsTest [T , T2 any ](t * testing.T , expectedSql []string ) {
2026
+ var t1 T
2027
+ var t2 T2
2028
+ modSql := testAutoMigrateDecimal (t , t1 , t2 )
2029
+ var alterSQL []string
2030
+ for _ , sql := range modSql {
2031
+ if strings .HasPrefix (sql , "ALTER TABLE " ) {
2032
+ alterSQL = append (alterSQL , sql )
2033
+ }
2034
+ }
2035
+
2036
+ if len (alterSQL ) != 3 {
2037
+ t .Fatalf ("decimal changed error,expected: %+v,got: %+v." , expectedSql , alterSQL )
2038
+ }
2039
+ for i := range alterSQL {
2040
+ if alterSQL [i ] != expectedSql [i ] {
2041
+ t .Fatalf ("decimal changed error,expected: %+v,got: %+v." , expectedSql , alterSQL )
2042
+ }
2043
+ }
2044
+ }
2045
+ func TestAutoMigrateDecimal (t * testing.T ) {
2046
+ if DB .Dialector .Name () == "sqlserver" { // database/sql will replace numeric to decimal. so only support decimal.
2047
+ type MigrateDecimalColumn struct {
2048
+ RecID1 int64 `gorm:"column:recid1;type:decimal(9,0);not null" json:"recid1"`
2049
+ RecID2 int64 `gorm:"column:recid2;type:decimal(8);not null" json:"recid2"`
2050
+ RecID3 int64 `gorm:"column:recid3;type:decimal(8,1);not null" json:"recid3"`
2051
+ }
2052
+ type MigrateDecimalColumn2 struct {
2053
+ RecID1 int64 `gorm:"column:recid1;type:decimal(8);not null" json:"recid1"`
2054
+ RecID2 int64 `gorm:"column:recid2;type:decimal(9,1);not null" json:"recid2"`
2055
+ RecID3 int64 `gorm:"column:recid3;type:decimal(9,2);not null" json:"recid3"`
2056
+ }
2057
+ expectedSql := []string {
2058
+ `ALTER TABLE "migrate_decimal_columns" ALTER COLUMN "recid1" decimal(8) NOT NULL` ,
2059
+ `ALTER TABLE "migrate_decimal_columns" ALTER COLUMN "recid2" decimal(9,1) NOT NULL` ,
2060
+ `ALTER TABLE "migrate_decimal_columns" ALTER COLUMN "recid3" decimal(9,2) NOT NULL` ,
2061
+ }
2062
+ decimalColumnsTest [MigrateDecimalColumn , MigrateDecimalColumn2 ](t , expectedSql )
2063
+ } else if DB .Dialector .Name () == "postgres" {
2064
+ type MigrateDecimalColumn struct {
2065
+ RecID1 int64 `gorm:"column:recid1;type:numeric(9,0);not null" json:"recid1"`
2066
+ RecID2 int64 `gorm:"column:recid2;type:numeric(8);not null" json:"recid2"`
2067
+ RecID3 int64 `gorm:"column:recid3;type:numeric(8,1);not null" json:"recid3"`
2068
+ }
2069
+ type MigrateDecimalColumn2 struct {
2070
+ RecID1 int64 `gorm:"column:recid1;type:numeric(8);not null" json:"recid1"`
2071
+ RecID2 int64 `gorm:"column:recid2;type:numeric(9,1);not null" json:"recid2"`
2072
+ RecID3 int64 `gorm:"column:recid3;type:numeric(9,2);not null" json:"recid3"`
2073
+ }
2074
+ expectedSql := []string {
2075
+ `ALTER TABLE "migrate_decimal_columns" ALTER COLUMN "recid1" TYPE numeric(8) USING "recid1"::numeric(8)` ,
2076
+ `ALTER TABLE "migrate_decimal_columns" ALTER COLUMN "recid2" TYPE numeric(9,1) USING "recid2"::numeric(9,1)` ,
2077
+ `ALTER TABLE "migrate_decimal_columns" ALTER COLUMN "recid3" TYPE numeric(9,2) USING "recid3"::numeric(9,2)` ,
2078
+ }
2079
+ decimalColumnsTest [MigrateDecimalColumn , MigrateDecimalColumn2 ](t , expectedSql )
2080
+ } else if DB .Dialector .Name () == "mysql" {
2081
+ type MigrateDecimalColumn struct {
2082
+ RecID1 int64 `gorm:"column:recid1;type:decimal(9,0);not null" json:"recid1"`
2083
+ RecID2 int64 `gorm:"column:recid2;type:decimal(8);not null" json:"recid2"`
2084
+ RecID3 int64 `gorm:"column:recid3;type:decimal(8,1);not null" json:"recid3"`
2085
+ }
2086
+ type MigrateDecimalColumn2 struct {
2087
+ RecID1 int64 `gorm:"column:recid1;type:decimal(8);not null" json:"recid1"`
2088
+ RecID2 int64 `gorm:"column:recid2;type:decimal(9,1);not null" json:"recid2"`
2089
+ RecID3 int64 `gorm:"column:recid3;type:decimal(9,2);not null" json:"recid3"`
2090
+ }
2091
+ expectedSql := []string {
2092
+ "ALTER TABLE `migrate_decimal_columns` MODIFY COLUMN `recid1` decimal(8) NOT NULL" ,
2093
+ "ALTER TABLE `migrate_decimal_columns` MODIFY COLUMN `recid2` decimal(9,1) NOT NULL" ,
2094
+ "ALTER TABLE `migrate_decimal_columns` MODIFY COLUMN `recid3` decimal(9,2) NOT NULL" ,
2095
+ }
2096
+ decimalColumnsTest [MigrateDecimalColumn , MigrateDecimalColumn2 ](t , expectedSql )
2097
+ }
2098
+ }
0 commit comments