This commit is contained in:
		
							parent
							
								
									be440e7512
								
							
						
					
					
						commit
						a3cc6c6088
					
				
							
								
								
									
										31
									
								
								scan.go
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								scan.go
									
									
									
									
									
								
							| @ -163,11 +163,10 @@ func Scan(rows Rows, db *DB, mode ScanMode) { | |||||||
| 		} | 		} | ||||||
| 	default: | 	default: | ||||||
| 		var ( | 		var ( | ||||||
| 			fields             = make([]*schema.Field, len(columns)) | 			fields       = make([]*schema.Field, len(columns)) | ||||||
| 			selectedColumnsMap = make(map[string]int, len(columns)) | 			joinFields   [][2]*schema.Field | ||||||
| 			joinFields         [][2]*schema.Field | 			sch          = db.Statement.Schema | ||||||
| 			sch                = db.Statement.Schema | 			reflectValue = db.Statement.ReflectValue | ||||||
| 			reflectValue       = db.Statement.ReflectValue |  | ||||||
| 		) | 		) | ||||||
| 
 | 
 | ||||||
| 		if reflectValue.Kind() == reflect.Interface { | 		if reflectValue.Kind() == reflect.Interface { | ||||||
| @ -200,26 +199,24 @@ func Scan(rows Rows, db *DB, mode ScanMode) { | |||||||
| 
 | 
 | ||||||
| 			// Not Pluck
 | 			// Not Pluck
 | ||||||
| 			if sch != nil { | 			if sch != nil { | ||||||
| 				schFieldsCount := len(sch.Fields) | 				matchedFieldCount := make(map[string]int, len(columns)) | ||||||
| 				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 { | 						fields[idx] = field | ||||||
| 							fields[idx] = field // handle duplicate fields
 | 						if count, ok := matchedFieldCount[column]; ok { | ||||||
| 							offset := curIndex + 1 | 							// handle duplicate fields
 | ||||||
| 							// handle sch inconsistent with database
 | 							for _, selectField := range sch.Fields { | ||||||
| 							// like Raw(`...`).Scan
 | 								if selectField.DBName == column && selectField.Readable { | ||||||
| 							if schFieldsCount > offset { | 									if count == 0 { | ||||||
| 								for fieldIndex, selectField := range sch.Fields[offset:] { | 										matchedFieldCount[column]++ | ||||||
| 									if selectField.DBName == column && selectField.Readable { |  | ||||||
| 										selectedColumnsMap[column] = curIndex + fieldIndex + 1 |  | ||||||
| 										fields[idx] = selectField | 										fields[idx] = selectField | ||||||
| 										break | 										break | ||||||
| 									} | 									} | ||||||
|  | 									count-- | ||||||
| 								} | 								} | ||||||
| 							} | 							} | ||||||
| 						} else { | 						} else { | ||||||
| 							fields[idx] = field | 							matchedFieldCount[column] = 1 | ||||||
| 							selectedColumnsMap[column] = idx |  | ||||||
| 						} | 						} | ||||||
| 					} else if names := strings.Split(column, "__"); len(names) > 1 { | 					} else if names := strings.Split(column, "__"); len(names) > 1 { | ||||||
| 						if rel, ok := sch.Relationships.Relations[names[0]]; ok { | 						if rel, ok := sch.Relationships.Relations[names[0]]; ok { | ||||||
|  | |||||||
| @ -9,12 +9,12 @@ require ( | |||||||
| 	github.com/jinzhu/now v1.1.5 | 	github.com/jinzhu/now v1.1.5 | ||||||
| 	github.com/lib/pq v1.10.7 | 	github.com/lib/pq v1.10.7 | ||||||
| 	github.com/mattn/go-sqlite3 v1.14.15 // indirect | 	github.com/mattn/go-sqlite3 v1.14.15 // indirect | ||||||
| 	golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0 // indirect | 	golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect | ||||||
| 	gorm.io/driver/mysql v1.3.6 | 	gorm.io/driver/mysql v1.3.6 | ||||||
| 	gorm.io/driver/postgres v1.3.10 | 	gorm.io/driver/postgres v1.3.10 | ||||||
| 	gorm.io/driver/sqlite v1.3.6 | 	gorm.io/driver/sqlite v1.3.6 | ||||||
| 	gorm.io/driver/sqlserver v1.3.2 | 	gorm.io/driver/sqlserver v1.3.2 | ||||||
| 	gorm.io/gorm v1.23.9 | 	gorm.io/gorm v1.23.10 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| replace gorm.io/gorm => ../ | replace gorm.io/gorm => ../ | ||||||
|  | |||||||
| @ -229,3 +229,34 @@ func TestJoinWithSoftDeleted(t *testing.T) { | |||||||
| 		t.Fatalf("joins NamedPet and Account should not empty:%v", user2) | 		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("users.*, user_speaks.*,  languages.*, pets.*").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 || *(results[0].Pet.UserID) != user.ID { | ||||||
|  | 		t.Fatalf("wrong user id in pet") | ||||||
|  | 	} else if results[0].Pet.Name != user.Pets[0].Name { | ||||||
|  | 		t.Fatalf("wrong pet name") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Stephano George
						Stephano George