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
					
				
							
								
								
									
										17
									
								
								scan.go
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								scan.go
									
									
									
									
									
								
							| @ -193,14 +193,21 @@ func Scan(rows Rows, db *DB, mode ScanMode) { | |||||||
| 
 | 
 | ||||||
| 			// Not Pluck
 | 			// Not Pluck
 | ||||||
| 			if sch != nil { | 			if sch != nil { | ||||||
|  | 				schFieldsCount := len(sch.Fields) | ||||||
| 				for idx, column := range columns { | 				for idx, column := range columns { | ||||||
| 					if field := sch.LookUpField(column); field != nil && field.Readable { | 					if field := sch.LookUpField(column); field != nil && field.Readable { | ||||||
| 						if curIndex, ok := selectedColumnsMap[column]; ok { | 						if curIndex, ok := selectedColumnsMap[column]; ok { | ||||||
| 							for fieldIndex, selectField := range sch.Fields[curIndex+1:] { | 							fields[idx] = field // handle duplicate fields
 | ||||||
| 								if selectField.DBName == column && selectField.Readable { | 							offset := curIndex + 1 | ||||||
| 									selectedColumnsMap[column] = curIndex + fieldIndex + 1 | 							// handle sch inconsistent with database
 | ||||||
| 									fields[idx] = selectField | 							// like Raw(`...`).Scan
 | ||||||
| 									break | 							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 { | 						} else { | ||||||
|  | |||||||
| @ -214,4 +214,29 @@ func TestScanToEmbedded(t *testing.T) { | |||||||
| 	if !addressMatched { | 	if !addressMatched { | ||||||
| 		t.Errorf("Failed, no address matched") | 		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