liukun4515 commented on code in PR #3281:
URL: https://github.com/apache/arrow-rs/pull/3281#discussion_r1046594005
##########
arrow-cast/src/cast.rs:
##########
@@ -2801,6 +2827,176 @@ fn cast_utf8_to_boolean(
Ok(Arc::new(output_array))
}
+/// Parses given string to specified decimal native (i128/i256) based on given
+/// scale. Returns an `Err` if it cannot parse given string.
+fn parse_string_to_decimal_native<T: DecimalType>(
+ value_str: &str,
+ scale: usize,
+) -> Result<T::Native, ArrowError>
+where
+ T::Native: DecimalCast + ArrowNativeTypeOp,
+{
+ let value_str = value_str.trim();
+ let parts: Vec<&str> = value_str.split('.').collect();
+ if parts.len() > 2 {
+ return Err(ArrowError::InvalidArgumentError(format!(
+ "Invalid decimal format: {:?}",
+ value_str
+ )));
+ }
+
+ let integers = parts[0].trim_start_matches('0');
+ let decimals = if parts.len() == 2 { parts[1] } else { "" };
+
+ // Adjust decimal based on scale
+ let number_decimals = if decimals.len() > scale {
+ let decimal_number = i256::from_string(decimals).ok_or_else(|| {
+ ArrowError::InvalidArgumentError(format!(
+ "Cannot parse decimal format: {}",
+ value_str
+ ))
+ })?;
+
+ let div =
+ i256::from_i128(10_i128).pow_checked((decimals.len() - scale) as
u32)?;
+
+ let half = div.div_wrapping(i256::from_i128(2));
+ let half_neg = half.neg_wrapping();
+
+ let d = decimal_number.div_wrapping(div);
+ let r = decimal_number.mod_wrapping(div);
+
+ // Round result
Review Comment:
👍
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]