diff --git a/go.mod b/go.mod index d1ba4316..fd0c5360 100644 --- a/go.mod +++ b/go.mod @@ -5,17 +5,17 @@ go 1.23.0 toolchain go1.24.3 require ( - gorm.io/driver/mysql v1.5.7 - gorm.io/driver/postgres v1.5.11 - gorm.io/driver/sqlite v1.5.7 - gorm.io/driver/sqlserver v1.6.0 + gorm.io/driver/mysql v1.6.0 + gorm.io/driver/postgres v1.6.0 + gorm.io/driver/sqlite v1.6.0 + gorm.io/driver/sqlserver v1.6.1 gorm.io/gen v0.3.27 - gorm.io/gorm v1.30.0 + gorm.io/gorm v1.30.1 ) require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/go-sql-driver/mysql v1.9.2 // indirect + github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -25,16 +25,16 @@ require ( github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.28 // indirect - github.com/microsoft/go-mssqldb v1.8.1 // indirect - golang.org/x/crypto v0.38.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/sync v0.14.0 // indirect - golang.org/x/text v0.25.0 // indirect - golang.org/x/tools v0.33.0 // indirect - gorm.io/datatypes v1.2.5 // indirect + github.com/mattn/go-sqlite3 v1.14.32 // indirect + github.com/microsoft/go-mssqldb v1.9.2 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/mod v0.27.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/tools v0.36.0 // indirect + gorm.io/datatypes v1.2.6 // indirect gorm.io/hints v1.1.2 // indirect - gorm.io/plugin/dbresolver v1.6.0 // indirect + gorm.io/plugin/dbresolver v1.6.2 // indirect ) replace gorm.io/gorm => ./gorm diff --git a/main_test.go b/main_test.go index 60a388f7..fdf09212 100644 --- a/main_test.go +++ b/main_test.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "testing" ) @@ -18,3 +19,53 @@ func TestGORM(t *testing.T) { t.Errorf("Failed, got error: %v", err) } } + +func TestBooleanDefaultBug(t *testing.T) { + // Auto migrate the Tree model + if err := DB.AutoMigrate(&Tree{}); err != nil { + t.Fatalf("Failed to migrate Tree model: %v", err) + } + + // Clean up any existing data + DB.Where("1 = 1").Delete(&Tree{}) + + // Create a tree with IsAlive explicitly set to false + tree := Tree{ + IsAlive: false, + Height: 10.0, + } + + if err := DB.Create(&tree).Error; err != nil { + t.Fatalf("Failed to create tree: %v", err) + } + + // Query the database to check the actual stored values + var debugCount struct { + IsAliveTrue int64 `json:"is_alive_true"` + IsAliveFalse int64 `json:"is_alive_false"` + } + + DB.Model(&Tree{}).Where("is_alive = ?", true).Count(&debugCount.IsAliveTrue) + DB.Model(&Tree{}).Where("is_alive = ?", false).Count(&debugCount.IsAliveFalse) + + fmt.Printf("DEBUG: After insert - has %d trees with is_alive=true, %d with is_alive=false\n", + debugCount.IsAliveTrue, debugCount.IsAliveFalse) + + // The bug: even though we set IsAlive to false, it might be stored as true due to the default value + if debugCount.IsAliveFalse == 0 { + t.Errorf("BUG REPRODUCED: Expected 1 tree with is_alive=false, but found %d. The boolean field with default:true cannot be set to false", debugCount.IsAliveFalse) + } + + // Verify by reading the record back + var retrievedTree Tree + if err := DB.First(&retrievedTree, tree.ID).Error; err != nil { + t.Fatalf("Failed to retrieve tree: %v", err) + } + + t.Logf("Original tree.IsAlive: %v", tree.IsAlive) + t.Logf("Retrieved tree.IsAlive: %v", retrievedTree.IsAlive) + + if retrievedTree.IsAlive != false { + t.Errorf("BUG REPRODUCED: Expected tree.IsAlive to be false, but got %v", retrievedTree.IsAlive) + } +} diff --git a/models.go b/models.go index 692a6842..390a3e83 100644 --- a/models.go +++ b/models.go @@ -58,3 +58,10 @@ type Language struct { Code string `gorm:"primarykey"` Name string } + +// Tree model to reproduce boolean default value bug +type Tree struct { + ID uint `json:"id" gorm:"primaryKey"` + IsAlive bool `json:"is_alive" gorm:"default:true"` + Height float64 `json:"height" gorm:"type:FLOAT"` +}