Browse Source

pass unsigned int without converting it to string (#838)

Darren Hoo 6 years ago
parent
commit
d3a0b0fcd7
5 changed files with 24 additions and 14 deletions
  1. 1 0
      AUTHORS
  2. 2 2
      connection_test.go
  3. 16 0
      packets.go
  4. 2 9
      statement.go
  5. 3 3
      statement_test.go

+ 1 - 0
AUTHORS

@@ -35,6 +35,7 @@ Hajime Nakagami <nakagami at gmail.com>
 Hanno Braun <mail at hannobraun.com>
 Henri Yandell <flamefew at gmail.com>
 Hirotaka Yamamoto <ymmt2005 at gmail.com>
+Huyiguang <hyg at webterren.com>
 ICHINOSE Shogo <shogo82148 at gmail.com>
 Ilia Cimpoes <ichimpoesh at gmail.com>
 INADA Naoki <songofacandy at gmail.com>

+ 2 - 2
connection_test.go

@@ -78,8 +78,8 @@ func TestCheckNamedValue(t *testing.T) {
 		t.Fatal("uint64 high-bit not convertible", err)
 	}
 
-	if value.Value != "18446744073709551615" {
-		t.Fatalf("uint64 high-bit not converted, got %#v %T", value.Value, value.Value)
+	if value.Value != ^uint64(0) {
+		t.Fatalf("uint64 high-bit converted, got %#v %T", value.Value, value.Value)
 	}
 }
 

+ 16 - 0
packets.go

@@ -1011,6 +1011,22 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
 					)
 				}
 
+			case uint64:
+				paramTypes[i+i] = byte(fieldTypeLongLong)
+				paramTypes[i+i+1] = 0x80 // type is unsigned
+
+				if cap(paramValues)-len(paramValues)-8 >= 0 {
+					paramValues = paramValues[:len(paramValues)+8]
+					binary.LittleEndian.PutUint64(
+						paramValues[len(paramValues)-8:],
+						uint64(v),
+					)
+				} else {
+					paramValues = append(paramValues,
+						uint64ToBytes(uint64(v))...,
+					)
+				}
+
 			case float64:
 				paramTypes[i+i] = byte(fieldTypeDouble)
 				paramTypes[i+i+1] = 0x00

+ 2 - 9
statement.go

@@ -13,7 +13,6 @@ import (
 	"fmt"
 	"io"
 	"reflect"
-	"strconv"
 )
 
 type mysqlStmt struct {
@@ -164,14 +163,8 @@ func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
 		}
 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 		return rv.Int(), nil
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
-		return int64(rv.Uint()), nil
-	case reflect.Uint64:
-		u64 := rv.Uint()
-		if u64 >= 1<<63 {
-			return strconv.FormatUint(u64, 10), nil
-		}
-		return int64(u64), nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return rv.Uint(), nil
 	case reflect.Float32, reflect.Float64:
 		return rv.Float(), nil
 	case reflect.Bool:

+ 3 - 3
statement_test.go

@@ -110,7 +110,7 @@ func TestConvertUnsignedIntegers(t *testing.T) {
 			t.Fatalf("%T type not convertible %s", value, err)
 		}
 
-		if output != int64(42) {
+		if output != uint64(42) {
 			t.Fatalf("%T type not converted, got %#v %T", value, output, output)
 		}
 	}
@@ -120,7 +120,7 @@ func TestConvertUnsignedIntegers(t *testing.T) {
 		t.Fatal("uint64 high-bit not convertible", err)
 	}
 
-	if output != "18446744073709551615" {
-		t.Fatalf("uint64 high-bit not converted, got %#v %T", output, output)
+	if output != ^uint64(0) {
+		t.Fatalf("uint64 high-bit converted, got %#v %T", output, output)
 	}
 }