summaryrefslogtreecommitdiff
path: root/libgo/go/database
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-09-06 18:12:46 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-09-06 18:12:46 +0000
commitaa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13 (patch)
tree7e63b06d1eec92beec6997c9d3ab47a5d6a835be /libgo/go/database
parent920ea3b8ba3164b61ac9490dfdfceb6936eda6dd (diff)
downloadgcc-aa8901e9bb0399d2c16f988ba2fe46eb0c0c5d13.tar.gz
libgo: update to Go 1.13beta1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/193497 From-SVN: r275473
Diffstat (limited to 'libgo/go/database')
-rw-r--r--libgo/go/database/sql/convert.go60
-rw-r--r--libgo/go/database/sql/convert_test.go114
-rw-r--r--libgo/go/database/sql/driver/driver.go2
-rw-r--r--libgo/go/database/sql/driver/types.go17
-rw-r--r--libgo/go/database/sql/driver/types_test.go14
-rw-r--r--libgo/go/database/sql/fakedb_test.go8
-rw-r--r--libgo/go/database/sql/sql.go89
-rw-r--r--libgo/go/database/sql/sql_test.go90
8 files changed, 377 insertions, 17 deletions
diff --git a/libgo/go/database/sql/convert.go b/libgo/go/database/sql/convert.go
index c450d987a46..4c056a1edad 100644
--- a/libgo/go/database/sql/convert.go
+++ b/libgo/go/database/sql/convert.go
@@ -98,10 +98,12 @@ func defaultCheckNamedValue(nv *driver.NamedValue) (err error) {
return err
}
-// driverArgs converts arguments from callers of Stmt.Exec and
+// driverArgsConnLocked converts arguments from callers of Stmt.Exec and
// Stmt.Query into driver Values.
//
// The statement ds may be nil, if no statement is available.
+//
+// ci must be locked.
func driverArgsConnLocked(ci driver.Conn, ds *driverStmt, args []interface{}) ([]driver.NamedValue, error) {
nvargs := make([]driver.NamedValue, len(args))
@@ -286,6 +288,11 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
*d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
return nil
}
+ case decimalDecompose:
+ switch d := dest.(type) {
+ case decimalCompose:
+ return d.Compose(s.Decompose(nil))
+ }
case nil:
switch d := dest.(type) {
case *interface{}:
@@ -420,6 +427,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
dv.Set(reflect.New(dv.Type().Elem()))
return convertAssignRows(dv.Interface(), src, rows)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
s := asString(src)
i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
if err != nil {
@@ -429,6 +439,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
dv.SetInt(i64)
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
s := asString(src)
u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
if err != nil {
@@ -438,6 +451,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
dv.SetUint(u64)
return nil
case reflect.Float32, reflect.Float64:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
s := asString(src)
f64, err := strconv.ParseFloat(s, dv.Type().Bits())
if err != nil {
@@ -447,6 +463,9 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
dv.SetFloat(f64)
return nil
case reflect.String:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
switch v := src.(type) {
case string:
dv.SetString(v)
@@ -539,3 +558,42 @@ func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
}
return vr.Value()
}
+
+// decimal composes or decomposes a decimal value to and from individual parts.
+// There are four parts: a boolean negative flag, a form byte with three possible states
+// (finite=0, infinite=1, NaN=2), a base-2 big-endian integer
+// coefficient (also known as a significand) as a []byte, and an int32 exponent.
+// These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent".
+// A zero length coefficient is a zero value.
+// The big-endian integer coefficent stores the most significant byte first (at coefficent[0]).
+// If the form is not finite the coefficient and exponent should be ignored.
+// The negative parameter may be set to true for any form, although implementations are not required
+// to respect the negative parameter in the non-finite form.
+//
+// Implementations may choose to set the negative parameter to true on a zero or NaN value,
+// but implementations that do not differentiate between negative and positive
+// zero or NaN values should ignore the negative parameter without error.
+// If an implementation does not support Infinity it may be converted into a NaN without error.
+// If a value is set that is larger than what is supported by an implementation,
+// an error must be returned.
+// Implementations must return an error if a NaN or Infinity is attempted to be set while neither
+// are supported.
+//
+// NOTE(kardianos): This is an experimental interface. See https://golang.org/issue/30870
+type decimal interface {
+ decimalDecompose
+ decimalCompose
+}
+
+type decimalDecompose interface {
+ // Decompose returns the internal decimal state in parts.
+ // If the provided buf has sufficient capacity, buf may be returned as the coefficient with
+ // the value set and length set as appropriate.
+ Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
+}
+
+type decimalCompose interface {
+ // Compose sets the internal decimal value from parts. If the value cannot be
+ // represented then an error should be returned.
+ Compose(form byte, negative bool, coefficient []byte, exponent int32) error
+}
diff --git a/libgo/go/database/sql/convert_test.go b/libgo/go/database/sql/convert_test.go
index b0aff7b1685..8a82891c253 100644
--- a/libgo/go/database/sql/convert_test.go
+++ b/libgo/go/database/sql/convert_test.go
@@ -439,7 +439,7 @@ func TestDriverArgs(t *testing.T) {
0: {
args: []interface{}{Valuer_V("foo")},
want: []driver.NamedValue{
- driver.NamedValue{
+ {
Ordinal: 1,
Value: "FOO",
},
@@ -448,7 +448,7 @@ func TestDriverArgs(t *testing.T) {
1: {
args: []interface{}{nilValuerVPtr},
want: []driver.NamedValue{
- driver.NamedValue{
+ {
Ordinal: 1,
Value: nil,
},
@@ -457,7 +457,7 @@ func TestDriverArgs(t *testing.T) {
2: {
args: []interface{}{nilValuerPPtr},
want: []driver.NamedValue{
- driver.NamedValue{
+ {
Ordinal: 1,
Value: "nil-to-str",
},
@@ -466,7 +466,7 @@ func TestDriverArgs(t *testing.T) {
3: {
args: []interface{}{"plain-str"},
want: []driver.NamedValue{
- driver.NamedValue{
+ {
Ordinal: 1,
Value: "plain-str",
},
@@ -475,7 +475,7 @@ func TestDriverArgs(t *testing.T) {
4: {
args: []interface{}{nilStrPtr},
want: []driver.NamedValue{
- driver.NamedValue{
+ {
Ordinal: 1,
Value: nil,
},
@@ -494,3 +494,107 @@ func TestDriverArgs(t *testing.T) {
}
}
}
+
+type dec struct {
+ form byte
+ neg bool
+ coefficient [16]byte
+ exponent int32
+}
+
+func (d dec) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) {
+ coef := make([]byte, 16)
+ copy(coef, d.coefficient[:])
+ return d.form, d.neg, coef, d.exponent
+}
+
+func (d *dec) Compose(form byte, negative bool, coefficient []byte, exponent int32) error {
+ switch form {
+ default:
+ return fmt.Errorf("unknown form %d", form)
+ case 1, 2:
+ d.form = form
+ d.neg = negative
+ return nil
+ case 0:
+ }
+ d.form = form
+ d.neg = negative
+ d.exponent = exponent
+
+ // This isn't strictly correct, as the extra bytes could be all zero,
+ // ignore this for this test.
+ if len(coefficient) > 16 {
+ return fmt.Errorf("coefficent too large")
+ }
+ copy(d.coefficient[:], coefficient)
+
+ return nil
+}
+
+type decFinite struct {
+ neg bool
+ coefficient [16]byte
+ exponent int32
+}
+
+func (d decFinite) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) {
+ coef := make([]byte, 16)
+ copy(coef, d.coefficient[:])
+ return 0, d.neg, coef, d.exponent
+}
+
+func (d *decFinite) Compose(form byte, negative bool, coefficient []byte, exponent int32) error {
+ switch form {
+ default:
+ return fmt.Errorf("unknown form %d", form)
+ case 1, 2:
+ return fmt.Errorf("unsupported form %d", form)
+ case 0:
+ }
+ d.neg = negative
+ d.exponent = exponent
+
+ // This isn't strictly correct, as the extra bytes could be all zero,
+ // ignore this for this test.
+ if len(coefficient) > 16 {
+ return fmt.Errorf("coefficent too large")
+ }
+ copy(d.coefficient[:], coefficient)
+
+ return nil
+}
+
+func TestDecimal(t *testing.T) {
+ list := []struct {
+ name string
+ in decimalDecompose
+ out dec
+ err bool
+ }{
+ {name: "same", in: dec{exponent: -6}, out: dec{exponent: -6}},
+
+ // Ensure reflection is not used to assign the value by using different types.
+ {name: "diff", in: decFinite{exponent: -6}, out: dec{exponent: -6}},
+
+ {name: "bad-form", in: dec{form: 200}, err: true},
+ }
+ for _, item := range list {
+ t.Run(item.name, func(t *testing.T) {
+ out := dec{}
+ err := convertAssign(&out, item.in)
+ if item.err {
+ if err == nil {
+ t.Fatalf("unexpected nil error")
+ }
+ return
+ }
+ if err != nil {
+ t.Fatalf("unexpected error: %v", err)
+ }
+ if !reflect.DeepEqual(out, item.out) {
+ t.Fatalf("got %#v want %#v", out, item.out)
+ }
+ })
+ }
+}
diff --git a/libgo/go/database/sql/driver/driver.go b/libgo/go/database/sql/driver/driver.go
index ecc6547bf37..316e7cea375 100644
--- a/libgo/go/database/sql/driver/driver.go
+++ b/libgo/go/database/sql/driver/driver.go
@@ -26,7 +26,7 @@ import (
// time.Time
//
// If the driver supports cursors, a returned Value may also implement the Rows interface
-// in this package. This is used when, for example, when a user selects a cursor
+// in this package. This is used, for example, when a user selects a cursor
// such as "select cursor(select * from my_table) from dual". If the Rows
// from the select is closed, the cursor Rows will also be closed.
type Value interface{}
diff --git a/libgo/go/database/sql/driver/types.go b/libgo/go/database/sql/driver/types.go
index 8b3cb6c8f61..24c3a454836 100644
--- a/libgo/go/database/sql/driver/types.go
+++ b/libgo/go/database/sql/driver/types.go
@@ -38,6 +38,7 @@ type ValueConverter interface {
// themselves to a driver Value.
type Valuer interface {
// Value returns a driver Value.
+ // Value must not panic.
Value() (Value, error)
}
@@ -179,6 +180,8 @@ func IsValue(v interface{}) bool {
switch v.(type) {
case []byte, bool, float64, int64, string, time.Time:
return true
+ case decimalDecompose:
+ return true
}
return false
}
@@ -235,7 +238,8 @@ func (defaultConverter) ConvertValue(v interface{}) (Value, error) {
return v, nil
}
- if vr, ok := v.(Valuer); ok {
+ switch vr := v.(type) {
+ case Valuer:
sv, err := callValuerValue(vr)
if err != nil {
return nil, err
@@ -244,6 +248,10 @@ func (defaultConverter) ConvertValue(v interface{}) (Value, error) {
return nil, fmt.Errorf("non-Value type %T returned from Value", sv)
}
return sv, nil
+
+ // For now, continue to prefer the Valuer interface over the decimal decompose interface.
+ case decimalDecompose:
+ return vr, nil
}
rv := reflect.ValueOf(v)
@@ -280,3 +288,10 @@ func (defaultConverter) ConvertValue(v interface{}) (Value, error) {
}
return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
}
+
+type decimalDecompose interface {
+ // Decompose returns the internal decimal state into parts.
+ // If the provided buf has sufficient capacity, buf may be returned as the coefficient with
+ // the value set and length set as appropriate.
+ Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
+}
diff --git a/libgo/go/database/sql/driver/types_test.go b/libgo/go/database/sql/driver/types_test.go
index 0379bf8892f..4c2996da85f 100644
--- a/libgo/go/database/sql/driver/types_test.go
+++ b/libgo/go/database/sql/driver/types_test.go
@@ -57,6 +57,7 @@ var valueConverterTests = []valueConverterTest{
{DefaultParameterConverter, bs{1}, []byte{1}, ""},
{DefaultParameterConverter, s("a"), "a", ""},
{DefaultParameterConverter, is{1}, nil, "unsupported type driver.is, a slice of int"},
+ {DefaultParameterConverter, dec{exponent: -6}, dec{exponent: -6}, ""},
}
func TestValueConverters(t *testing.T) {
@@ -79,3 +80,16 @@ func TestValueConverters(t *testing.T) {
}
}
}
+
+type dec struct {
+ form byte
+ neg bool
+ coefficient [16]byte
+ exponent int32
+}
+
+func (d dec) Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32) {
+ coef := make([]byte, 16)
+ copy(coef, d.coefficient[:])
+ return d.form, d.neg, coef, d.exponent
+}
diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go
index dcdd264baa8..c0371f3e784 100644
--- a/libgo/go/database/sql/fakedb_test.go
+++ b/libgo/go/database/sql/fakedb_test.go
@@ -1141,6 +1141,8 @@ func converterForType(typ string) driver.ValueConverter {
return driver.Null{Converter: driver.Bool}
case "int32":
return driver.Int32
+ case "nullint32":
+ return driver.Null{Converter: driver.DefaultParameterConverter}
case "string":
return driver.NotNull{Converter: fakeDriverString{}}
case "nullstring":
@@ -1158,7 +1160,9 @@ func converterForType(typ string) driver.ValueConverter {
// TODO(coopernurse): add type-specific converter
return driver.Null{Converter: driver.DefaultParameterConverter}
case "datetime":
- return driver.DefaultParameterConverter
+ return driver.NotNull{Converter: driver.DefaultParameterConverter}
+ case "nulldatetime":
+ return driver.Null{Converter: driver.DefaultParameterConverter}
case "any":
return anyTypeConverter{}
}
@@ -1173,6 +1177,8 @@ func colTypeToReflectType(typ string) reflect.Type {
return reflect.TypeOf(NullBool{})
case "int32":
return reflect.TypeOf(int32(0))
+ case "nullint32":
+ return reflect.TypeOf(NullInt32{})
case "string":
return reflect.TypeOf("")
case "nullstring":
diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go
index 8cdc903c680..5c5b7dc7e97 100644
--- a/libgo/go/database/sql/sql.go
+++ b/libgo/go/database/sql/sql.go
@@ -8,7 +8,7 @@
// The sql package must be used in conjunction with a database driver.
// See https://golang.org/s/sqldrivers for a list of drivers.
//
-// Drivers that do not support context cancelation will not return until
+// Drivers that do not support context cancellation will not return until
// after the query is completed.
//
// For usage examples, see the wiki page at
@@ -234,6 +234,32 @@ func (n NullInt64) Value() (driver.Value, error) {
return n.Int64, nil
}
+// NullInt32 represents an int32 that may be null.
+// NullInt32 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullInt32 struct {
+ Int32 int32
+ Valid bool // Valid is true if Int32 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullInt32) Scan(value interface{}) error {
+ if value == nil {
+ n.Int32, n.Valid = 0, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Int32, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullInt32) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return int64(n.Int32), nil
+}
+
// NullFloat64 represents a float64 that may be null.
// NullFloat64 implements the Scanner interface so
// it can be used as a scan destination, similar to NullString.
@@ -286,6 +312,32 @@ func (n NullBool) Value() (driver.Value, error) {
return n.Bool, nil
}
+// NullTime represents a time.Time that may be null.
+// NullTime implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullTime struct {
+ Time time.Time
+ Valid bool // Valid is true if Time is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullTime) Scan(value interface{}) error {
+ if value == nil {
+ n.Time, n.Valid = time.Time{}, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Time, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullTime) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return n.Time, nil
+}
+
// Scanner is an interface used by Scan.
type Scanner interface {
// Scan assigns a value from a database driver.
@@ -1740,6 +1792,8 @@ type Conn struct {
done int32
}
+// grabConn takes a context to implement stmtConnGrabber
+// but the context is not used.
func (c *Conn) grabConn(context.Context) (*driverConn, releaseConn, error) {
if atomic.LoadInt32(&c.done) != 0 {
return nil, nil, ErrConnDone
@@ -1804,6 +1858,39 @@ func (c *Conn) PrepareContext(ctx context.Context, query string) (*Stmt, error)
return c.db.prepareDC(ctx, dc, release, c, query)
}
+// Raw executes f exposing the underlying driver connection for the
+// duration of f. The driverConn must not be used outside of f.
+//
+// Once f returns and err is nil, the Conn will continue to be usable
+// until Conn.Close is called.
+func (c *Conn) Raw(f func(driverConn interface{}) error) (err error) {
+ var dc *driverConn
+ var release releaseConn
+
+ // grabConn takes a context to implement stmtConnGrabber, but the context is not used.
+ dc, release, err = c.grabConn(nil)
+ if err != nil {
+ return
+ }
+ fPanic := true
+ dc.Mutex.Lock()
+ defer func() {
+ dc.Mutex.Unlock()
+
+ // If f panics fPanic will remain true.
+ // Ensure an error is passed to release so the connection
+ // may be discarded.
+ if fPanic {
+ err = driver.ErrBadConn
+ }
+ release(err)
+ }()
+ err = f(dc.ci)
+ fPanic = false
+
+ return
+}
+
// BeginTx starts a transaction.
//
// The provided context is used until the transaction is committed or rolled back.
diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go
index 64b9dfea5c2..f68cefe43ae 100644
--- a/libgo/go/database/sql/sql_test.go
+++ b/libgo/go/database/sql/sql_test.go
@@ -131,6 +131,7 @@ func TestDriverPanic(t *testing.T) {
}
func exec(t testing.TB, db *DB, query string, args ...interface{}) {
+ t.Helper()
_, err := db.Exec(query, args...)
if err != nil {
t.Fatalf("Exec of %q: %v", query, err)
@@ -1338,6 +1339,54 @@ func TestConnQuery(t *testing.T) {
}
}
+func TestConnRaw(t *testing.T) {
+ db := newTestDB(t, "people")
+ defer closeDB(t, db)
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ conn, err := db.Conn(ctx)
+ if err != nil {
+ t.Fatal(err)
+ }
+ conn.dc.ci.(*fakeConn).skipDirtySession = true
+ defer conn.Close()
+
+ sawFunc := false
+ err = conn.Raw(func(dc interface{}) error {
+ sawFunc = true
+ if _, ok := dc.(*fakeConn); !ok {
+ return fmt.Errorf("got %T want *fakeConn", dc)
+ }
+ return nil
+ })
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !sawFunc {
+ t.Fatal("Raw func not called")
+ }
+
+ func() {
+ defer func() {
+ x := recover()
+ if x == nil {
+ t.Fatal("expected panic")
+ }
+ conn.closemu.Lock()
+ closed := conn.dc == nil
+ conn.closemu.Unlock()
+ if !closed {
+ t.Fatal("expected connection to be closed after panic")
+ }
+ }()
+ err = conn.Raw(func(dc interface{}) error {
+ panic("Conn.Raw panic should return an error")
+ })
+ t.Fatal("expected panic from Raw func")
+ }()
+}
+
func TestCursorFake(t *testing.T) {
db := newTestDB(t, "people")
defer closeDB(t, db)
@@ -1401,7 +1450,7 @@ func TestInvalidNilValues(t *testing.T) {
{
name: "int",
input: &date2,
- expectedError: `sql: Scan error on column index 0, name "bdate": converting driver.Value type <nil> ("<nil>") to a int: invalid syntax`,
+ expectedError: `sql: Scan error on column index 0, name "bdate": converting NULL to int is unsupported`,
},
}
@@ -1671,6 +1720,18 @@ func TestNullInt64Param(t *testing.T) {
nullTestRun(t, spec)
}
+func TestNullInt32Param(t *testing.T) {
+ spec := nullTestSpec{"nullint32", "int32", [6]nullTestRow{
+ {NullInt32{31, true}, 1, NullInt32{31, true}},
+ {NullInt32{-22, false}, 1, NullInt32{0, false}},
+ {22, 1, NullInt32{22, true}},
+ {NullInt32{33, true}, 1, NullInt32{33, true}},
+ {NullInt32{222, false}, 1, NullInt32{0, false}},
+ {0, NullInt32{31, false}, nil},
+ }}
+ nullTestRun(t, spec)
+}
+
func TestNullFloat64Param(t *testing.T) {
spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
@@ -1695,6 +1756,21 @@ func TestNullBoolParam(t *testing.T) {
nullTestRun(t, spec)
}
+func TestNullTimeParam(t *testing.T) {
+ t0 := time.Time{}
+ t1 := time.Date(2000, 1, 1, 8, 9, 10, 11, time.UTC)
+ t2 := time.Date(2010, 1, 1, 8, 9, 10, 11, time.UTC)
+ spec := nullTestSpec{"nulldatetime", "datetime", [6]nullTestRow{
+ {NullTime{t1, true}, t2, NullTime{t1, true}},
+ {NullTime{t1, false}, t2, NullTime{t0, false}},
+ {t1, t2, NullTime{t1, true}},
+ {NullTime{t1, true}, t2, NullTime{t1, true}},
+ {NullTime{t1, false}, t2, NullTime{t0, false}},
+ {t2, NullTime{t1, false}, nil},
+ }}
+ nullTestRun(t, spec)
+}
+
func nullTestRun(t *testing.T, spec nullTestSpec) {
db := newTestDB(t, "")
defer closeDB(t, db)
@@ -3530,7 +3606,7 @@ type nvcConn struct {
skipNamedValueCheck bool
}
-type decimal struct {
+type decimalInt struct {
value int
}
@@ -3554,7 +3630,7 @@ func (c *nvcConn) CheckNamedValue(nv *driver.NamedValue) error {
nv.Value = "OUT:*string"
}
return nil
- case decimal, []int64:
+ case decimalInt, []int64:
return nil
case doNotInclude:
return driver.ErrRemoveArgument
@@ -3583,13 +3659,13 @@ func TestNamedValueChecker(t *testing.T) {
}
o1 := ""
- _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A,str1=?,out1=?O1,array1=?", Named("A", decimal{123}), "hello", Named("O1", Out{Dest: &o1}), []int64{42, 128, 707}, doNotInclude{})
+ _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A,str1=?,out1=?O1,array1=?", Named("A", decimalInt{123}), "hello", Named("O1", Out{Dest: &o1}), []int64{42, 128, 707}, doNotInclude{})
if err != nil {
t.Fatal("exec insert", err)
}
var (
str1 string
- dec1 decimal
+ dec1 decimalInt
arr1 []int64
)
err = db.QueryRowContext(ctx, "SELECT|keys|dec1,str1,array1|").Scan(&dec1, &str1, &arr1)
@@ -3599,7 +3675,7 @@ func TestNamedValueChecker(t *testing.T) {
list := []struct{ got, want interface{} }{
{o1, "from-server"},
- {dec1, decimal{123}},
+ {dec1, decimalInt{123}},
{str1, "hello"},
{arr1, []int64{42, 128, 707}},
}
@@ -3632,7 +3708,7 @@ func TestNamedValueCheckerSkip(t *testing.T) {
t.Fatal("exec create", err)
}
- _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A", Named("A", decimal{123}))
+ _, err = db.ExecContext(ctx, "INSERT|keys|dec1=?A", Named("A", decimalInt{123}))
if err == nil {
t.Fatalf("expected error with bad argument, got %v", err)
}