aboutsummaryrefslogtreecommitdiff
path: root/src/database/sql/driver
diff options
context:
space:
mode:
authorDaniel Theophanes <kardianos@gmail.com>2019-04-26 12:49:23 -0700
committerDaniel Theophanes <kardianos@gmail.com>2019-06-13 16:59:01 +0000
commit683ffe09f66f0834baf039deeabe16eec6b09daa (patch)
tree46ca283a2cc566d294ff672b5391279087d7f6e3 /src/database/sql/driver
parentdc63b59630cbc7fe1b039757bac0d6f713dfc26d (diff)
downloadgo-683ffe09f66f0834baf039deeabe16eec6b09daa.tar.xz
database/sql: add support for decimal interface
Add support for scanning decimal types into values. If the dest supports the decimal composer interface and the src supports the decimal decomposer, set the value of the decimal when Scanning. Add support for sending decimal decomposer interface values as parameters. For #30870 Change-Id: Ic5dbf9069df8d56405852b17542a9188d55c2947 Reviewed-on: https://go-review.googlesource.com/c/go/+/174181 Run-TryBot: Daniel Theophanes <kardianos@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/database/sql/driver')
-rw-r--r--src/database/sql/driver/types.go16
-rw-r--r--src/database/sql/driver/types_test.go14
2 files changed, 29 insertions, 1 deletions
diff --git a/src/database/sql/driver/types.go b/src/database/sql/driver/types.go
index 64b41faaa8..24c3a45483 100644
--- a/src/database/sql/driver/types.go
+++ b/src/database/sql/driver/types.go
@@ -180,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
}
@@ -236,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
@@ -245,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)
@@ -281,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/src/database/sql/driver/types_test.go b/src/database/sql/driver/types_test.go
index 0379bf8892..4c2996da85 100644
--- a/src/database/sql/driver/types_test.go
+++ b/src/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
+}