@@ -127,28 +127,30 @@ impl TryFrom<&'_ BigDecimal> for PgNumeric {
127
127
}
128
128
129
129
Ok ( PgNumeric :: Number {
130
- sign : match sign {
131
- Sign :: Plus | Sign :: NoSign => PgNumericSign :: Positive ,
132
- Sign :: Minus => PgNumericSign :: Negative ,
133
- } ,
130
+ sign : sign_to_pg ( sign) ,
134
131
scale,
135
132
weight,
136
133
digits,
137
134
} )
138
135
}
139
136
}
140
137
138
+ #[ doc=include_str ! ( "bigdecimal-range.md" ) ]
141
139
impl Encode < ' _ , Postgres > for BigDecimal {
142
140
fn encode_by_ref ( & self , buf : & mut PgArgumentBuffer ) -> IsNull {
143
- use std:: str:: FromStr ;
144
141
// If the argument is too big, then we replace it with a less big argument.
145
142
// This less big argument is already outside the range of allowed PostgreSQL DECIMAL, which
146
143
// means that PostgreSQL will return the 22P03 error kind upon receiving it. This is the
147
144
// expected error, and the user should be ready to handle it anyway.
148
145
PgNumeric :: try_from ( self )
149
146
. unwrap_or_else ( |_| {
150
- PgNumeric :: try_from ( & BigDecimal :: from_str ( & format ! ( "{:030000}" , 0 ) ) . unwrap ( ) )
151
- . unwrap ( )
147
+ PgNumeric :: Number {
148
+ digits : vec ! [ 1 ] ,
149
+ // This is larger than the maximum allowed value, so Postgres should return an error.
150
+ scale : 0x4000 ,
151
+ weight : 0 ,
152
+ sign : sign_to_pg ( self . sign ( ) ) ,
153
+ }
152
154
} )
153
155
. encode ( buf) ;
154
156
@@ -162,6 +164,9 @@ impl Encode<'_, Postgres> for BigDecimal {
162
164
}
163
165
}
164
166
167
+ /// ### Note: `NaN`
168
+ /// `BigDecimal` has a greater range than `NUMERIC` (see the corresponding `Encode` impl for details)
169
+ /// but cannot represent `NaN`, so decoding may return an error.
165
170
impl Decode < ' _ , Postgres > for BigDecimal {
166
171
fn decode ( value : PgValueRef < ' _ > ) -> Result < Self , BoxDynError > {
167
172
match value. format ( ) {
@@ -171,6 +176,13 @@ impl Decode<'_, Postgres> for BigDecimal {
171
176
}
172
177
}
173
178
179
+ fn sign_to_pg ( sign : Sign ) -> PgNumericSign {
180
+ match sign {
181
+ Sign :: Plus | Sign :: NoSign => PgNumericSign :: Positive ,
182
+ Sign :: Minus => PgNumericSign :: Negative ,
183
+ }
184
+ }
185
+
174
186
#[ cfg( test) ]
175
187
mod bigdecimal_to_pgnumeric {
176
188
use super :: { BigDecimal , PgNumeric , PgNumericSign } ;
0 commit comments