Hi there,
We've been using structs for returning fields with sql.NullString which has worked fine, however when using a struct that has an sql.NullString to insert into our database we get a panic:
panic: reflect: call of reflect.Value.Type on zero Value
It seems to be hitting the In function here:
v := reflect.ValueOf(arg)
t := reflectx.Deref(v.Type())
Thanks!
If you're using a pointer, don't - it should be a value.
Thanks! We are using the value itself, not a pointer. The struct looks like:
insert := struct {
ID sql.NullString `db:"id"`
}
and the value:
if in.GetId() != "" {
insert.ID = sql.NullString{Valid: true, String: in.GetId()}
}
This works only if the value is not null - if it is then we get the panic.
Strange, this definitely works here. Make sure you're using tip and provide a stack trace.
By the way, it's intentional that fields mismatch? One is ID, one is Name.
I'll create a repro to test on - and oops yeah it's ID - I've edited now.
Got a reproduction ready: https://github.com/sadief/sql_nullstring_repro
The problem seems to be this:
When calling sqlx.In on a query where one of the arguments is either a nil pointer or sql.NullString{Valid: false}, it hits the reflect panic.
For example, with this query:
update things
set parent_id=:pid, name=:name
where value in (:values)
And a struct like so:
struct {
ID *uuid.UUID `db:"id"`
ParentId *uuid.UUID `db:"pid"`
Name sql.NullString `db:"name"`
Values []string `db:"values"`
}
You can't pass in the zero value for Name or a nil UUID for ParentId -- even thought nulling either of those two fields might be what you want to do.
I even tried using sql.NullString{Valid: false, String: "-"} but it still fails -- it looks like when it hits bind.go:122, what gets passed into reflect.ValueOf is nil, so when v.Type() is called it panics.
Most helpful comment
Thanks! We are using the value itself, not a pointer. The struct looks like:
and the value:
This works only if the value is not null - if it is then we get the panic.