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

Call to sqlx.In on driver.Value with nil value panics #952

Open
moxar opened this issue Oct 18, 2024 · 0 comments
Open

Call to sqlx.In on driver.Value with nil value panics #952

moxar opened this issue Oct 18, 2024 · 0 comments

Comments

@moxar
Copy link

moxar commented Oct 18, 2024

Hi,

I didn't know how to contribute, so I opened the issue and the associated PR: #953

Description

When calling sqlx.In on a pointer to var that implements driver.Valuer interface, the function panics for nil pointer dereference.

Current behaviour

type Valuer struct {
    Val string
}
 
func (v Valuer) Value() (driver.Value, error) {
    return v.Val, nil
}

query := `SELECT * FROM foo WHERE x = ? or y IN (?)`
        _, _, err := In(query,
            (*Valuer)(nil), // a non-inited pointer to valuer
            []interface{}{
                "a",                 // a usual value
                nil,                 // a nil value
                Valuer{Val: "foo"},  // a Valuer
                &Valuer{Val: "foo"}, // a pointer to valuer
                (*Valuer)(nil),      // a non-inited pointer to valuer
            },
        )
--- FAIL: TestIn (0.00s)
    --- FAIL: TestIn/with_nil_driver.Valuer (0.00s)
panic: value method github.com/jmoiron/sqlx.Valuer.Value called using nil *Valuer pointer [recovered]
        panic: value method github.com/jmoiron/sqlx.Valuer.Value called using nil *Valuer pointer

goroutine 13 [running]:
testing.tRunner.func1.2({0x8452a0, 0xc0001d5320})
        /usr/local/go/src/testing/testing.go:1632 +0x230
testing.tRunner.func1()
        /usr/local/go/src/testing/testing.go:1635 +0x35e
panic({0x8452a0?, 0xc0001d5320?})
        /usr/local/go/src/runtime/panic.go:785 +0x132
github.com/jmoiron/sqlx.(*Valuer).Value(0xb48390?)
        <autogenerated>:1 +0x45
github.com/jmoiron/sqlx.In({0x8af3e6, 0x29}, {0xc0000d9f30, 0x2, 0x2})
        /home/athomas/Work/sqlx/bind.go:166 +0x157
github.com/jmoiron/sqlx.TestIn.func1(0xc0000aad00)
        /home/athomas/Work/sqlx/sqlx_test.go:1552 +0x154
testing.tRunner(0xc0000aad00, 0x8d1b60)
        /usr/local/go/src/testing/testing.go:1690 +0xf4
created by testing.(*T).Run in goroutine 12
        /usr/local/go/src/testing/testing.go:1743 +0x390
FAIL    github.com/jmoiron/sqlx 0.006s

expected behaviour

The call should not panic. In stdlib, the resolution of a driver.Valuer returns nil in the special case of a nil value, as decribed in this snippet. I would expect sqlx to behave like stdlib on this matter.

// callValuerValue returns vr.Value(), with one exception:
// If vr.Value is an auto-generated method on a pointer type and the
// pointer is nil, it would panic at runtime in the panicwrap
// method. Treat it like nil instead.
// Issue 8415.
//
// This is so people can implement driver.Value on value types and
// still use nil pointers to those types to mean nil/NULL, just like
// string/*string.
//
// This function is mirrored in the database/sql package.
func callValuerValue(vr Valuer) (v Value, err error) {
	if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Pointer &&
		rv.IsNil() &&
		rv.Type().Elem().Implements(valuerReflectType) {
		return nil, nil
	}
	return vr.Value()
}
--- PASS: TestIn (0.00s)
    --- PASS: TestIn/with_nil_driver.Valuer (0.00s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant