From 1e13fd7543826a5d341401387cb1aa22fdf4b9f6 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Mon, 8 Apr 2024 11:29:55 +0800 Subject: [PATCH] Fix duplicated columns in INSERT SQL for some fields with default value --- callbacks/create.go | 4 ++-- tests/default_value_test.go | 18 ++++++++++++++++++ tests/go.mod | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/callbacks/create.go b/callbacks/create.go index afea2ccac..8b7846b63 100644 --- a/callbacks/create.go +++ b/callbacks/create.go @@ -307,7 +307,7 @@ func ConvertToCreateValues(stmt *gorm.Statement) (values clause.Values) { values.Columns = append(values.Columns, clause.Column{Name: field.DBName}) for idx := range values.Values { if vs[idx] == nil { - values.Values[idx] = append(values.Values[idx], stmt.Dialector.DefaultValueOf(field)) + values.Values[idx] = append(values.Values[idx], stmt.DefaultValueOf(field)) } else { values.Values[idx] = append(values.Values[idx], vs[idx]) } @@ -333,7 +333,7 @@ func ConvertToCreateValues(stmt *gorm.Statement) (values clause.Values) { } for _, field := range stmt.Schema.FieldsWithDefaultDBValue { - if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) { + if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) && field.DefaultValueInterface == nil { if rvOfvalue, isZero := field.ValueOf(stmt.Context, stmt.ReflectValue); !isZero { values.Columns = append(values.Columns, clause.Column{Name: field.DBName}) values.Values[0] = append(values.Values[0], rvOfvalue) diff --git a/tests/default_value_test.go b/tests/default_value_test.go index 918f0796d..71d6deb25 100644 --- a/tests/default_value_test.go +++ b/tests/default_value_test.go @@ -38,4 +38,22 @@ func TestDefaultValue(t *testing.T) { } else if result.Name != "foo" || result.Name2 != "foo" || result.Name3 != "" || result.Age != 18 || !result.Enabled || result.Created.Format("20060102") != "20000102" { t.Fatalf("Failed to find created data with default data, got %+v", result) } + + type Harumph2 struct { + ID int `gorm:"default:0"` + Email string `gorm:"not null;index:,unique"` + Name string `gorm:"notNull;default:foo"` + Name2 string `gorm:"size:233;not null;default:'foo'"` + Name3 string `gorm:"size:233;notNull;default:''"` + Age int `gorm:"default:18"` + Created time.Time `gorm:"default:2000-01-02"` + Enabled bool `gorm:"default:true"` + } + + harumph2 := Harumph2{ID: 2, Email: "hello2@gorm.io"} + if err := DB.Table("harumphs").Create(&harumph2).Error; err != nil { + t.Fatalf("Failed to create data with default value, got error: %v", err) + } else if harumph2.ID != 2 || harumph2.Name != "foo" || harumph2.Name2 != "foo" || harumph2.Name3 != "" || harumph2.Age != 18 || !harumph2.Enabled || harumph2.Created.Format("20060102") != "20000102" { + t.Fatalf("Failed to create data with default value, got: %+v", harumph2) + } } diff --git a/tests/go.mod b/tests/go.mod index 3d3901d93..d58469c45 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -11,13 +11,13 @@ require ( gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlite v1.5.5 gorm.io/driver/sqlserver v1.5.3 - gorm.io/gorm v1.25.8 + gorm.io/gorm v1.25.9 ) require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-sql-driver/mysql v1.8.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect @@ -29,7 +29,7 @@ require ( github.com/microsoft/go-mssqldb v1.7.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/text v0.14.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect )