Open twpayne opened 6 years ago
6 years later... but I have run into another flavor of this I'm wondering if the community or @twpayne have an opinion or experience with this.
I just ran into this problem when dealing w/ optional/nullable geometry types and the Value()
implementation null pointer dereferencing.
It happens if you have a data model like so (example in postgres):
...
my_optional_point geometry(POINT, 4326)
...
and an equivalent go model:
type MyRow struct{
...
MyOptionalPoint *ewkb.Point
...
}
So when using a pointer like this the Value
method dereferences this here: https://github.com/twpayne/go-geom/blob/c56c06dcc8693824100b638c85bb3d6026e7a8ef/encoding/ewkb/sql.go#L92
Instead a small check would have to be added additionally such as:
func (p *Point) Value() (driver.Value, error) {
if p == nil{
return nil, nil
}
if p.Point == nil {
return nil, nil
}
return value(p.Point)
}
and shortening it (to leverage short circuit &&):
func (p *Point) Value() (driver.Value, error) {
if p != nil && p.Point != nil {
return value(p.Point)
}
return nil, nil
}
So while allowing the encoding to be nullable the entire pointer is not allowed to be nullable. I'm curious if this should be handled on the user side or the Value
interface side. There is lengthy discussions on this topic.
If anyone else runs into this issue a workaround on the SQL insertion side is something like this:
func DisambiguatePointer(ptr interface{}) interface{} {
if !reflect.ValueOf(ptr).IsNil() {
return ptr
}
return nil
}
...
db.Exec(
context.Background(),
"INSERT INTO my_table ( my_optional_point ) VALUES ( $1 )",
DisambiguatePointer(MyRow.MyOptionalPoint),
)
...
This code will successfully take a nil pointer of a type like *ewkb.Point
and ensure that Value
is not called on it during a SQL insertion or other SQL code.
See #90 and #91 for discussion and initial code.