Sqlx: Inserting a struct with sql.NullString returns panic

Created on 5 Nov 2018  路  6Comments  路  Source: jmoiron/sqlx

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!

Most helpful comment

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.

All 6 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

railsmechanic picture railsmechanic  路  5Comments

hexdigest picture hexdigest  路  4Comments

davidxiao picture davidxiao  路  5Comments

x1unix picture x1unix  路  4Comments

MichaelHipp picture MichaelHipp  路  5Comments