Commit d7c0de98 authored by Scott Bell's avatar Scott Bell Committed by Ian Lance Taylor

database/sql: additional underlying types in DefaultValueConverter

The previous documentation purported to convert underlying strings to
[]byte, which it did not do. This adds support for underlying bool,
string, and []byte, which convert directly to their underlying type.

Fixes #15174.

Change-Id: I7fc4e2520577f097a48f39c9ff6c8160fdfb7be4
Reviewed-on: https://go-review.googlesource.com/27812Reviewed-by: 's avatarDaniel Theophanes <kardianos@gmail.com>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
parent 0df762ed
...@@ -198,9 +198,9 @@ func IsScanValue(v interface{}) bool { ...@@ -198,9 +198,9 @@ func IsScanValue(v interface{}) bool {
// Value method is used to return a Value. As a fallback, the provided // Value method is used to return a Value. As a fallback, the provided
// argument's underlying type is used to convert it to a Value: // argument's underlying type is used to convert it to a Value:
// underlying integer types are converted to int64, floats to float64, // underlying integer types are converted to int64, floats to float64,
// and strings to []byte. If the argument is a nil pointer, // bool, string, and []byte to themselves. If the argument is a nil
// ConvertValue returns a nil Value. If the argument is a non-nil // pointer, ConvertValue returns a nil Value. If the argument is a
// pointer, it is dereferenced and ConvertValue is called // non-nil pointer, it is dereferenced and ConvertValue is called
// recursively. Other types are an error. // recursively. Other types are an error.
var DefaultParameterConverter defaultConverter var DefaultParameterConverter defaultConverter
...@@ -267,6 +267,16 @@ func (defaultConverter) ConvertValue(v interface{}) (Value, error) { ...@@ -267,6 +267,16 @@ func (defaultConverter) ConvertValue(v interface{}) (Value, error) {
return int64(u64), nil return int64(u64), nil
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
return rv.Float(), nil return rv.Float(), nil
case reflect.Bool:
return rv.Bool(), nil
case reflect.Slice:
ek := rv.Type().Elem().Kind()
if ek == reflect.Uint8 {
return rv.Bytes(), nil
}
return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek)
case reflect.String:
return rv.String(), nil
} }
return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind()) return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
} }
...@@ -20,6 +20,16 @@ type valueConverterTest struct { ...@@ -20,6 +20,16 @@ type valueConverterTest struct {
var now = time.Now() var now = time.Now()
var answer int64 = 42 var answer int64 = 42
type (
i int64
f float64
b bool
bs []byte
s string
t time.Time
is []int
)
var valueConverterTests = []valueConverterTest{ var valueConverterTests = []valueConverterTest{
{Bool, "true", true, ""}, {Bool, "true", true, ""},
{Bool, "True", true, ""}, {Bool, "True", true, ""},
...@@ -41,6 +51,12 @@ var valueConverterTests = []valueConverterTest{ ...@@ -41,6 +51,12 @@ var valueConverterTests = []valueConverterTest{
{DefaultParameterConverter, (*int64)(nil), nil, ""}, {DefaultParameterConverter, (*int64)(nil), nil, ""},
{DefaultParameterConverter, &answer, answer, ""}, {DefaultParameterConverter, &answer, answer, ""},
{DefaultParameterConverter, &now, now, ""}, {DefaultParameterConverter, &now, now, ""},
{DefaultParameterConverter, i(9), int64(9), ""},
{DefaultParameterConverter, f(0.1), float64(0.1), ""},
{DefaultParameterConverter, b(true), true, ""},
{DefaultParameterConverter, bs{1}, []byte{1}, ""},
{DefaultParameterConverter, s("a"), "a", ""},
{DefaultParameterConverter, is{1}, nil, "unsupported type driver.is, a slice of int"},
} }
func TestValueConverters(t *testing.T) { func TestValueConverters(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment