]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: check if src is nil before converting to string
authorDaniel Theophanes <kardianos@gmail.com>
Fri, 26 Apr 2019 18:09:51 +0000 (11:09 -0700)
committerDaniel Theophanes <kardianos@gmail.com>
Fri, 26 Apr 2019 19:59:11 +0000 (19:59 +0000)
A nil src (NULL database value) will result in a "nil" string,
which will never parse correctly in a ParseInt or similar
numeric conversion. The resulting error is confusing. Check
for a nil src prior to converting the value to string
if the resulting string will be parsed after that.

Closes #31274

Change-Id: I90f12cceff00fbbfdd3e343b04fa7e2596390e6d
Reviewed-on: https://go-review.googlesource.com/c/go/+/174177
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/database/sql/convert.go
src/database/sql/sql_test.go

index c450d987a465125db4e858dff1ae48ca05f9ab9c..2149a8e7006f386b0f74191df52eb54161229a89 100644 (file)
@@ -420,6 +420,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
                dv.Set(reflect.New(dv.Type().Elem()))
                return convertAssignRows(dv.Interface(), src, rows)
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+               if src == nil {
+                       return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+               }
                s := asString(src)
                i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
                if err != nil {
@@ -429,6 +432,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
                dv.SetInt(i64)
                return nil
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+               if src == nil {
+                       return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+               }
                s := asString(src)
                u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
                if err != nil {
@@ -438,6 +444,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
                dv.SetUint(u64)
                return nil
        case reflect.Float32, reflect.Float64:
+               if src == nil {
+                       return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+               }
                s := asString(src)
                f64, err := strconv.ParseFloat(s, dv.Type().Bits())
                if err != nil {
@@ -447,6 +456,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
                dv.SetFloat(f64)
                return nil
        case reflect.String:
+               if src == nil {
+                       return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+               }
                switch v := src.(type) {
                case string:
                        dv.SetString(v)
index c07c5d3bd23cee687bd864d5c37ebeee47f82bef..cc30ad3daa9561e9fa3da583ea3d10b986b0dace 100644 (file)
@@ -1401,7 +1401,7 @@ func TestInvalidNilValues(t *testing.T) {
                {
                        name:          "int",
                        input:         &date2,
-                       expectedError: `sql: Scan error on column index 0, name "bdate": converting driver.Value type <nil> ("<nil>") to a int: invalid syntax`,
+                       expectedError: `sql: Scan error on column index 0, name "bdate": converting NULL to int is unsupported`,
                },
        }