Skip to content

Commit b214b19

Browse files
committed
Fix failing test on call to sqlx.In with (driver.Valuer)(nil)
1 parent 22d3b0d commit b214b19

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

bind.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
163163
for i, arg := range args {
164164
if a, ok := arg.(driver.Valuer); ok {
165165
var err error
166-
arg, err = a.Value()
166+
arg, err = callValuerValue(a)
167167
if err != nil {
168168
return "", nil, err
169169
}
@@ -263,3 +263,24 @@ func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interfa
263263

264264
return args
265265
}
266+
267+
// callValuerValue returns vr.Value(), with one exception:
268+
// If vr.Value is an auto-generated method on a pointer type and the
269+
// pointer is nil, it would panic at runtime in the panicwrap
270+
// method. Treat it like nil instead.
271+
// Issue 8415.
272+
//
273+
// This is so people can implement driver.Value on value types and
274+
// still use nil pointers to those types to mean nil/NULL, just like
275+
// string/*string.
276+
//
277+
// This function is copied from database/sql/driver package
278+
// and mirrored in the database/sql package.
279+
func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
280+
if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Pointer &&
281+
rv.IsNil() &&
282+
rv.Type().Elem().Implements(reflect.TypeOf((*driver.Valuer)(nil)).Elem()) {
283+
return nil, nil
284+
}
285+
return vr.Value()
286+
}

0 commit comments

Comments
 (0)