From 71501f592a64f1fc80ac88a6bd6b404121c4c7c7 Mon Sep 17 00:00:00 2001 From: Vipul Vaibhaw Date: Tue, 7 May 2024 12:15:46 +0530 Subject: [PATCH] adding ansi checks and code refactor --- .../execution/datafusion/expressions/cast.rs | 88 +++++++++++-------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/core/src/execution/datafusion/expressions/cast.rs b/core/src/execution/datafusion/expressions/cast.rs index 0e715f277..5c28211ae 100644 --- a/core/src/execution/datafusion/expressions/cast.rs +++ b/core/src/execution/datafusion/expressions/cast.rs @@ -334,45 +334,7 @@ impl Cast { } (DataType::Float64, DataType::Decimal128(precision, scale)) => { - let input = array.as_any().downcast_ref::().unwrap(); - let mut cast_array = PrimitiveArray::::builder(input.len()); - - let mul = (*precision as f64).powi(*scale as i32); - - for i in 0..input.len() { - if input.is_null(i) { - cast_array.append_null(); - } else { - let input_value = input.value(i); - let value = (input_value * mul).round().to_i128(); - - if let Some(value) = value { - if Decimal128Type::validate_decimal_precision(value, *precision).is_err() { - return Err( - CometError::NumericValueOutOfRange { - value: input_value.to_string(), - precision: *precision, - scale: *scale, - } - .into(), - ); - } - - cast_array.append_value(value); - } else { - return Err( - CometError::NumericValueOutOfRange { - value: input_value.to_string(), - precision: *precision, - scale: *scale, - } - .into(), - ); - } - } - } - - Arc::new(cast_array.with_precision_and_scale(*precision, *scale)?.finish()) as ArrayRef + Self::cast_float64_to_decimal128(&array, *precision, *scale, self.eval_mode)? } _ => { // when we have no Spark-specific casting we delegate to DataFusion @@ -437,6 +399,54 @@ impl Cast { Ok(cast_array) } + fn cast_float64_to_decimal128 ( + array: &dyn Array, + precision: u8, + scale: i8, + eval_mode: EvalMode, + ) -> CometResult { + let input = array.as_any().downcast_ref::().unwrap(); + let mut cast_array = PrimitiveArray::::builder(input.len()); + + let mul = (precision as f64).powi(scale as i32); + + for i in 0..input.len() { + if input.is_null(i) { + cast_array.append_null(); + } else { + let input_value = input.value(i); + let value = (input_value * mul).round().to_i128(); + + match value { + Some(v) => { + if Decimal128Type::validate_decimal_precision(v, precision).is_err() { + return Err(CometError::NumericValueOutOfRange { + value: input_value.to_string(), + precision, + scale, + }); + } + cast_array.append_value(v); + } + None => { + if eval_mode == EvalMode::Ansi { + return Err(CometError::NumericValueOutOfRange { + value: input_value.to_string(), + precision, + scale, + }); + } else { + cast_array.append_null(); + } + } + } + } + } + + let res = Arc::new(cast_array.with_precision_and_scale(precision, scale)?.finish()) as ArrayRef; + Ok(res) + } + fn spark_cast_float64_to_utf8( from: &dyn Array, _eval_mode: EvalMode,