fix: duplicate column scan (#5369)
* fix: duplicate column scan * fix: dup filed in inconsistent schema and database * chore[ci skip]: gofumpt style * chore[ci skip]: fix typo
This commit is contained in:
		
							parent
							
								
									7d1a92d60e
								
							
						
					
					
						commit
						7e13b03bd4
					
				
							
								
								
									
										9
									
								
								scan.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								scan.go
									
									
									
									
									
								
							| @ -193,16 +193,23 @@ 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 { | ||||
| 							for fieldIndex, selectField := range sch.Fields[curIndex+1:] { | ||||
| 							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 | ||||
| 									} | ||||
| 								} | ||||
| 							} | ||||
| 						} else { | ||||
| 							fields[idx] = field | ||||
| 							selectedColumnsMap[column] = idx | ||||
|  | ||||
| @ -214,4 +214,29 @@ 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) | ||||
| 
 | ||||
| 	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) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Cr
						Cr