From b4490de97e131a512d3bf076161f6c656d8705f4 Mon Sep 17 00:00:00 2001 From: Stephano George Date: Tue, 27 Sep 2022 17:13:14 +0800 Subject: [PATCH] Fix: Wrong value when Find with JOIN and same column name (#5711) --- scan.go | 30 +++++++++++------------------- tests/joins_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/scan.go b/scan.go index 2db431601..aa1dcd262 100644 --- a/scan.go +++ b/scan.go @@ -200,28 +200,20 @@ func Scan(rows Rows, db *DB, mode ScanMode) { // Not Pluck if sch != nil { - schFieldsCount := len(sch.Fields) for idx, column := range columns { - if field := sch.LookUpField(column); field != nil && field.Readable { - if curIndex, ok := selectedColumnsMap[column]; ok { - fields[idx] = field // handle duplicate fields - offset := curIndex + 1 - // handle sch inconsistent with database - // like Raw(`...`).Scan - if schFieldsCount > offset { - for fieldIndex, selectField := range sch.Fields[offset:] { - if selectField.DBName == column && selectField.Readable { - selectedColumnsMap[column] = curIndex + fieldIndex + 1 - fields[idx] = selectField - break - } - } + for i, field := range sch.Fields[selectedColumnsMap[column]:] { + if field.DBName == column { + if field.Readable { + fields[idx] = field + selectedColumnsMap[column] += i + 1 } - } else { - fields[idx] = field - selectedColumnsMap[column] = idx + break } - } else if names := strings.Split(column, "__"); len(names) > 1 { + } + if fields[idx] != nil { + continue + } + if names := strings.Split(column, "__"); len(names) > 1 { if rel, ok := sch.Relationships.Relations[names[0]]; ok { if field := rel.FieldSchema.LookUpField(strings.Join(names[1:], "__")); field != nil && field.Readable { fields[idx] = field diff --git a/tests/joins_test.go b/tests/joins_test.go index 4908e5ba4..2271bd175 100644 --- a/tests/joins_test.go +++ b/tests/joins_test.go @@ -3,6 +3,7 @@ package tests_test import ( "regexp" "sort" + "strings" "testing" "gorm.io/gorm" @@ -229,3 +230,32 @@ func TestJoinWithSoftDeleted(t *testing.T) { t.Fatalf("joins NamedPet and Account should not empty:%v", user2) } } + +func TestJoinWithSameColumnName(t *testing.T) { + user := GetUser("TestJoinWithSameColumnName", Config{ + Languages: 1, + Pets: 1, + }) + DB.Create(user) + type UserSpeak struct { + UserID uint + LanguageCode string + } + type Result struct { + User + UserSpeak + Language + Pet + } + results := make([]Result, 0, 1) + DB.Select("*").Table("users").Joins("JOIN user_speaks ON user_speaks.user_id = users.id"). + Joins("JOIN languages ON languages.code = user_speaks.language_code"). + Joins("LEFT OUTER JOIN pets ON pets.user_id = users.id").Find(&results) + if len(results) == 0 { + t.Fatalf("no record find") + } else if results[0].Pet.UserID == nil { + t.Fatalf("wrong user id in pet") + } else if !strings.Contains(results[0].Pet.Name, "_pet_") { + t.Fatalf("wrong pet name") + } +}