@@ -46,6 +46,10 @@ fn get_decimal_cls(py: Python<'_>) -> PyResult<&Bound<'_, PyType>> {
4646 . map ( |ty| ty. bind ( py) )
4747}
4848
49+ /// Struct for Decimal.
50+ ///
51+ /// It's necessary because we use custom forks and there is
52+ /// no implementation of `ToPyObject` for Decimal.
4953struct InnerDecimal ( Decimal ) ;
5054
5155impl ToPyObject for InnerDecimal {
@@ -90,6 +94,7 @@ pub enum PythonDTO {
9094 PyJson ( Value ) ,
9195 PyMacAddr6 ( MacAddr6 ) ,
9296 PyMacAddr8 ( MacAddr8 ) ,
97+ PyDecimal ( Decimal ) ,
9398 PyCustomType ( Vec < u8 > ) ,
9499}
95100
@@ -126,6 +131,7 @@ impl PythonDTO {
126131 PythonDTO :: PyDateTimeTz ( _) => Ok ( tokio_postgres:: types:: Type :: TIMESTAMPTZ_ARRAY ) ,
127132 PythonDTO :: PyMacAddr6 ( _) => Ok ( tokio_postgres:: types:: Type :: MACADDR_ARRAY ) ,
128133 PythonDTO :: PyMacAddr8 ( _) => Ok ( tokio_postgres:: types:: Type :: MACADDR8_ARRAY ) ,
134+ PythonDTO :: PyDecimal ( _) => Ok ( tokio_postgres:: types:: Type :: NUMERIC_ARRAY ) ,
129135 _ => Err ( RustPSQLDriverError :: PyToRustValueConversionError (
130136 "Can't process array type, your type doesn't have support yet" . into ( ) ,
131137 ) ) ,
@@ -265,6 +271,9 @@ impl ToSql for PythonDTO {
265271 PythonDTO :: PyJsonb ( py_dict) | PythonDTO :: PyJson ( py_dict) => {
266272 <& Value as ToSql >:: to_sql ( & py_dict, ty, out) ?;
267273 }
274+ PythonDTO :: PyDecimal ( py_decimal) => {
275+ <Decimal as ToSql >:: to_sql ( py_decimal, ty, out) ?;
276+ }
268277 }
269278 if return_is_null_true {
270279 Ok ( tokio_postgres:: types:: IsNull :: Yes )
@@ -543,7 +552,7 @@ fn postgres_bytes_to_py(
543552 _composite_field_postgres_to_py :: < Option < i32 > > ( type_, buf, is_simple) ?. to_object ( py) ,
544553 ) ,
545554 // Convert BigInt into i64, then into int
546- Type :: INT8 => Ok (
555+ Type :: INT8 | Type :: MONEY => Ok (
547556 _composite_field_postgres_to_py :: < Option < i64 > > ( type_, buf, is_simple) ?. to_object ( py) ,
548557 ) ,
549558 // Convert REAL into f32, then into float
@@ -621,13 +630,12 @@ fn postgres_bytes_to_py(
621630 }
622631 }
623632 Type :: NUMERIC => {
624- if let Some ( money_ ) = _composite_field_postgres_to_py :: < Option < Decimal > > (
633+ if let Some ( numeric_ ) = _composite_field_postgres_to_py :: < Option < Decimal > > (
625634 type_, buf, is_simple,
626635 ) ? {
627- Ok ( InnerDecimal ( money_) . to_object ( py) )
628- } else {
629- Ok ( py. None ( ) . to_object ( py) )
636+ return Ok ( InnerDecimal ( numeric_) . to_object ( py) ) ;
630637 }
638+ Ok ( py. None ( ) . to_object ( py) )
631639 }
632640 // ---------- Array Text Types ----------
633641 Type :: BOOL_ARRAY => Ok ( _composite_field_postgres_to_py :: < Option < Vec < bool > > > (
@@ -651,7 +659,7 @@ fn postgres_bytes_to_py(
651659 ) ?
652660 . to_object ( py) ) ,
653661 // Convert ARRAY of BigInt into Vec<i64>, then into list[int]
654- Type :: INT8_ARRAY => Ok ( _composite_field_postgres_to_py :: < Option < Vec < i64 > > > (
662+ Type :: INT8_ARRAY | Type :: MONEY_ARRAY => Ok ( _composite_field_postgres_to_py :: < Option < Vec < i64 > > > (
655663 type_, buf, is_simple,
656664 ) ?
657665 . to_object ( py) ) ,
@@ -723,6 +731,18 @@ fn postgres_bytes_to_py(
723731 None => Ok ( py. None ( ) . to_object ( py) ) ,
724732 }
725733 }
734+ Type :: NUMERIC_ARRAY => {
735+ if let Some ( numeric_array) = _composite_field_postgres_to_py :: < Option < Vec < Decimal > > > (
736+ type_, buf, is_simple,
737+ ) ? {
738+ let py_list = PyList :: empty_bound ( py) ;
739+ for numeric_ in numeric_array {
740+ py_list. append ( InnerDecimal ( numeric_) . to_object ( py) ) ?;
741+ }
742+ return Ok ( py_list. to_object ( py) )
743+ } ;
744+ Ok ( py. None ( ) . to_object ( py) )
745+ } ,
726746 _ => Err ( RustPSQLDriverError :: RustToPyValueConversionError (
727747 format ! ( "Cannot convert {type_} into Python type, please look at the custom_decoders functionality." )
728748 ) ) ,
0 commit comments