sqlboiler
sqlboiler copied to clipboard
Call of `reflect.Value.Field` on zero `Value`
What version of SQLBoiler are you using (sqlboiler --version
)?
SQLBoiler v3.7.1
What is your database and version (eg. Postgresql 10)
Postgres 10.6
If this happened at runtime what code produced the issue? (if not applicable leave blank)
var u struct {
User *models.User `boil:",bind"`
}
err = models.Users().Bind(nil, db, &u)
if err != nil {
panic(err)
}
Please provide a relevant database schema so we can replicate your issue (Provided you are comfortable sharing this)
CREATE TABLE "user" (
id SERIAL PRIMARY KEY
);
Further information. What did you do, what did you expect?
I expected the u
variable to be filled but instead I get this panic:
panic: reflect: call of reflect.Value.Field on zero Value
goroutine 1 [running]:
reflect.Value.Field({0x0?, 0x0?, 0xc000143bc0?}, 0x44b9f2?)
/usr/lib/go/src/reflect/value.go:1220 +0xef
github.com/volatiletech/sqlboiler/queries.ptrFromMapping({0x7063e0?, 0xc0000b0de0?, 0x7d7938?}, 0xff0000, 0x1)
/home/elia/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/queries/reflect.go:378 +0x129
github.com/volatiletech/sqlboiler/queries.PtrsFromMapping({0x7063e0?, 0xc0000b0de0?, 0xc0000a0480?}, {0xc0000a3270, 0x1, 0x0?})
/home/elia/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/queries/reflect.go:344 +0x94
github.com/volatiletech/sqlboiler/queries.bind(0x6e5e40?, {0x6e5e40?, 0xc0000b0de0}, {0x7d9360, 0x7063e0}, {0x6ecca0?, 0xc000098e90?}, 0x0)
/home/elia/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/queries/reflect.go:280 +0x62b
github.com/volatiletech/sqlboiler/queries.(*Query).Bind(0xc0000fb600, {0x0, 0x0}, {0x7d7d98?, 0xc00009fee0}, {0x6e5e40, 0xc0000b0de0})
/home/elia/go/pkg/mod/github.com/volatiletech/[email protected]+incompatible/queries/reflect.go:147 +0x147
main.main()
/home/elia/dump/sqlboilertest/main.go:18 +0xfa
exit status 2
The panic is not caused by the if err != nil { panic(err) }
but by the call to .Bind
itself.
When I change the type of the field from *models.User
to models.User
the issue disappears. But I'd like to use a pointer for performance reasons.
As a workaround, you can allocate the field so that the pointer is not nil but points to an zeroed models.User
instead:
u.User = new(models.User)
I'm not exactly sure why this works though.
My best guess is that SQLBoiler uses reflect
to recursively inspect the structure of the bound variable and needs actual non-nil values in order to do so.
This remains an issue when binding to a slice since I can't pre-allocate the pointers without knowing how many rows will be returned.
This is sort of working as intended. If you send in a PR that addresses this, I will review but I will not work on this myself.