]> Cypherpunks repositories - gostls13.git/commitdiff
database/sql: optimized []byte copy + []byte(nil) -> *interface fix
authorJulien Schmidt <google@julienschmidt.com>
Tue, 26 Mar 2013 00:43:30 +0000 (17:43 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 26 Mar 2013 00:43:30 +0000 (17:43 -0700)
Make the copy directly in the convert switch instead of an extra loop.
Also stops converting nil-[]byte to zero-[]byte when assigning to *interface

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/7962044

src/pkg/database/sql/convert.go
src/pkg/database/sql/convert_test.go
src/pkg/database/sql/sql.go

index 5530a5d90578b597f727f1c8c0a073a0d475be62..c04adde1fc1603dafc35d4cd04696223555b6aa8 100644 (file)
@@ -112,15 +112,13 @@ func convertAssign(dest, src interface{}) error {
                        if d == nil {
                                return errNilPtr
                        }
-                       bcopy := make([]byte, len(s))
-                       copy(bcopy, s)
-                       *d = bcopy
+                       *d = cloneBytes(s)
                        return nil
                case *[]byte:
                        if d == nil {
                                return errNilPtr
                        }
-                       *d = s
+                       *d = cloneBytes(s)
                        return nil
                case *RawBytes:
                        if d == nil {
@@ -131,6 +129,12 @@ func convertAssign(dest, src interface{}) error {
                }
        case nil:
                switch d := dest.(type) {
+               case *interface{}:
+                       if d == nil {
+                               return errNilPtr
+                       }
+                       *d = nil
+                       return nil
                case *[]byte:
                        if d == nil {
                                return errNilPtr
@@ -250,6 +254,16 @@ func convertAssign(dest, src interface{}) error {
        return fmt.Errorf("unsupported driver -> Scan pair: %T -> %T", src, dest)
 }
 
+func cloneBytes(b []byte) []byte {
+       if b == nil {
+               return nil
+       } else {
+               c := make([]byte, len(b))
+               copy(c, b)
+               return c
+       }
+}
+
 func asString(src interface{}) string {
        switch v := src.(type) {
        case string:
index 6aedeb0a4608968e128d3bfa3b861ae1a71fbce1..950e24fc3a8e65bec86af25b7fcefea0458bda64 100644 (file)
@@ -143,6 +143,7 @@ var conversionTests = []conversionTest{
        {s: []byte("byteslice"), d: &scaniface, wantiface: []byte("byteslice")},
        {s: true, d: &scaniface, wantiface: true},
        {s: nil, d: &scaniface},
+       {s: []byte(nil), d: &scaniface, wantiface: []byte(nil)},
 }
 
 func intPtrValue(intptr interface{}) interface{} {
@@ -221,7 +222,7 @@ func TestConversions(t *testing.T) {
                        }
                        if srcBytes, ok := ct.s.([]byte); ok {
                                dstBytes := (*ifptr).([]byte)
-                               if &dstBytes[0] == &srcBytes[0] {
+                               if len(srcBytes) > 0 && &dstBytes[0] == &srcBytes[0] {
                                        errf("copy into interface{} didn't copy []byte data")
                                }
                        }
index 236e2c095defb4056b8ac2b2e236f12d6dfccfdf..d89aa5979277e9e7edd3982316de0fae2baf30b5 100644 (file)
@@ -1301,24 +1301,6 @@ func (rs *Rows) Scan(dest ...interface{}) error {
                        return fmt.Errorf("sql: Scan error on column index %d: %v", i, err)
                }
        }
-       for _, dp := range dest {
-               b, ok := dp.(*[]byte)
-               if !ok {
-                       continue
-               }
-               if *b == nil {
-                       // If the []byte is now nil (for a NULL value),
-                       // don't fall through to below which would
-                       // turn it into a non-nil 0-length byte slice
-                       continue
-               }
-               if _, ok = dp.(*RawBytes); ok {
-                       continue
-               }
-               clone := make([]byte, len(*b))
-               copy(clone, *b)
-               *b = clone
-       }
        return nil
 }