@@ -328,11 +328,12 @@ impl_to_timestamp_constructors!(ToTimestampMicrosFunc);
328328impl_to_timestamp_constructors ! ( ToTimestampNanosFunc ) ;
329329
330330fn decimal_to_nanoseconds ( value : i128 , scale : i8 ) -> i64 {
331- let scale_factor = 10_i128 . pow ( scale as u32 ) ;
332- let seconds = value / scale_factor;
333- let fraction = value % scale_factor;
334- let nanos = ( fraction * 1_000_000_000 ) / scale_factor;
335- let timestamp_nanos = seconds * 1_000_000_000 + nanos;
331+ let nanos_exponent = 9_i16 - scale as i16 ;
332+ let timestamp_nanos = if nanos_exponent >= 0 {
333+ value * 10_i128 . pow ( nanos_exponent as u32 )
334+ } else {
335+ value / 10_i128 . pow ( nanos_exponent. unsigned_abs ( ) as u32 )
336+ } ;
336337 timestamp_nanos as i64
337338}
338339
@@ -1852,4 +1853,23 @@ mod tests {
18521853 assert_contains ! ( actual, expected) ;
18531854 }
18541855 }
1856+
1857+ #[ test]
1858+ fn test_decimal_to_nanoseconds_negative_scale ( ) {
1859+ // scale -2: internal value 5 represents 5 * 10^2 = 500 seconds
1860+ let nanos = decimal_to_nanoseconds ( 5 , -2 ) ;
1861+ assert_eq ! ( nanos, 500_000_000_000 ) ; // 500 seconds in nanoseconds
1862+
1863+ // scale -1: internal value 10 represents 10 * 10^1 = 100 seconds
1864+ let nanos = decimal_to_nanoseconds ( 10 , -1 ) ;
1865+ assert_eq ! ( nanos, 100_000_000_000 ) ;
1866+
1867+ // scale 0: internal value 5 represents 5 seconds
1868+ let nanos = decimal_to_nanoseconds ( 5 , 0 ) ;
1869+ assert_eq ! ( nanos, 5_000_000_000 ) ;
1870+
1871+ // scale 3: internal value 1500 represents 1.5 seconds
1872+ let nanos = decimal_to_nanoseconds ( 1500 , 3 ) ;
1873+ assert_eq ! ( nanos, 1_500_000_000 ) ;
1874+ }
18551875}
0 commit comments