mirror of https://github.com/jackc/pgx.git
parent
53ec52aa17
commit
8cf6721d66
|
@ -109,6 +109,33 @@ func (n Numeric) Float64Value() (Float8, error) {
|
||||||
return Float8{Float64: f, Valid: true}, nil
|
return Float8{Float64: f, Valid: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Numeric) ScanInt64(v Int8) error {
|
||||||
|
if !v.Valid {
|
||||||
|
*n = Numeric{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
*n = Numeric{Int: big.NewInt(v.Int64), Valid: true}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Numeric) Int64Value() (Int8, error) {
|
||||||
|
if !n.Valid {
|
||||||
|
return Int8{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
bi, err := n.toBigInt()
|
||||||
|
if err != nil {
|
||||||
|
return Int8{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bi.IsInt64() {
|
||||||
|
return Int8{}, fmt.Errorf("cannot convert %v to int64", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Int8{Int64: bi.Int64(), Valid: true}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Numeric) toBigInt() (*big.Int, error) {
|
func (n *Numeric) toBigInt() (*big.Int, error) {
|
||||||
if n.Exp == 0 {
|
if n.Exp == 0 {
|
||||||
return n.Int, nil
|
return n.Int, nil
|
||||||
|
@ -450,18 +477,15 @@ func (encodePlanNumericCodecTextFloat64Valuer) Encode(value interface{}, buf []b
|
||||||
}
|
}
|
||||||
|
|
||||||
if math.IsNaN(n.Float64) {
|
if math.IsNaN(n.Float64) {
|
||||||
return encodeNumericBinary(Numeric{NaN: true, Valid: true}, buf)
|
buf = append(buf, "NaN"...)
|
||||||
} else if math.IsInf(n.Float64, 1) {
|
} else if math.IsInf(n.Float64, 1) {
|
||||||
return encodeNumericBinary(Numeric{InfinityModifier: Infinity, Valid: true}, buf)
|
buf = append(buf, "Infinity"...)
|
||||||
} else if math.IsInf(n.Float64, -1) {
|
} else if math.IsInf(n.Float64, -1) {
|
||||||
return encodeNumericBinary(Numeric{InfinityModifier: NegativeInfinity, Valid: true}, buf)
|
buf = append(buf, "-Infinity"...)
|
||||||
|
} else {
|
||||||
|
buf = append(buf, strconv.FormatFloat(n.Float64, 'f', -1, 64)...)
|
||||||
}
|
}
|
||||||
num, exp, err := parseNumericString(strconv.FormatFloat(n.Float64, 'f', -1, 64))
|
return buf, nil
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return encodeNumericText(Numeric{Int: num, Exp: exp, Valid: true}, buf)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type encodePlanNumericCodecTextInt64Valuer struct{}
|
type encodePlanNumericCodecTextInt64Valuer struct{}
|
||||||
|
@ -476,7 +500,8 @@ func (encodePlanNumericCodecTextInt64Valuer) Encode(value interface{}, buf []byt
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return encodeNumericText(Numeric{Int: big.NewInt(n.Int64), Valid: true}, buf)
|
buf = append(buf, strconv.FormatInt(n.Int64, 10)...)
|
||||||
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encodeNumericText(n Numeric, buf []byte) (newBuf []byte, err error) {
|
func encodeNumericText(n Numeric, buf []byte) (newBuf []byte, err error) {
|
||||||
|
@ -495,9 +520,20 @@ func encodeNumericText(n Numeric, buf []byte) (newBuf []byte, err error) {
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = append(buf, n.Int.String()...)
|
digits := n.Int.String()
|
||||||
|
if n.Exp >= 0 {
|
||||||
|
buf = append(buf, digits...)
|
||||||
|
if n.Exp > 0 {
|
||||||
|
for i := int32(0); i < n.Exp; i++ {
|
||||||
|
buf = append(buf, '0')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf = append(buf, digits...)
|
||||||
buf = append(buf, 'e')
|
buf = append(buf, 'e')
|
||||||
buf = append(buf, strconv.FormatInt(int64(n.Exp), 10)...)
|
buf = append(buf, strconv.FormatInt(int64(n.Exp), 10)...)
|
||||||
|
}
|
||||||
|
|
||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,12 @@ func TestNumericCodec(t *testing.T) {
|
||||||
{pgtype.Numeric{}, new(pgtype.Numeric), isExpectedEq(pgtype.Numeric{})},
|
{pgtype.Numeric{}, new(pgtype.Numeric), isExpectedEq(pgtype.Numeric{})},
|
||||||
{nil, new(pgtype.Numeric), isExpectedEq(pgtype.Numeric{})},
|
{nil, new(pgtype.Numeric), isExpectedEq(pgtype.Numeric{})},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, "int8", []pgxtest.ValueRoundTripTest{
|
||||||
|
{mustParseNumeric(t, "-1"), new(pgtype.Numeric), isExpectedEqNumeric(mustParseNumeric(t, "-1"))},
|
||||||
|
{mustParseNumeric(t, "0"), new(pgtype.Numeric), isExpectedEqNumeric(mustParseNumeric(t, "0"))},
|
||||||
|
{mustParseNumeric(t, "1"), new(pgtype.Numeric), isExpectedEqNumeric(mustParseNumeric(t, "1"))},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNumericCodecInfinity(t *testing.T) {
|
func TestNumericCodecInfinity(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue