fix: can not set field in-place in join
This commit is contained in:
		
							parent
							
								
									ebac31ea48
								
							
						
					
					
						commit
						8039ba0eb1
					
				
							
								
								
									
										9
									
								
								scan.go
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								scan.go
									
									
									
									
									
								
							@ -66,18 +66,23 @@ func (db *DB) scanIntoStruct(rows Rows, reflectValue reflect.Value, values []int
 | 
				
			|||||||
	db.RowsAffected++
 | 
						db.RowsAffected++
 | 
				
			||||||
	db.AddError(rows.Scan(values...))
 | 
						db.AddError(rows.Scan(values...))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						joinedSchemaMap := make(map[*schema.Field]interface{}, 0)
 | 
				
			||||||
	for idx, field := range fields {
 | 
						for idx, field := range fields {
 | 
				
			||||||
		if field != nil {
 | 
							if field != nil {
 | 
				
			||||||
			if len(joinFields) == 0 || joinFields[idx][0] == nil {
 | 
								if len(joinFields) == 0 || joinFields[idx][0] == nil {
 | 
				
			||||||
				db.AddError(field.Set(db.Statement.Context, reflectValue, values[idx]))
 | 
									db.AddError(field.Set(db.Statement.Context, reflectValue, values[idx]))
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				relValue := joinFields[idx][0].ReflectValueOf(db.Statement.Context, reflectValue)
 | 
									joinSchema := joinFields[idx][0]
 | 
				
			||||||
				if relValue.Kind() == reflect.Ptr && relValue.IsNil() {
 | 
									relValue := joinSchema.ReflectValueOf(db.Statement.Context, reflectValue)
 | 
				
			||||||
 | 
									if relValue.Kind() == reflect.Ptr {
 | 
				
			||||||
 | 
										if _, ok := joinedSchemaMap[joinSchema]; !ok {
 | 
				
			||||||
						if value := reflect.ValueOf(values[idx]).Elem(); value.Kind() == reflect.Ptr && value.IsNil() {
 | 
											if value := reflect.ValueOf(values[idx]).Elem(); value.Kind() == reflect.Ptr && value.IsNil() {
 | 
				
			||||||
							continue
 | 
												continue
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						relValue.Set(reflect.New(relValue.Type().Elem()))
 | 
											relValue.Set(reflect.New(relValue.Type().Elem()))
 | 
				
			||||||
 | 
											joinedSchemaMap[joinSchema] = nil
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				db.AddError(joinFields[idx][1].Set(db.Statement.Context, relValue, values[idx]))
 | 
									db.AddError(joinFields[idx][1].Set(db.Statement.Context, relValue, values[idx]))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
@ -1260,6 +1260,11 @@ func TestQueryScannerWithSingleColumn(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestQueryResetNullValue(t *testing.T) {
 | 
					func TestQueryResetNullValue(t *testing.T) {
 | 
				
			||||||
 | 
						type QueryResetItem struct {
 | 
				
			||||||
 | 
							ID   string `gorm:"type:varchar(5)"`
 | 
				
			||||||
 | 
							Name string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	type QueryResetNullValue struct {
 | 
						type QueryResetNullValue struct {
 | 
				
			||||||
		ID      int
 | 
							ID      int
 | 
				
			||||||
		Name    string     `gorm:"default:NULL"`
 | 
							Name    string     `gorm:"default:NULL"`
 | 
				
			||||||
@ -1268,10 +1273,14 @@ func TestQueryResetNullValue(t *testing.T) {
 | 
				
			|||||||
		Number2 uint64     `gorm:"default:NULL"`
 | 
							Number2 uint64     `gorm:"default:NULL"`
 | 
				
			||||||
		Number3 float64    `gorm:"default:NULL"`
 | 
							Number3 float64    `gorm:"default:NULL"`
 | 
				
			||||||
		Now     *time.Time `gorm:"defalut:NULL"`
 | 
							Now     *time.Time `gorm:"defalut:NULL"`
 | 
				
			||||||
 | 
							Item1Id string
 | 
				
			||||||
 | 
							Item1   *QueryResetItem `gorm:"references:ID"`
 | 
				
			||||||
 | 
							Item2Id string
 | 
				
			||||||
 | 
							Item2   *QueryResetItem `gorm:"references:ID"`
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DB.Migrator().DropTable(&QueryResetNullValue{})
 | 
						DB.Migrator().DropTable(&QueryResetNullValue{}, &QueryResetItem{})
 | 
				
			||||||
	DB.AutoMigrate(&QueryResetNullValue{})
 | 
						DB.AutoMigrate(&QueryResetNullValue{}, &QueryResetItem{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	now := time.Now()
 | 
						now := time.Now()
 | 
				
			||||||
	q1 := QueryResetNullValue{
 | 
						q1 := QueryResetNullValue{
 | 
				
			||||||
@ -1281,9 +1290,26 @@ func TestQueryResetNullValue(t *testing.T) {
 | 
				
			|||||||
		Number2: 200,
 | 
							Number2: 200,
 | 
				
			||||||
		Number3: 300.1,
 | 
							Number3: 300.1,
 | 
				
			||||||
		Now:     &now,
 | 
							Now:     &now,
 | 
				
			||||||
 | 
							Item1: &QueryResetItem{
 | 
				
			||||||
 | 
								ID:   "u_1_1",
 | 
				
			||||||
 | 
								Name: "item_1_1",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Item2: &QueryResetItem{
 | 
				
			||||||
 | 
								ID:   "u_1_2",
 | 
				
			||||||
 | 
								Name: "item_1_2",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	q2 := QueryResetNullValue{}
 | 
						q2 := QueryResetNullValue{
 | 
				
			||||||
 | 
							Item1: &QueryResetItem{
 | 
				
			||||||
 | 
								ID:   "u_2_1",
 | 
				
			||||||
 | 
								Name: "item_2_1",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							Item2: &QueryResetItem{
 | 
				
			||||||
 | 
								ID:   "u_2_2",
 | 
				
			||||||
 | 
								Name: "item_2_2",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var err error
 | 
						var err error
 | 
				
			||||||
	err = DB.Create(&q1).Error
 | 
						err = DB.Create(&q1).Error
 | 
				
			||||||
@ -1297,7 +1323,7 @@ func TestQueryResetNullValue(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var qs []QueryResetNullValue
 | 
						var qs []QueryResetNullValue
 | 
				
			||||||
	err = DB.Find(&qs).Error
 | 
						err = DB.Joins("Item1").Joins("Item2").Find(&qs).Error
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("failed to find:%v", err)
 | 
							t.Errorf("failed to find:%v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user