]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: update the conversion errors to be clearer
authorDaniel Theophanes <kardianos@gmail.com>
Mon, 17 Oct 2016 16:28:06 +0000 (09:28 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Fri, 21 Oct 2016 08:31:15 +0000 (08:31 +0000)
There was some ambiguity over which argument was referred to when
a conversion error was returned. Now refer to the argument by
either explicit ordinal position or name if present.

Fixes #15676

Change-Id: Id933196b7e648baa664f4121fa3fb1b07b3c4880
Reviewed-on: https://go-review.googlesource.com/31262
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 594a816966e53701664a68a52444c40e383a7203..44695b67a616524add6d205a9e51c2da1c8fd1b9 100644 (file)
@@ -17,6 +17,13 @@ import (
 
 var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
 
+func describeNamedValue(nv *driver.NamedValue) string {
+       if len(nv.Name) == 0 {
+               return fmt.Sprintf("$%d", nv.Ordinal)
+       }
+       return fmt.Sprintf("with name %q", nv.Name)
+}
+
 // driverArgs converts arguments from callers of Stmt.Exec and
 // Stmt.Query into driver Values.
 //
@@ -33,15 +40,16 @@ func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error)
        if !ok {
                for n, arg := range args {
                        var err error
-                       nvargs[n].Ordinal = n + 1
+                       nv := &nvargs[n]
+                       nv.Ordinal = n + 1
                        if np, ok := arg.(NamedParam); ok {
                                arg = np.Value
                                nvargs[n].Name = np.Name
                        }
-                       nvargs[n].Value, err = driver.DefaultParameterConverter.ConvertValue(arg)
+                       nv.Value, err = driver.DefaultParameterConverter.ConvertValue(arg)
 
                        if err != nil {
-                               return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err)
+                               return nil, fmt.Errorf("sql: converting Exec argument %s type: %v", describeNamedValue(nv), err)
                        }
                }
                return nvargs, nil
@@ -49,10 +57,11 @@ func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error)
 
        // Let the Stmt convert its own arguments.
        for n, arg := range args {
-               nvargs[n].Ordinal = n + 1
+               nv := &nvargs[n]
+               nv.Ordinal = n + 1
                if np, ok := arg.(NamedParam); ok {
                        arg = np.Value
-                       nvargs[n].Name = np.Name
+                       nv.Name = np.Name
                }
                // First, see if the value itself knows how to convert
                // itself to a driver type. For example, a NullString
@@ -60,10 +69,10 @@ func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error)
                if vr, ok := arg.(driver.Valuer); ok {
                        sv, err := callValuerValue(vr)
                        if err != nil {
-                               return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err)
+                               return nil, fmt.Errorf("sql: argument %s from Value: %v", describeNamedValue(nv), err)
                        }
                        if !driver.IsValue(sv) {
-                               return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv)
+                               return nil, fmt.Errorf("sql: argument %s: non-subset type %T returned from Value", describeNamedValue(nv), sv)
                        }
                        arg = sv
                }
@@ -77,14 +86,14 @@ func driverArgs(ds *driverStmt, args []interface{}) ([]driver.NamedValue, error)
                // same error.
                var err error
                ds.Lock()
-               nvargs[n].Value, err = cc.ColumnConverter(n).ConvertValue(arg)
+               nv.Value, err = cc.ColumnConverter(n).ConvertValue(arg)
                ds.Unlock()
                if err != nil {
-                       return nil, fmt.Errorf("sql: converting argument #%d's type: %v", n, err)
+                       return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err)
                }
-               if !driver.IsValue(nvargs[n].Value) {
-                       return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T",
-                               arg, nvargs[n].Value)
+               if !driver.IsValue(nv.Value) {
+                       return nil, fmt.Errorf("sql: for argument %s, driver ColumnConverter error converted %T to unsupported type %T",
+                               describeNamedValue(nv), arg, nv.Value)
                }
        }
 
index f4b887ca963735695c1f07287f0e21f1ef490355..228a3f25804f89df2ae54fdf3192406cba120bde 100644 (file)
@@ -745,8 +745,8 @@ func TestExec(t *testing.T) {
                {[]interface{}{7, 9}, ""},
 
                // Invalid conversions:
-               {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument #1's type: sql/driver: value 4294967295 overflows int32"},
-               {[]interface{}{"Brad", "strconv fail"}, "sql: converting argument #1's type: sql/driver: value \"strconv fail\" can't be converted to int32"},
+               {[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument $2 type: sql/driver: value 4294967295 overflows int32"},
+               {[]interface{}{"Brad", "strconv fail"}, `sql: converting argument $2 type: sql/driver: value "strconv fail" can't be converted to int32`},
 
                // Wrong number of args:
                {[]interface{}{}, "sql: expected 2 arguments, got 0"},