Skip to content

Commit 0cc29e9

Browse files
committed
Merge pull request go-sql-driver#332 from arnehormann/uint64params
support uint64 parameters with high bit set
2 parents 7ff0b8c + b2cd472 commit 0cc29e9

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

driver_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,49 @@ func TestNULL(t *testing.T) {
780780
})
781781
}
782782

783+
func TestUint64(t *testing.T) {
784+
const (
785+
u0 = uint64(0)
786+
uall = ^u0
787+
uhigh = uall >> 1
788+
utop = ^uhigh
789+
s0 = int64(0)
790+
sall = ^s0
791+
shigh = int64(uhigh)
792+
stop = ^shigh
793+
)
794+
runTests(t, dsn, func(dbt *DBTest) {
795+
stmt, err := dbt.db.Prepare(`SELECT ?, ?, ? ,?, ?, ?, ?, ?`)
796+
if err != nil {
797+
dbt.Fatal(err)
798+
}
799+
defer stmt.Close()
800+
row := stmt.QueryRow(
801+
u0, uhigh, utop, uall,
802+
s0, shigh, stop, sall,
803+
)
804+
805+
var ua, ub, uc, ud uint64
806+
var sa, sb, sc, sd int64
807+
808+
err = row.Scan(&ua, &ub, &uc, &ud, &sa, &sb, &sc, &sd)
809+
if err != nil {
810+
dbt.Fatal(err)
811+
}
812+
switch {
813+
case ua != u0,
814+
ub != uhigh,
815+
uc != utop,
816+
ud != uall,
817+
sa != s0,
818+
sb != shigh,
819+
sc != stop,
820+
sd != sall:
821+
dbt.Fatal("Unexpected result value")
822+
}
823+
})
824+
}
825+
783826
func TestLongData(t *testing.T) {
784827
runTests(t, dsn, func(dbt *DBTest) {
785828
var maxAllowedPacketSize int

statement.go

+37
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ package mysql
1010

1111
import (
1212
"database/sql/driver"
13+
"fmt"
14+
"reflect"
1315
)
1416

1517
type mysqlStmt struct {
@@ -34,6 +36,10 @@ func (stmt *mysqlStmt) NumInput() int {
3436
return stmt.paramCount
3537
}
3638

39+
func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
40+
return converter{}
41+
}
42+
3743
func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
3844
if stmt.mc.netConn == nil {
3945
errLog.Print(ErrInvalidConn)
@@ -110,3 +116,34 @@ func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
110116

111117
return rows, err
112118
}
119+
120+
type converter struct{}
121+
122+
func (converter) ConvertValue(v interface{}) (driver.Value, error) {
123+
if driver.IsValue(v) {
124+
return v, nil
125+
}
126+
127+
rv := reflect.ValueOf(v)
128+
switch rv.Kind() {
129+
case reflect.Ptr:
130+
// indirect pointers
131+
if rv.IsNil() {
132+
return nil, nil
133+
}
134+
return driver.DefaultParameterConverter.ConvertValue(rv.Elem().Interface())
135+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
136+
return rv.Int(), nil
137+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
138+
return int64(rv.Uint()), nil
139+
case reflect.Uint64:
140+
u64 := rv.Uint()
141+
if u64 >= 1<<63 {
142+
return fmt.Sprintf("%d", u64), nil
143+
}
144+
return int64(u64), nil
145+
case reflect.Float32, reflect.Float64:
146+
return rv.Float(), nil
147+
}
148+
return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
149+
}

0 commit comments

Comments
 (0)