diff --git a/pgtype/numeric.go b/pgtype/numeric.go index 2444be017..4dbec7861 100644 --- a/pgtype/numeric.go +++ b/pgtype/numeric.go @@ -119,6 +119,26 @@ func (n Numeric) Int64Value() (Int8, error) { return Int8{Int64: bi.Int64(), Valid: true}, nil } +func (n *Numeric) ScanScientific(src string) error { + if !strings.ContainsAny("eE", src) { + return scanPlanTextAnyToNumericScanner{}.Scan([]byte(src), n) + } + + if bigF, ok := new(big.Float).SetString(string(src)); ok { + smallF, _ := bigF.Float64() + src = strconv.FormatFloat(smallF, 'f', -1, 64) + } + + num, exp, err := parseNumericString(src) + if err != nil { + return err + } + + *n = Numeric{Int: num, Exp: exp, Valid: true} + + return nil +} + func (n *Numeric) toBigInt() (*big.Int, error) { if n.Exp == 0 { return n.Int, nil @@ -759,13 +779,6 @@ func (scanPlanTextAnyToNumericScanner) Scan(src []byte, dst any) error { return scanner.ScanNumeric(Numeric{InfinityModifier: NegativeInfinity, Valid: true}) } - if strings.ContainsAny(string(src), "eE") { - if bigF, ok := new(big.Float).SetString(string(src)); ok { - smallF, _ := bigF.Float64() - src = []byte(strconv.FormatFloat(smallF, 'f', -1, 64)) - } - } - num, exp, err := parseNumericString(string(src)) if err != nil { return err diff --git a/pgtype/numeric_test.go b/pgtype/numeric_test.go index 70d68c184..691cc9794 100644 --- a/pgtype/numeric_test.go +++ b/pgtype/numeric_test.go @@ -283,18 +283,6 @@ func TestNumericUnmarshalJSON(t *testing.T) { src: []byte("1234.56789"), wantErr: false, }, - { - name: "float: 1e10", - want: &pgtype.Numeric{Valid: true, Int: big.NewInt(1), Exp: 10}, - src: []byte("1e10"), - wantErr: false, - }, - { - name: "float: 1.000101231014e10", - want: &pgtype.Numeric{Valid: true, Int: big.NewInt(1000101231014), Exp: -2}, - src: []byte("1.000101231014e10"), - wantErr: false, - }, { name: "invalid value", want: &pgtype.Numeric{},