New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
embedded should be nil if not exists #6288
Comments
maybe we need to add something like this ? from gorm.io/gorm/schema/field.go
|
PR welcome |
Hi
I add those types in tests/embedded_struct_test.go, and it will also make the test failed. type Content struct {
Content interface{} `gorm:"type:String"`
}
func (c Content) Value() (driver.Value, error) {
return json.Marshal(c)
}
func (c *Content) Scan(src interface{}) error {
...
}
type Author struct {
ID string
Name string
Email string
Age int
Content Content
ContentPtr *Content
BirthDay time.Time
BirthDayPtr *time.Time
} I've trying to change the reflect logic on struct scanner & pointer scanner to resolve this problem. Not sure if it's gorm wants? diff --git a/schema/field.go b/schema/field.go index 7d1a178..dd08e05 100644 --- a/schema/field.go +++ b/schema/field.go @@ -846,7 +846,7 @@ func (field *Field) setupValuerAndSetter() { field.Set = func(ctx context.Context, value reflect.Value, v interface{}) error { switch data := v.(type) { case **time.Time: - if data != nil { + if data != nil && *data != nil { field.ReflectValueOf(ctx, value).Set(reflect.ValueOf(*data)) } case time.Time: @@ -882,14 +882,12 @@ func (field *Field) setupValuerAndSetter() { reflectV := reflect.ValueOf(v) if !reflectV.IsValid() { field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem()) + } else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() { + return } else if reflectV.Type().AssignableTo(field.FieldType) { field.ReflectValueOf(ctx, value).Set(reflectV) } else if reflectV.Kind() == reflect.Ptr { - if reflectV.IsNil() || !reflectV.IsValid() { - field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem()) - } else { - return field.Set(ctx, value, reflectV.Elem().Interface()) - } + return field.Set(ctx, value, reflectV.Elem().Interface()) } else { fieldValue := field.ReflectValueOf(ctx, value) if fieldValue.IsNil() { @@ -910,14 +908,12 @@ func (field *Field) setupValuerAndSetter() { reflectV := reflect.ValueOf(v) if !reflectV.IsValid() { field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem()) + } else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() { + return } else if reflectV.Type().AssignableTo(field.FieldType) { field.ReflectValueOf(ctx, value).Set(reflectV) } else if reflectV.Kind() == reflect.Ptr { - if reflectV.IsNil() || !reflectV.IsValid() { - field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem()) - } else { - return field.Set(ctx, value, reflectV.Elem().Interface()) - } + return field.Set(ctx, value, reflectV.Elem().Interface()) } else { if valuer, ok := v.(driver.Valuer); ok { v, _ = valuer.Value() |
@aclich You are welcome to create a PR. If you can confirm that this is a bug and provide a unit test, we will review it. |
Your Question
refer to the pr #6219
the test from tests/embedded_struct_test.go works fine.
but after i added one field with data type int, the test will failed.
from
to
the output will show:
Expected to get back a nil Author but got: &{ 0}
Expected answer
the author should also be nil.
More information
I test int & uint types, here is the result
The text was updated successfully, but these errors were encountered: