From a6b8eb4ba447619e7f9f18a7c871e4b9b05b4629 Mon Sep 17 00:00:00 2001 From: a631807682 <631807682@qq.com> Date: Tue, 24 May 2022 10:50:34 +0800 Subject: [PATCH 1/4] fix: duplicate column scan --- scan.go | 1 + tests/scan_test.go | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/scan.go b/scan.go index ad3734d89..21ca51a29 100644 --- a/scan.go +++ b/scan.go @@ -196,6 +196,7 @@ func Scan(rows Rows, db *DB, mode ScanMode) { 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 diff --git a/tests/scan_test.go b/tests/scan_test.go index 425c0a299..1824c0882 100644 --- a/tests/scan_test.go +++ b/tests/scan_test.go @@ -214,4 +214,11 @@ func TestScanToEmbedded(t *testing.T) { if !addressMatched { t.Errorf("Failed, no address matched") } + + personDupField := Person{ID: person1.ID} + if err := DB.Select("people.id, people.*"). + First(&personDupField).Error; err != nil { + t.Errorf("Failed to run join query, got error: %v", err) + } + AssertEqual(t, person1, personDupField) } 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 2/4] 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 21ca51a29..3a2d139da 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 1824c0882..b7bf9a5ef 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) } From 9da5e4e5dbbf177bf801355dd7f4a4732f1c831a Mon Sep 17 00:00:00 2001 From: a631807682 <631807682@qq.com> Date: Fri, 27 May 2022 15:50:02 +0800 Subject: [PATCH 3/4] chore[ci skip]: gofumpt style --- tests/scan_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/scan_test.go b/tests/scan_test.go index b7bf9a5ef..6f2e9f54d 100644 --- a/tests/scan_test.go +++ b/tests/scan_test.go @@ -224,7 +224,8 @@ func TestScanToEmbedded(t *testing.T) { user := User{ Name: "TestScanToEmbedded_1", - Manager: &User{Name: "TestScanToEmbedded_1_m1", + Manager: &User{ + Name: "TestScanToEmbedded_1_m1", Manager: &User{Name: "TestScanToEmbedded_1_m1_m1"}, }, } From 0622c0f95802a50ac3f00c58053edec80b1906ff Mon Sep 17 00:00:00 2001 From: a631807682 <631807682@qq.com> Date: Fri, 27 May 2022 16:02:50 +0800 Subject: [PATCH 4/4] chore[ci skip]: fix typo --- scan.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scan.go b/scan.go index 3a2d139da..a611a9ce8 100644 --- a/scan.go +++ b/scan.go @@ -193,7 +193,7 @@ func Scan(rows Rows, db *DB, mode ScanMode) { // Not Pluck if sch != nil { - schFiledCount := len(sch.Fields) + schFieldsCount := len(sch.Fields) for idx, column := range columns { if field := sch.LookUpField(column); field != nil && field.Readable { if curIndex, ok := selectedColumnsMap[column]; ok { @@ -201,7 +201,7 @@ func Scan(rows Rows, db *DB, mode ScanMode) { offset := curIndex + 1 // handle sch inconsistent with database // like Raw(`...`).Scan - if schFiledCount > offset { + if schFieldsCount > offset { for fieldIndex, selectField := range sch.Fields[offset:] { if selectField.DBName == column && selectField.Readable { selectedColumnsMap[column] = curIndex + fieldIndex + 1