diff options
| author | Julien Schmidt <google@julienschmidt.com> | 2013-03-25 17:43:30 -0700 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@golang.org> | 2013-03-25 17:43:30 -0700 |
| commit | 5e74f5029b15decee67095532a5c60cb98bbea52 (patch) | |
| tree | 9b121706fee2fb95b5a9390654178fa19fb7ff7f /src/pkg/database/sql | |
| parent | 4529c047b852772eb380499926c1c4e1c42da625 (diff) | |
| download | go-5e74f5029b15decee67095532a5c60cb98bbea52.tar.xz | |
database/sql: optimized []byte copy + []byte(nil) -> *interface fix
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
Diffstat (limited to 'src/pkg/database/sql')
| -rw-r--r-- | src/pkg/database/sql/convert.go | 22 | ||||
| -rw-r--r-- | src/pkg/database/sql/convert_test.go | 3 | ||||
| -rw-r--r-- | src/pkg/database/sql/sql.go | 18 |
3 files changed, 20 insertions, 23 deletions
diff --git a/src/pkg/database/sql/convert.go b/src/pkg/database/sql/convert.go index 5530a5d905..c04adde1fc 100644 --- a/src/pkg/database/sql/convert.go +++ b/src/pkg/database/sql/convert.go @@ -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: diff --git a/src/pkg/database/sql/convert_test.go b/src/pkg/database/sql/convert_test.go index 6aedeb0a46..950e24fc3a 100644 --- a/src/pkg/database/sql/convert_test.go +++ b/src/pkg/database/sql/convert_test.go @@ -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") } } diff --git a/src/pkg/database/sql/sql.go b/src/pkg/database/sql/sql.go index 236e2c095d..d89aa59792 100644 --- a/src/pkg/database/sql/sql.go +++ b/src/pkg/database/sql/sql.go @@ -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 } |
