Skip to content
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

encoding/wkb should support NULL values #92

Open
twpayne opened this issue Aug 30, 2017 · 2 comments
Open

encoding/wkb should support NULL values #92

twpayne opened this issue Aug 30, 2017 · 2 comments

Comments

@twpayne
Copy link
Owner

twpayne commented Aug 30, 2017

See #90 and #91 for discussion and initial code.

@zachcoleman
Copy link

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:

if p.Point == nil {

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.

@zachcoleman
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants