Skip to content

Commit

Permalink
sqlx: 解决 RawBytes 共享内存的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
flycash committed Oct 1, 2023
1 parent c5bfbd4 commit 261de80
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion sqlx/scanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package sqlx

import (
"bytes"
"database/sql"
"errors"
"fmt"
"reflect"
Expand All @@ -24,6 +26,7 @@ var (
ErrNoMoreRows = errors.New("ekit: 已读取完")
errInvalidArgument = errors.New("ekit: 参数非法")
_ Scanner = &sqlRowsScanner{}
bytesType = reflect.TypeOf([]byte(""))
)

// Scanner 用于简化sql.Rows包中的Scan操作
Expand Down Expand Up @@ -54,6 +57,7 @@ func NewSQLRowsScanner(r Rows) (Scanner, error) {
for i, columnType := range columnTypes {
typ := columnType.ScanType()
for typ.Kind() == reflect.Pointer {
// 兼容 sqlite,理论上来说其他 driver 不应该命中这个分支

Check warning on line 60 in sqlx/scanner.go

View check run for this annotation

Codecov / codecov/patch

sqlx/scanner.go#L60

Added line #L60 was not covered by tests
typ = typ.Elem()
}
columnValuePointers[i] = reflect.New(typ).Interface()
Expand Down Expand Up @@ -84,7 +88,12 @@ func (s *sqlRowsScanner) Scan() ([]any, error) {
func (s *sqlRowsScanner) columnValues() []any {
values := make([]any, len(s.columnValuePointers))
for i := 0; i < len(s.columnValuePointers); i++ {
values[i] = reflect.ValueOf(s.columnValuePointers[i]).Elem().Interface()
val := reflect.ValueOf(s.columnValuePointers[i]).Elem().Interface()
// sql.RawBytes 存在内存共享的问题,所以需要执行复制
if rawBytes, ok := val.(sql.RawBytes); ok {
val = sql.RawBytes(bytes.Clone(rawBytes))
}

Check warning on line 95 in sqlx/scanner.go

View check run for this annotation

Codecov / codecov/patch

sqlx/scanner.go#L94-L95

Added lines #L94 - L95 were not covered by tests
values[i] = val
}
return values
}
Expand Down

0 comments on commit 261de80

Please sign in to comment.