(&self, args: ScalarFunctionArgs)
| 278 | } |
| 279 | |
| 280 | fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> { |
| 281 | if args.arg_fields.iter().any(|a| a.data_type().is_null()) { |
| 282 | return ColumnarValue::Scalar(ScalarValue::Null) |
| 283 | .cast_to(args.return_type(), None); |
| 284 | } |
| 285 | |
| 286 | let default_decimal_places = ColumnarValue::Scalar(ScalarValue::Int32(Some(0))); |
| 287 | let decimal_places = if args.args.len() == 2 { |
| 288 | &args.args[1] |
| 289 | } else { |
| 290 | &default_decimal_places |
| 291 | }; |
| 292 | |
| 293 | if let (ColumnarValue::Scalar(value_scalar), ColumnarValue::Scalar(dp_scalar)) = |
| 294 | (&args.args[0], decimal_places) |
| 295 | { |
| 296 | if value_scalar.is_null() || dp_scalar.is_null() { |
| 297 | return ColumnarValue::Scalar(ScalarValue::Null) |
| 298 | .cast_to(args.return_type(), None); |
| 299 | } |
| 300 | |
| 301 | let dp = if let ScalarValue::Int32(Some(dp)) = dp_scalar { |
| 302 | *dp |
| 303 | } else { |
| 304 | return internal_err!( |
| 305 | "Unexpected datatype for decimal_places: {}", |
| 306 | dp_scalar.data_type() |
| 307 | ); |
| 308 | }; |
| 309 | |
| 310 | match (value_scalar, args.return_type()) { |
| 311 | (ScalarValue::Float32(Some(v)), _) => { |
| 312 | let rounded = round_float(*v, dp)?; |
| 313 | Ok(ColumnarValue::Scalar(ScalarValue::from(rounded))) |
| 314 | } |
| 315 | (ScalarValue::Float64(Some(v)), _) => { |
| 316 | let rounded = round_float(*v, dp)?; |
| 317 | Ok(ColumnarValue::Scalar(ScalarValue::from(rounded))) |
| 318 | } |
| 319 | ( |
| 320 | ScalarValue::Decimal32(Some(v), in_precision, scale), |
| 321 | Decimal32(out_precision, out_scale), |
| 322 | ) => { |
| 323 | let rounded = |
| 324 | round_decimal_or_zero(*v, *in_precision, *scale, *out_scale, dp)?; |
| 325 | let rounded = if *out_precision == Decimal32Type::MAX_PRECISION |
| 326 | && *scale == 0 |
| 327 | && dp < 0 |
| 328 | { |
| 329 | // With scale == 0 and negative dp, rounding can carry into an additional |
| 330 | // digit (e.g. 99 -> 100). If we're already at max precision we can't widen |
| 331 | // the type, so validate and error rather than producing an invalid decimal. |
| 332 | validate_decimal_precision::<Decimal32Type>( |
| 333 | rounded, |
| 334 | *out_precision, |
| 335 | *out_scale, |
| 336 | ) |
| 337 | } else { |
nothing calls this directly
no test coverage detected