Skip to content

Commit 355a391

Browse files
committed
Fixes go-gorm#7090
This PR adds the case to handle the assignment of a nil Ptr value to a uuid.UUID (resolved as an Array), so that the model object reflects the correct value after Updates() has completed.
1 parent 4a50b36 commit 355a391

File tree

7 files changed

+48
-7
lines changed

7 files changed

+48
-7
lines changed

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ require (
77
github.com/jinzhu/now v1.1.5
88
golang.org/x/text v0.14.0
99
)
10+
11+
require github.com/google/uuid v1.6.0

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
2+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
13
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
24
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
35
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=

schema/field.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,9 @@ func (field *Field) setupValuerAndSetter() {
896896
if !reflectV.IsValid() {
897897
field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem())
898898
} else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() {
899-
return
899+
if field.FieldType.Elem().Kind() == reflect.Array {
900+
field.ReflectValueOf(ctx, value).Set(reflectV)
901+
}
900902
} else if reflectV.Type().AssignableTo(field.FieldType) {
901903
field.ReflectValueOf(ctx, value).Set(reflectV)
902904
} else if reflectV.Kind() == reflect.Ptr {

tests/connpool_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ func TestConnPoolWrapper(t *testing.T) {
101101
db: nativeDB,
102102
expect: []string{
103103
"SELECT VERSION()",
104-
"INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`) VALUES (?,?,?,?,?,?,?,?,?)",
104+
"INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`user_uuid`) VALUES (?,?,?,?,?,?,?,?,?,?)",
105105
"SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?",
106-
"INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`) VALUES (?,?,?,?,?,?,?,?,?)",
106+
"INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`user_uuid`) VALUES (?,?,?,?,?,?,?,?,?,?)",
107107
"SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?",
108108
"SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?",
109-
"INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`) VALUES (?,?,?,?,?,?,?,?,?)",
109+
"INSERT INTO `users` (`created_at`,`updated_at`,`deleted_at`,`name`,`age`,`birthday`,`company_id`,`manager_id`,`active`,`user_uuid`) VALUES (?,?,?,?,?,?,?,?,?,?)",
110110
"SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?",
111111
"SELECT * FROM `users` WHERE name = ? AND `users`.`deleted_at` IS NULL ORDER BY `users`.`id` LIMIT ?",
112112
},

tests/sql_builder_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func TestDryRun(t *testing.T) {
158158
dryRunDB := DB.Session(&gorm.Session{DryRun: true})
159159

160160
stmt := dryRunDB.Create(&user).Statement
161-
if stmt.SQL.String() == "" || len(stmt.Vars) != 9 {
161+
if stmt.SQL.String() == "" || len(stmt.Vars) != 10 {
162162
t.Errorf("Failed to generate sql, got %v", stmt.SQL.String())
163163
}
164164

@@ -403,7 +403,7 @@ func TestToSQL(t *testing.T) {
403403
sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
404404
return tx.Model(&User{}).Create(user)
405405
})
406-
assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false) RETURNING "id"`, sql)
406+
assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active","user_uuid") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false,NULL) RETURNING "id"`, sql)
407407

408408
// save
409409
user = &User{Name: "foo", Age: 20}
@@ -412,7 +412,7 @@ func TestToSQL(t *testing.T) {
412412
sql = DB.ToSQL(func(tx *gorm.DB) *gorm.DB {
413413
return tx.Model(&User{}).Save(user)
414414
})
415-
assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false) RETURNING "id"`, sql)
415+
assertEqualSQL(t, `INSERT INTO "users" ("created_at","updated_at","deleted_at","name","age","birthday","company_id","manager_id","active","user_uuid") VALUES ('2021-10-18 00:00:00','2021-10-18 00:00:00',NULL,'foo',20,NULL,NULL,NULL,false,NULL) RETURNING "id"`, sql)
416416

417417
// updates
418418
user = &User{Name: "bar", Age: 22}

tests/update_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/google/uuid"
1112
"gorm.io/gorm"
1213
"gorm.io/gorm/clause"
1314
"gorm.io/gorm/utils"
@@ -183,6 +184,38 @@ func TestUpdates(t *testing.T) {
183184

184185
user3.Age += 100
185186
AssertObjEqual(t, user4, user3, "UpdatedAt", "Age")
187+
188+
// Updates() with map and uuid.UUID - Case 1 - Update with UUID value
189+
uuidVal, uuidErr := uuid.NewUUID()
190+
if uuidErr != nil {
191+
t.Errorf("No error should occur while generating UUID, but got %v", uuidErr)
192+
}
193+
tx := DB.Model(&user4)
194+
uuidErr = tx.Updates(map[string]interface{}{"user_uuid": uuidVal}).Error
195+
if uuidErr != nil {
196+
t.Errorf("No error should occur while updating with UUID value, but got %v", uuidErr)
197+
}
198+
AssertEqual(t, user4.UserUUID, uuidVal)
199+
200+
// Updates() with map and uuid.UUID - Case 2 - Update with a new UUID value
201+
uuidValNew, uuidErr := uuid.NewUUID()
202+
if uuidErr != nil {
203+
t.Errorf("No error should occur while generating UUID, but got %v", uuidErr)
204+
}
205+
var newTestUUID *uuid.UUID = &uuidValNew
206+
uuidErr = tx.Updates(map[string]interface{}{"user_uuid": newTestUUID}).Error
207+
if uuidErr != nil {
208+
t.Errorf("No error should occur while updating with UUID value, but got %v", uuidErr)
209+
}
210+
AssertEqual(t, user4.UserUUID, newTestUUID)
211+
212+
// Updates() with map and uuid.UUID - Case 3 - Update with UUID nil pointer
213+
var nilUUIDPtr *uuid.UUID = nil
214+
uuidErr = tx.Updates(map[string]interface{}{"user_uuid": nilUUIDPtr}).Error
215+
if uuidErr != nil {
216+
t.Errorf("No error should occur while updating with nil UUID pointer, but got %v", uuidErr)
217+
}
218+
AssertEqual(t, user4.UserUUID, nilUUIDPtr)
186219
}
187220

188221
func TestUpdateColumn(t *testing.T) {

utils/tests/models.go

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"database/sql"
55
"time"
66

7+
"github.com/google/uuid"
78
"gorm.io/gorm"
89
)
910

@@ -30,6 +31,7 @@ type User struct {
3031
Languages []Language `gorm:"many2many:UserSpeak;"`
3132
Friends []*User `gorm:"many2many:user_friends;"`
3233
Active bool
34+
UserUUID *uuid.UUID
3335
}
3436

3537
type Account struct {

0 commit comments

Comments
 (0)