@@ -175,6 +175,20 @@ macro_rules! push_value {
175175 } } ;
176176}
177177
178+ macro_rules! push_big_decimal_value {
179+ ( $row_values: expr, $column: expr, $row: expr, $scale: expr, $array_type: ident) => { {
180+ let array = $column. as_any( ) . downcast_ref:: <array:: $array_type>( ) ;
181+ if let Some ( valid_array) = array {
182+ if valid_array. is_null( $row) {
183+ $row_values. push( Keyword :: Null . into( ) ) ;
184+ continue ;
185+ }
186+ $row_values
187+ . push( BigDecimal :: new( valid_array. value( $row) . into( ) , i64 :: from( * $scale) ) . into( ) ) ;
188+ }
189+ } } ;
190+ }
191+
178192macro_rules! push_list_values {
179193 ( $data_type: expr, $list_array: expr, $row_values: expr, $array_type: ty, $vec_type: ty, $sql_type: expr) => { {
180194 let mut list_values: Vec <$vec_type> = Vec :: new( ) ;
@@ -260,18 +274,14 @@ impl<'a> InsertBuilder<'a> {
260274 DataType :: LargeUtf8 => push_value ! ( row_values, column, row, LargeStringArray ) ,
261275 DataType :: Utf8View => push_value ! ( row_values, column, row, StringViewArray ) ,
262276 DataType :: Boolean => push_value ! ( row_values, column, row, BooleanArray ) ,
277+ DataType :: Decimal32 ( _, scale) => {
278+ push_big_decimal_value ! ( row_values, column, row, scale, Decimal32Array )
279+ }
280+ DataType :: Decimal64 ( _, scale) => {
281+ push_big_decimal_value ! ( row_values, column, row, scale, Decimal64Array )
282+ }
263283 DataType :: Decimal128 ( _, scale) => {
264- let array = column. as_any ( ) . downcast_ref :: < array:: Decimal128Array > ( ) ;
265- if let Some ( valid_array) = array {
266- if valid_array. is_null ( row) {
267- row_values. push ( Keyword :: Null . into ( ) ) ;
268- continue ;
269- }
270- row_values. push (
271- BigDecimal :: new ( valid_array. value ( row) . into ( ) , i64:: from ( * scale) )
272- . into ( ) ,
273- ) ;
274- }
284+ push_big_decimal_value ! ( row_values, column, row, scale, Decimal128Array )
275285 }
276286 DataType :: Decimal256 ( _, scale) => {
277287 let array = column. as_any ( ) . downcast_ref :: < array:: Decimal256Array > ( ) ;
@@ -1321,9 +1331,10 @@ pub(crate) fn map_data_type_to_column_type(data_type: &DataType) -> ColumnType {
13211331 DataType :: Utf8 | DataType :: LargeUtf8 | DataType :: Utf8View => ColumnType :: Text ,
13221332 DataType :: Boolean => ColumnType :: Boolean ,
13231333 #[ allow( clippy:: cast_sign_loss) ] // This is safe because scale will never be negative
1324- DataType :: Decimal128 ( p, s) | DataType :: Decimal256 ( p, s) => {
1325- ColumnType :: Decimal ( Some ( ( u32:: from ( * p) , * s as u32 ) ) )
1326- }
1334+ DataType :: Decimal32 ( p, s)
1335+ | DataType :: Decimal64 ( p, s)
1336+ | DataType :: Decimal128 ( p, s)
1337+ | DataType :: Decimal256 ( p, s) => ColumnType :: Decimal ( Some ( ( u32:: from ( * p) , * s as u32 ) ) ) ,
13271338 DataType :: Timestamp ( _unit, time_zone) => {
13281339 if time_zone. is_some ( ) {
13291340 return ColumnType :: TimestampWithTimeZone ;
@@ -1468,17 +1479,22 @@ mod tests {
14681479 Field :: new( "id" , DataType :: Int32 , false ) ,
14691480 Field :: new( "name" , DataType :: Utf8 , false ) ,
14701481 Field :: new( "age" , DataType :: Int32 , true ) ,
1482+ Field :: new( "balance" , DataType :: Decimal64 ( 10 , 2 ) , true ) ,
14711483 ] ) ;
14721484 let id_array = array:: Int32Array :: from ( vec ! [ 1 , 2 , 3 ] ) ;
14731485 let name_array = array:: StringArray :: from ( vec ! [ "a" , "b" , "c" ] ) ;
14741486 let age_array = array:: Int32Array :: from ( vec ! [ 10 , 20 , 30 ] ) ;
1487+ let balance_array = array:: Decimal64Array :: from ( vec ! [ 12345 , -12345 , 12300 ] )
1488+ . with_precision_and_scale ( 10 , 2 )
1489+ . unwrap ( ) ;
14751490
14761491 let batch1 = RecordBatch :: try_new (
14771492 Arc :: new ( schema1. clone ( ) ) ,
14781493 vec ! [
14791494 Arc :: new( id_array. clone( ) ) ,
14801495 Arc :: new( name_array. clone( ) ) ,
14811496 Arc :: new( age_array. clone( ) ) ,
1497+ Arc :: new( balance_array. clone( ) ) ,
14821498 ] ,
14831499 )
14841500 . expect ( "Unable to build record batch" ) ;
@@ -1487,6 +1503,7 @@ mod tests {
14871503 Field :: new( "id" , DataType :: Int32 , false ) ,
14881504 Field :: new( "name" , DataType :: Utf8 , false ) ,
14891505 Field :: new( "blah" , DataType :: Int32 , true ) ,
1506+ Field :: new( "balance" , DataType :: Decimal64 ( 10 , 2 ) , true ) ,
14901507 ] ) ;
14911508
14921509 let batch2 = RecordBatch :: try_new (
@@ -1495,6 +1512,7 @@ mod tests {
14951512 Arc :: new( id_array) ,
14961513 Arc :: new( name_array) ,
14971514 Arc :: new( age_array) ,
1515+ Arc :: new( balance_array) ,
14981516 ] ,
14991517 )
15001518 . expect ( "Unable to build record batch" ) ;
@@ -1503,7 +1521,16 @@ mod tests {
15031521 let sql = InsertBuilder :: new ( & TableReference :: from ( "users" ) , & record_batches)
15041522 . build_postgres ( None )
15051523 . expect ( "Failed to build insert statement" ) ;
1506- assert_eq ! ( sql, "INSERT INTO \" users\" (\" id\" , \" name\" , \" age\" ) VALUES (1, 'a', 10), (2, 'b', 20), (3, 'c', 30), (1, 'a', 10), (2, 'b', 20), (3, 'c', 30)" ) ;
1524+ assert_eq ! (
1525+ sql,
1526+ "INSERT INTO \" users\" (\" id\" , \" name\" , \" age\" , \" balance\" ) VALUES \
1527+ (1, 'a', 10, 123.45), \
1528+ (2, 'b', 20, -123.45), \
1529+ (3, 'c', 30, 123.00), \
1530+ (1, 'a', 10, 123.45), \
1531+ (2, 'b', 20, -123.45), \
1532+ (3, 'c', 30, 123.00)"
1533+ ) ;
15071534 }
15081535
15091536 #[ test]
0 commit comments