From 4ec73c9bf46662bfef7a87d766e9c34661846385 Mon Sep 17 00:00:00 2001 From: Edward McFarlane <3036610+emcfarlane@users.noreply.github.com> Date: Mon, 19 Dec 2022 04:49:05 +0100 Subject: [PATCH] Add test case for embedded value selects (#5901) * Add test case for embedded value selects * Revert recycle struct optimisation to avoid pointer overwrites --- scan.go | 12 +++--------- tests/embedded_struct_test.go | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/scan.go b/scan.go index 0a26ce4b..12a77862 100644 --- a/scan.go +++ b/scan.go @@ -65,7 +65,6 @@ func (db *DB) scanIntoStruct(rows Rows, reflectValue reflect.Value, values []int db.RowsAffected++ db.AddError(rows.Scan(values...)) - joinedSchemaMap := make(map[*schema.Field]interface{}) for idx, field := range fields { if field == nil { @@ -241,9 +240,8 @@ func Scan(rows Rows, db *DB, mode ScanMode) { switch reflectValue.Kind() { case reflect.Slice, reflect.Array: var ( - elem reflect.Value - recyclableStruct = reflect.New(reflectValueType) - isArrayKind = reflectValue.Kind() == reflect.Array + elem reflect.Value + isArrayKind = reflectValue.Kind() == reflect.Array ) if !update || reflectValue.Len() == 0 { @@ -275,11 +273,7 @@ func Scan(rows Rows, db *DB, mode ScanMode) { } } } else { - if isPtr && db.RowsAffected > 0 { - elem = reflect.New(reflectValueType) - } else { - elem = recyclableStruct - } + elem = reflect.New(reflectValueType) } db.scanIntoStruct(rows, elem, values, fields, joinFields) diff --git a/tests/embedded_struct_test.go b/tests/embedded_struct_test.go index e309d06c..ae69baca 100644 --- a/tests/embedded_struct_test.go +++ b/tests/embedded_struct_test.go @@ -36,7 +36,7 @@ func TestEmbeddedStruct(t *testing.T) { type EngadgetPost struct { BasePost BasePost `gorm:"Embedded"` - Author Author `gorm:"Embedded;EmbeddedPrefix:author_"` // Embedded struct + Author *Author `gorm:"Embedded;EmbeddedPrefix:author_"` // Embedded struct ImageUrl string } @@ -74,13 +74,27 @@ func TestEmbeddedStruct(t *testing.T) { t.Errorf("embedded struct's value should be scanned correctly") } - DB.Save(&EngadgetPost{BasePost: BasePost{Title: "engadget_news"}}) + DB.Save(&EngadgetPost{BasePost: BasePost{Title: "engadget_news"}, Author: &Author{Name: "Edward"}}) + DB.Save(&EngadgetPost{BasePost: BasePost{Title: "engadget_article"}, Author: &Author{Name: "George"}}) var egNews EngadgetPost if err := DB.First(&egNews, "title = ?", "engadget_news").Error; err != nil { t.Errorf("no error should happen when query with embedded struct, but got %v", err) } else if egNews.BasePost.Title != "engadget_news" { t.Errorf("embedded struct's value should be scanned correctly") } + + var egPosts []EngadgetPost + if err := DB.Order("author_name asc").Find(&egPosts).Error; err != nil { + t.Fatalf("no error should happen when query with embedded struct, but got %v", err) + } + expectAuthors := []string{"Edward", "George"} + for i, post := range egPosts { + t.Log(i, post.Author) + if want := expectAuthors[i]; post.Author.Name != want { + t.Errorf("expected author %s got %s", want, post.Author.Name) + } + } + } func TestEmbeddedPointerTypeStruct(t *testing.T) {