From 5163bb910730ac81da213fcf5770fc53f4058aed Mon Sep 17 00:00:00 2001 From: a631807682 <631807682@qq.com> Date: Fri, 27 May 2022 15:42:55 +0800 Subject: [PATCH] fix: dup filed in inconsistent schema and database --- scan.go | 16 +++++++++++----- tests/scan_test.go | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/scan.go b/scan.go index 21ca51a2..3a2d139d 100644 --- a/scan.go +++ b/scan.go @@ -193,15 +193,21 @@ func Scan(rows Rows, db *DB, mode ScanMode) { // Not Pluck if sch != nil { + schFiledCount := 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 - for fieldIndex, selectField := range sch.Fields[curIndex+1:] { - if selectField.DBName == column && selectField.Readable { - selectedColumnsMap[column] = curIndex + fieldIndex + 1 - fields[idx] = selectField - break + offset := curIndex + 1 + // handle sch inconsistent with database + // like Raw(`...`).Scan + if schFiledCount > offset { + for fieldIndex, selectField := range sch.Fields[offset:] { + if selectField.DBName == column && selectField.Readable { + selectedColumnsMap[column] = curIndex + fieldIndex + 1 + fields[idx] = selectField + break + } } } } else { diff --git a/tests/scan_test.go b/tests/scan_test.go index 1824c088..b7bf9a5e 100644 --- a/tests/scan_test.go +++ b/tests/scan_test.go @@ -221,4 +221,21 @@ func TestScanToEmbedded(t *testing.T) { t.Errorf("Failed to run join query, got error: %v", err) } AssertEqual(t, person1, personDupField) + + user := User{ + Name: "TestScanToEmbedded_1", + Manager: &User{Name: "TestScanToEmbedded_1_m1", + Manager: &User{Name: "TestScanToEmbedded_1_m1_m1"}, + }, + } + DB.Create(&user) + + type UserScan struct { + ID uint + Name string + ManagerID *uint + } + var user2 UserScan + err := DB.Raw("SELECT * FROM users INNER JOIN users Manager ON users.manager_id = Manager.id WHERE users.id = ?", user.ID).Scan(&user2).Error + AssertEqual(t, err, nil) }