You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a type (Geometry4326) that implements the Scanner and Valuer interfaces, and wraps an underlying C type that performs geometric operations:
// Geom is an example GORM ModeltypeGeomstruct{
IDintAOI*Geometry4326`gorm:"type:geometry(POINT,4326)"`
}
// Geometry4326 wraps the geos Geometry struct and implements Scanner and ValuertypeGeometry4326struct {
*geos.Geometryvalidbool
}
/* From geom library: */typeGeometrystruct {
g*C.GEOSGeometry
}
Due to an issue described here, reflect panics in go versions after 1.15.4 when attempting to call Value.Interface() on new reflect.Values created with a reflect.Type. Unfortunately, this is what happens in GORM schema/field.go, when it recursively enters the struct and uses reflection to create new instances of the (unexported) fields. This happens when trying to do a form of Get (such as db.First()), causing a panic later on line 234 (gorm v1.21.6) when it tries to do: if _, ok := fieldValue.Interface().(*time.Time); ok {...}
Snippet from field.go:
fieldValue:=reflect.New(field.IndirectFieldType)
// if field is valuer, used its value or first fields as data typevaluer, isValuer:=fieldValue.Interface().(driver.Valuer)
ifisValuer {
if_, ok:=fieldValue.Interface().(GormDataTypeInterface); !ok {
ifv, err:=valuer.Value(); reflect.ValueOf(v).IsValid() &&err==nil {
fieldValue=reflect.ValueOf(v)
}
vargetRealFieldValuefunc(reflect.Value)
getRealFieldValue=func(v reflect.Value) {
rv:=reflect.Indirect(v)
ifrv.Kind() ==reflect.Struct&&!rv.Type().ConvertibleTo(TimeReflectType) {
fori:=0; i<rv.Type().NumField(); i++ {
newFieldType:=rv.Type().Field(i).TypefornewFieldType.Kind() ==reflect.Ptr {
newFieldType=newFieldType.Elem()
}
fieldValue=reflect.New(newFieldType)
ifrv.Type() !=reflect.Indirect(fieldValue).Type() {
getRealFieldValue(fieldValue)
}
iffieldValue.IsValid() {
return
}
forkey, value:=rangeParseTagSetting(field.IndirectFieldType.Field(i).Tag.Get("gorm"), ";") {
if_, ok:=field.TagSettings[key]; !ok {
field.TagSettings[key] =value
}
}
}
}
}
getRealFieldValue(fieldValue)
}
}
The document you expected this should be explained
N/A
Expected answer
This begs the question, why does GORM care what is inside the underlying struct if it implements its own Scanner and Valuer? Why is it trying to create a new instance of an unexported struct field of an underlying library? All it needs to care about is the column and the type, so that it can perform a query, allowing Scan() to actually fill the retrieved data into the struct.
The text was updated successfully, but these errors were encountered:
This issue has been automatically marked as stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days
Your Question
I have a type (
Geometry4326
) that implements theScanner
andValuer
interfaces, and wraps an underlying C type that performs geometric operations:Due to an issue described here, reflect panics in go versions after 1.15.4 when attempting to call
Value.Interface()
on new reflect.Values created with a reflect.Type. Unfortunately, this is what happens in GORMschema/field.go
, when it recursively enters the struct and uses reflection to create new instances of the (unexported) fields. This happens when trying to do a form of Get (such asdb.First()
), causing a panic later on line 234 (gorm v1.21.6) when it tries to do:if _, ok := fieldValue.Interface().(*time.Time); ok {...}
Snippet from
field.go
:The document you expected this should be explained
N/A
Expected answer
This begs the question, why does GORM care what is inside the underlying struct if it implements its own
Scanner
andValuer
? Why is it trying to create a new instance of an unexported struct field of an underlying library? All it needs to care about is the column and the type, so that it can perform a query, allowingScan()
to actually fill the retrieved data into the struct.The text was updated successfully, but these errors were encountered: