@@ -40,27 +40,55 @@ impl TryToDataFusion<ScalarValue> for Scalar {
4040 let precision = decimal_type. precision ( ) ;
4141 let scale = decimal_type. scale ( ) ;
4242
43- if precision <= i128:: MAX_PRECISION {
43+ if precision <= i32:: MAX_PRECISION {
44+ match dscalar. decimal_value ( ) {
45+ None => ScalarValue :: Decimal32 ( None , precision, scale) ,
46+ Some ( value) => match value. cast :: < i32 > ( ) {
47+ Some ( v32) => ScalarValue :: Decimal32 ( Some ( v32) , precision, scale) ,
48+ None => {
49+ vortex_bail ! (
50+ "invalid ScalarValue {value} for decimal with precision {precision}" ,
51+ )
52+ }
53+ } ,
54+ }
55+ } else if precision <= i64:: MAX_PRECISION {
56+ match dscalar. decimal_value ( ) {
57+ None => ScalarValue :: Decimal64 ( None , precision, scale) ,
58+ Some ( value) => match value. cast :: < i64 > ( ) {
59+ Some ( v64) => ScalarValue :: Decimal64 ( Some ( v64) , precision, scale) ,
60+ None => {
61+ vortex_bail ! (
62+ "invalid ScalarValue {value} for decimal with precision {precision}" ,
63+ )
64+ }
65+ } ,
66+ }
67+ } else if precision <= i128:: MAX_PRECISION {
4468 match dscalar. decimal_value ( ) {
4569 None => ScalarValue :: Decimal128 ( None , precision, scale) ,
46- Some ( DecimalValue :: I128 ( v128) ) => {
47- ScalarValue :: Decimal128 ( Some ( v128) , precision, scale)
48- }
49- _ => vortex_bail ! (
50- "invalid ScalarValue for decimal with precision {}" ,
51- precision
52- ) ,
70+ Some ( value) => match value. cast :: < i128 > ( ) {
71+ Some ( v128) => ScalarValue :: Decimal128 ( Some ( v128) , precision, scale) ,
72+ None => {
73+ vortex_bail ! (
74+ "invalid ScalarValue {value} for decimal with precision {precision}" ,
75+ )
76+ }
77+ } ,
5378 }
5479 } else {
5580 match dscalar. decimal_value ( ) {
5681 None => ScalarValue :: Decimal256 ( None , precision, scale) ,
57- Some ( DecimalValue :: I256 ( v256) ) => {
58- ScalarValue :: Decimal256 ( Some ( v256. into ( ) ) , precision, scale)
59- }
60- _ => vortex_bail ! (
61- "invalid ScalarValue for decimal with precision {}" ,
62- precision
63- ) ,
82+ Some ( value) => match value. cast :: < i256 > ( ) {
83+ Some ( v256) => {
84+ ScalarValue :: Decimal256 ( Some ( v256. into ( ) ) , precision, scale)
85+ }
86+ None => {
87+ vortex_bail ! (
88+ "invalid ScalarValue {value} for decimal with precision {precision}" ,
89+ )
90+ }
91+ } ,
6492 }
6593 }
6694 }
@@ -210,6 +238,32 @@ impl FromDataFusion<ScalarValue> for Scalar {
210238 . unwrap_or_else ( vortex:: scalar:: ScalarValue :: null) ,
211239 )
212240 }
241+ ScalarValue :: Decimal32 ( decimal, precision, scale) => {
242+ let decimal_dtype = DecimalDType :: new ( * precision, * scale) ;
243+ let nullable = Nullability :: Nullable ;
244+ if let Some ( value) = decimal {
245+ Scalar :: decimal (
246+ DecimalValue :: I32 ( * value) ,
247+ decimal_dtype,
248+ Nullability :: Nullable ,
249+ )
250+ } else {
251+ Scalar :: null ( DType :: Decimal ( decimal_dtype, nullable) )
252+ }
253+ }
254+ ScalarValue :: Decimal64 ( decimal, precision, scale) => {
255+ let decimal_dtype = DecimalDType :: new ( * precision, * scale) ;
256+ let nullable = Nullability :: Nullable ;
257+ if let Some ( value) = decimal {
258+ Scalar :: decimal (
259+ DecimalValue :: I64 ( * value) ,
260+ decimal_dtype,
261+ Nullability :: Nullable ,
262+ )
263+ } else {
264+ Scalar :: null ( DType :: Decimal ( decimal_dtype, nullable) )
265+ }
266+ }
213267 ScalarValue :: Decimal128 ( decimal, precision, scale) => {
214268 let decimal_dtype = DecimalDType :: new ( * precision, * scale) ;
215269 let nullable = Nullability :: Nullable ;
@@ -351,17 +405,41 @@ mod tests {
351405 }
352406
353407 #[ rstest]
408+ #[ case:: decimal32_some(
409+ Scalar :: decimal(
410+ DecimalValue :: I32 ( 1234 ) ,
411+ DecimalDType :: new( 5 , 2 ) ,
412+ Nullability :: NonNullable
413+ ) ,
414+ ScalarValue :: Decimal32 ( Some ( 1234 ) , 5 , 2 )
415+ ) ]
416+ #[ case:: decimal32_null(
417+ Scalar :: null( DType :: Decimal ( DecimalDType :: new( 5 , 2 ) , Nullability :: Nullable ) ) ,
418+ ScalarValue :: Decimal32 ( None , 5 , 2 )
419+ ) ]
420+ #[ case:: decimal64_some(
421+ Scalar :: decimal(
422+ DecimalValue :: I64 ( 12345 ) ,
423+ DecimalDType :: new( 10 , 2 ) ,
424+ Nullability :: NonNullable
425+ ) ,
426+ ScalarValue :: Decimal64 ( Some ( 12345 ) , 10 , 2 )
427+ ) ]
428+ #[ case:: decimal64_null(
429+ Scalar :: null( DType :: Decimal ( DecimalDType :: new( 10 , 2 ) , Nullability :: Nullable ) ) ,
430+ ScalarValue :: Decimal64 ( None , 10 , 2 )
431+ ) ]
354432 #[ case:: decimal128_some(
355433 Scalar :: decimal(
356434 DecimalValue :: I128 ( 12345 ) ,
357- DecimalDType :: new( 10 , 2 ) ,
435+ DecimalDType :: new( 20 , 2 ) ,
358436 Nullability :: NonNullable
359437 ) ,
360- ScalarValue :: Decimal128 ( Some ( 12345 ) , 10 , 2 )
438+ ScalarValue :: Decimal128 ( Some ( 12345 ) , 20 , 2 )
361439 ) ]
362440 #[ case:: decimal128_null(
363- Scalar :: null( DType :: Decimal ( DecimalDType :: new( 10 , 2 ) , Nullability :: Nullable ) ) ,
364- ScalarValue :: Decimal128 ( None , 10 , 2 )
441+ Scalar :: null( DType :: Decimal ( DecimalDType :: new( 20 , 2 ) , Nullability :: Nullable ) ) ,
442+ ScalarValue :: Decimal128 ( None , 20 , 2 )
365443 ) ]
366444 #[ case:: decimal256_some(
367445 Scalar :: decimal(
@@ -560,8 +638,16 @@ mod tests {
560638 ScalarValue :: Binary ( None )
561639 ) ]
562640 #[ case:: null_decimal128(
641+ Scalar :: null( DType :: Decimal ( DecimalDType :: new( 20 , 2 ) , Nullability :: Nullable ) ) ,
642+ ScalarValue :: Decimal128 ( None , 20 , 2 )
643+ ) ]
644+ #[ case:: null_decimal64(
563645 Scalar :: null( DType :: Decimal ( DecimalDType :: new( 10 , 2 ) , Nullability :: Nullable ) ) ,
564- ScalarValue :: Decimal128 ( None , 10 , 2 )
646+ ScalarValue :: Decimal64 ( None , 10 , 2 )
647+ ) ]
648+ #[ case:: null_decimal32(
649+ Scalar :: null( DType :: Decimal ( DecimalDType :: new( 5 , 2 ) , Nullability :: Nullable ) ) ,
650+ ScalarValue :: Decimal32 ( None , 5 , 2 )
565651 ) ]
566652 fn test_null_handling ( #[ case] vortex_null : Scalar , #[ case] expected_df_null : ScalarValue ) {
567653 // Test Vortex -> DataFusion
0 commit comments