1use std::sync::Arc;
19
20use arrow::array::{ArrayRef, AsArray};
21use arrow::compute::{DecimalCast, rescale_decimal};
22use arrow::datatypes::{
23 ArrowNativeTypeOp, DataType, Decimal32Type, Decimal64Type, Decimal128Type,
24 Decimal256Type, DecimalType, Float32Type, Float64Type,
25};
26use datafusion_common::{Result, ScalarValue, exec_err};
27use datafusion_expr::interval_arithmetic::Interval;
28use datafusion_expr::preimage::PreimageResult;
29use datafusion_expr::simplify::SimplifyContext;
30use datafusion_expr::sort_properties::{ExprProperties, SortProperties};
31use datafusion_expr::{
32 Coercion, ColumnarValue, Documentation, Expr, ScalarFunctionArgs, ScalarUDFImpl,
33 Signature, TypeSignature, TypeSignatureClass, Volatility,
34};
35use datafusion_macros::user_doc;
36use num_traits::{CheckedAdd, Float, One};
37
38use super::decimal::{apply_decimal_op, floor_decimal_value};
39
40#[user_doc(
41 doc_section(label = "Math Functions"),
42 description = "Returns the nearest integer less than or equal to a number.",
43 syntax_example = "floor(numeric_expression)",
44 standard_argument(name = "numeric_expression", prefix = "Numeric"),
45 sql_example = r#"```sql
46> SELECT floor(3.14);
47+-------------+
48| floor(3.14) |
49+-------------+
50| 3.0 |
51+-------------+
52```"#
53)]
54#[derive(Debug, PartialEq, Eq, Hash)]
55pub struct FloorFunc {
56 signature: Signature,
57}
58
59impl Default for FloorFunc {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl FloorFunc {
66 pub fn new() -> Self {
67 let decimal_sig = Coercion::new_exact(TypeSignatureClass::Decimal);
68 Self {
69 signature: Signature::one_of(
70 vec![
71 TypeSignature::Coercible(vec![decimal_sig]),
72 TypeSignature::Uniform(1, vec![DataType::Float64, DataType::Float32]),
73 ],
74 Volatility::Immutable,
75 ),
76 }
77 }
78}
79
80macro_rules! preimage_bounds {
83 (float: $variant:ident, $value:expr) => {
85 float_preimage_bounds($value).map(|(lo, hi)| {
86 (
87 ScalarValue::$variant(Some(lo)),
88 ScalarValue::$variant(Some(hi)),
89 )
90 })
91 };
92
93 (int: $variant:ident, $value:expr) => {
95 int_preimage_bounds($value).map(|(lo, hi)| {
96 (
97 ScalarValue::$variant(Some(lo)),
98 ScalarValue::$variant(Some(hi)),
99 )
100 })
101 };
102
103 (decimal: $variant:ident, $decimal_type:ty, $value:expr, $precision:expr, $scale:expr) => {
105 decimal_preimage_bounds::<$decimal_type>($value, $precision, $scale).map(
106 |(lo, hi)| {
107 (
108 ScalarValue::$variant(Some(lo), $precision, $scale),
109 ScalarValue::$variant(Some(hi), $precision, $scale),
110 )
111 },
112 )
113 };
114}
115
116impl ScalarUDFImpl for FloorFunc {
117 fn name(&self) -> &str {
118 "floor"
119 }
120
121 fn signature(&self) -> &Signature {
122 &self.signature
123 }
124
125 fn return_type(&self, arg_types: &[DataType]) -> Result<DataType> {
126 match &arg_types[0] {
127 DataType::Null => Ok(DataType::Float64),
128 other => Ok(other.clone()),
129 }
130 }
131
132 fn is_strict(&self) -> bool {
133 true
134 }
135
136 fn invoke_with_args(&self, args: ScalarFunctionArgs) -> Result<ColumnarValue> {
137 let arg = &args.args[0];
138
139 if let ColumnarValue::Scalar(scalar) = arg {
141 match scalar {
142 ScalarValue::Float64(v) => {
143 return Ok(ColumnarValue::Scalar(ScalarValue::Float64(
144 v.map(f64::floor),
145 )));
146 }
147 ScalarValue::Float32(v) => {
148 return Ok(ColumnarValue::Scalar(ScalarValue::Float32(
149 v.map(f32::floor),
150 )));
151 }
152 ScalarValue::Null => {
153 return Ok(ColumnarValue::Scalar(ScalarValue::Float64(None)));
154 }
155 _ => {}
158 }
159 }
160
161 let is_scalar = matches!(arg, ColumnarValue::Scalar(_));
163
164 let value = arg.to_array(args.number_rows)?;
166
167 let result: ArrayRef = match value.data_type() {
168 DataType::Float64 => Arc::new(
169 value
170 .as_primitive::<Float64Type>()
171 .unary::<_, Float64Type>(f64::floor),
172 ),
173 DataType::Float32 => Arc::new(
174 value
175 .as_primitive::<Float32Type>()
176 .unary::<_, Float32Type>(f32::floor),
177 ),
178 DataType::Null => {
179 return Ok(ColumnarValue::Scalar(ScalarValue::Float64(None)));
180 }
181 DataType::Decimal32(precision, scale) => {
182 apply_decimal_op::<Decimal32Type, _>(
183 &value,
184 *precision,
185 *scale,
186 self.name(),
187 floor_decimal_value,
188 )?
189 }
190 DataType::Decimal64(precision, scale) => {
191 apply_decimal_op::<Decimal64Type, _>(
192 &value,
193 *precision,
194 *scale,
195 self.name(),
196 floor_decimal_value,
197 )?
198 }
199 DataType::Decimal128(precision, scale) => {
200 apply_decimal_op::<Decimal128Type, _>(
201 &value,
202 *precision,
203 *scale,
204 self.name(),
205 floor_decimal_value,
206 )?
207 }
208 DataType::Decimal256(precision, scale) => {
209 apply_decimal_op::<Decimal256Type, _>(
210 &value,
211 *precision,
212 *scale,
213 self.name(),
214 floor_decimal_value,
215 )?
216 }
217 other => {
218 return exec_err!(
219 "Unsupported data type {other:?} for function {}",
220 self.name()
221 );
222 }
223 };
224
225 if is_scalar {
227 ScalarValue::try_from_array(&result, 0).map(ColumnarValue::Scalar)
228 } else {
229 Ok(ColumnarValue::Array(result))
230 }
231 }
232
233 fn output_ordering(&self, input: &[ExprProperties]) -> Result<SortProperties> {
234 Ok(input[0].sort_properties)
235 }
236
237 fn evaluate_bounds(&self, inputs: &[&Interval]) -> Result<Interval> {
238 let data_type = inputs[0].data_type();
239 Interval::make_unbounded(&data_type)
240 }
241
242 fn preimage(
250 &self,
251 args: &[Expr],
252 lit_expr: &Expr,
253 _info: &SimplifyContext,
254 ) -> Result<PreimageResult> {
255 debug_assert!(args.len() == 1, "floor() takes exactly one argument");
257
258 let arg = args[0].clone();
259
260 let Expr::Literal(lit_value, _) = lit_expr else {
262 return Ok(PreimageResult::None);
263 };
264
265 let Some((lower, upper)) = (match lit_value {
267 ScalarValue::Float64(Some(n)) => preimage_bounds!(float: Float64, *n),
269 ScalarValue::Float32(Some(n)) => preimage_bounds!(float: Float32, *n),
270
271 ScalarValue::Int8(Some(n)) => preimage_bounds!(int: Int8, *n),
275 ScalarValue::Int16(Some(n)) => preimage_bounds!(int: Int16, *n),
276 ScalarValue::Int32(Some(n)) => preimage_bounds!(int: Int32, *n),
277 ScalarValue::Int64(Some(n)) => preimage_bounds!(int: Int64, *n),
278
279 ScalarValue::Decimal32(Some(n), precision, scale) => {
284 preimage_bounds!(decimal: Decimal32, Decimal32Type, *n, *precision, *scale)
285 }
286 ScalarValue::Decimal64(Some(n), precision, scale) => {
287 preimage_bounds!(decimal: Decimal64, Decimal64Type, *n, *precision, *scale)
288 }
289 ScalarValue::Decimal128(Some(n), precision, scale) => {
290 preimage_bounds!(decimal: Decimal128, Decimal128Type, *n, *precision, *scale)
291 }
292 ScalarValue::Decimal256(Some(n), precision, scale) => {
293 preimage_bounds!(decimal: Decimal256, Decimal256Type, *n, *precision, *scale)
294 }
295
296 _ => None,
298 }) else {
299 return Ok(PreimageResult::None);
300 };
301
302 Ok(PreimageResult::Range {
303 expr: arg,
304 interval: Box::new(Interval::try_new(lower, upper)?),
305 })
306 }
307
308 fn documentation(&self) -> Option<&Documentation> {
309 self.doc()
310 }
311}
312
313fn float_preimage_bounds<F: Float>(n: F) -> Option<(F, F)> {
322 let one = F::one();
323 if !n.is_finite() {
325 return None;
326 }
327 if n.fract() != F::zero() {
329 return None;
330 }
331 if n + one <= n {
333 return None;
334 }
335 Some((n, n + one))
336}
337
338fn int_preimage_bounds<I: CheckedAdd + One + Copy>(n: I) -> Option<(I, I)> {
342 let upper = n.checked_add(&I::one())?;
343 Some((n, upper))
344}
345
346fn decimal_preimage_bounds<D: DecimalType>(
352 value: D::Native,
353 precision: u8,
354 scale: i8,
355) -> Option<(D::Native, D::Native)>
356where
357 D::Native: DecimalCast + ArrowNativeTypeOp + std::ops::Rem<Output = D::Native>,
358{
359 let one_scaled: D::Native = rescale_decimal::<D, D>(
362 D::Native::ONE, 1, 0, precision, scale, )?;
368
369 if scale > 0 && value % one_scaled != D::Native::ZERO {
372 return None;
373 }
374
375 let upper = value.add_checked(one_scaled).ok()?;
381
382 Some((value, upper))
383}
384
385#[cfg(test)]
386mod tests {
387 use super::*;
388 use arrow_buffer::i256;
389 use datafusion_expr::col;
390
391 fn assert_preimage_range(
393 input: ScalarValue,
394 expected_lower: ScalarValue,
395 expected_upper: ScalarValue,
396 ) {
397 let floor_func = FloorFunc::new();
398 let args = vec![col("x")];
399 let lit_expr = Expr::Literal(input.clone(), None);
400 let info = SimplifyContext::default();
401
402 let result = floor_func.preimage(&args, &lit_expr, &info).unwrap();
403
404 match result {
405 PreimageResult::Range { expr, interval } => {
406 assert_eq!(expr, col("x"));
407 assert_eq!(interval.lower().clone(), expected_lower);
408 assert_eq!(interval.upper().clone(), expected_upper);
409 }
410 PreimageResult::None => {
411 panic!("Expected Range, got None for input {input:?}")
412 }
413 }
414 }
415
416 fn assert_preimage_none(input: ScalarValue) {
418 let floor_func = FloorFunc::new();
419 let args = vec![col("x")];
420 let lit_expr = Expr::Literal(input.clone(), None);
421 let info = SimplifyContext::default();
422
423 let result = floor_func.preimage(&args, &lit_expr, &info).unwrap();
424 assert!(
425 matches!(result, PreimageResult::None),
426 "Expected None for input {input:?}"
427 );
428 }
429
430 #[test]
431 fn test_floor_preimage_valid_cases() {
432 assert_preimage_range(
434 ScalarValue::Float64(Some(100.0)),
435 ScalarValue::Float64(Some(100.0)),
436 ScalarValue::Float64(Some(101.0)),
437 );
438 assert_preimage_range(
440 ScalarValue::Float32(Some(50.0)),
441 ScalarValue::Float32(Some(50.0)),
442 ScalarValue::Float32(Some(51.0)),
443 );
444 assert_preimage_range(
446 ScalarValue::Int64(Some(42)),
447 ScalarValue::Int64(Some(42)),
448 ScalarValue::Int64(Some(43)),
449 );
450 assert_preimage_range(
452 ScalarValue::Int32(Some(100)),
453 ScalarValue::Int32(Some(100)),
454 ScalarValue::Int32(Some(101)),
455 );
456 assert_preimage_range(
458 ScalarValue::Float64(Some(-5.0)),
459 ScalarValue::Float64(Some(-5.0)),
460 ScalarValue::Float64(Some(-4.0)),
461 );
462 assert_preimage_range(
464 ScalarValue::Float64(Some(0.0)),
465 ScalarValue::Float64(Some(0.0)),
466 ScalarValue::Float64(Some(1.0)),
467 );
468 }
469
470 #[test]
471 fn test_floor_preimage_non_integer_float() {
472 assert_preimage_none(ScalarValue::Float64(Some(1.3)));
475 assert_preimage_none(ScalarValue::Float64(Some(-2.5)));
476 assert_preimage_none(ScalarValue::Float32(Some(3.7)));
477 }
478
479 #[test]
480 fn test_floor_preimage_integer_overflow() {
481 assert_preimage_none(ScalarValue::Int64(Some(i64::MAX)));
483 assert_preimage_none(ScalarValue::Int32(Some(i32::MAX)));
484 assert_preimage_none(ScalarValue::Int16(Some(i16::MAX)));
485 assert_preimage_none(ScalarValue::Int8(Some(i8::MAX)));
486 }
487
488 #[test]
489 fn test_floor_preimage_float_edge_cases() {
490 assert_preimage_none(ScalarValue::Float64(Some(f64::INFINITY)));
492 assert_preimage_none(ScalarValue::Float64(Some(f64::NEG_INFINITY)));
493 assert_preimage_none(ScalarValue::Float64(Some(f64::NAN)));
494 assert_preimage_none(ScalarValue::Float64(Some(f64::MAX))); assert_preimage_none(ScalarValue::Float32(Some(f32::INFINITY)));
498 assert_preimage_none(ScalarValue::Float32(Some(f32::NEG_INFINITY)));
499 assert_preimage_none(ScalarValue::Float32(Some(f32::NAN)));
500 assert_preimage_none(ScalarValue::Float32(Some(f32::MAX))); }
502
503 #[test]
504 fn test_floor_preimage_null_values() {
505 assert_preimage_none(ScalarValue::Float64(None));
506 assert_preimage_none(ScalarValue::Float32(None));
507 assert_preimage_none(ScalarValue::Int64(None));
508 }
509
510 #[test]
513 fn test_floor_preimage_decimal_valid_cases() {
514 assert_preimage_range(
518 ScalarValue::Decimal32(Some(10000), 9, 2),
519 ScalarValue::Decimal32(Some(10000), 9, 2), ScalarValue::Decimal32(Some(10100), 9, 2), );
522
523 assert_preimage_range(
525 ScalarValue::Decimal32(Some(5000), 9, 2),
526 ScalarValue::Decimal32(Some(5000), 9, 2), ScalarValue::Decimal32(Some(5100), 9, 2), );
529
530 assert_preimage_range(
532 ScalarValue::Decimal32(Some(-500), 9, 2),
533 ScalarValue::Decimal32(Some(-500), 9, 2), ScalarValue::Decimal32(Some(-400), 9, 2), );
536
537 assert_preimage_range(
539 ScalarValue::Decimal32(Some(0), 9, 2),
540 ScalarValue::Decimal32(Some(0), 9, 2), ScalarValue::Decimal32(Some(100), 9, 2), );
543
544 assert_preimage_range(
546 ScalarValue::Decimal32(Some(42), 9, 0),
547 ScalarValue::Decimal32(Some(42), 9, 0),
548 ScalarValue::Decimal32(Some(43), 9, 0),
549 );
550
551 assert_preimage_range(
553 ScalarValue::Decimal64(Some(10000), 18, 2),
554 ScalarValue::Decimal64(Some(10000), 18, 2), ScalarValue::Decimal64(Some(10100), 18, 2), );
557
558 assert_preimage_range(
560 ScalarValue::Decimal64(Some(-500), 18, 2),
561 ScalarValue::Decimal64(Some(-500), 18, 2), ScalarValue::Decimal64(Some(-400), 18, 2), );
564
565 assert_preimage_range(
567 ScalarValue::Decimal64(Some(0), 18, 2),
568 ScalarValue::Decimal64(Some(0), 18, 2),
569 ScalarValue::Decimal64(Some(100), 18, 2),
570 );
571
572 assert_preimage_range(
574 ScalarValue::Decimal128(Some(10000), 38, 2),
575 ScalarValue::Decimal128(Some(10000), 38, 2), ScalarValue::Decimal128(Some(10100), 38, 2), );
578
579 assert_preimage_range(
581 ScalarValue::Decimal128(Some(-500), 38, 2),
582 ScalarValue::Decimal128(Some(-500), 38, 2), ScalarValue::Decimal128(Some(-400), 38, 2), );
585
586 assert_preimage_range(
588 ScalarValue::Decimal128(Some(0), 38, 2),
589 ScalarValue::Decimal128(Some(0), 38, 2),
590 ScalarValue::Decimal128(Some(100), 38, 2),
591 );
592
593 assert_preimage_range(
595 ScalarValue::Decimal256(Some(i256::from(10000)), 76, 2),
596 ScalarValue::Decimal256(Some(i256::from(10000)), 76, 2), ScalarValue::Decimal256(Some(i256::from(10100)), 76, 2), );
599
600 assert_preimage_range(
602 ScalarValue::Decimal256(Some(i256::from(-500)), 76, 2),
603 ScalarValue::Decimal256(Some(i256::from(-500)), 76, 2), ScalarValue::Decimal256(Some(i256::from(-400)), 76, 2), );
606
607 assert_preimage_range(
609 ScalarValue::Decimal256(Some(i256::ZERO), 76, 2),
610 ScalarValue::Decimal256(Some(i256::ZERO), 76, 2),
611 ScalarValue::Decimal256(Some(i256::from(100)), 76, 2),
612 );
613 }
614
615 #[test]
616 fn test_floor_preimage_decimal_non_integer() {
617 assert_preimage_none(ScalarValue::Decimal32(Some(130), 9, 2)); assert_preimage_none(ScalarValue::Decimal32(Some(-250), 9, 2)); assert_preimage_none(ScalarValue::Decimal32(Some(370), 9, 2)); assert_preimage_none(ScalarValue::Decimal32(Some(1), 9, 2)); assert_preimage_none(ScalarValue::Decimal64(Some(130), 18, 2)); assert_preimage_none(ScalarValue::Decimal64(Some(-250), 18, 2)); assert_preimage_none(ScalarValue::Decimal128(Some(130), 38, 2)); assert_preimage_none(ScalarValue::Decimal128(Some(-250), 38, 2)); assert_preimage_none(ScalarValue::Decimal256(Some(i256::from(130)), 76, 2)); assert_preimage_none(ScalarValue::Decimal256(Some(i256::from(-250)), 76, 2)); assert_preimage_none(ScalarValue::Decimal32(Some(i32::MAX - 50), 10, 2));
641
642 assert_preimage_none(ScalarValue::Decimal64(Some(i64::MAX - 50), 19, 2));
645 }
646
647 #[test]
648 fn test_floor_preimage_decimal_overflow() {
649 assert_preimage_none(ScalarValue::Decimal32(Some(i32::MAX), 10, 0));
653
654 assert_preimage_none(ScalarValue::Decimal64(Some(i64::MAX), 19, 0));
656 }
657
658 #[test]
659 fn test_floor_preimage_decimal_edge_cases() {
660 let safe_max_aligned_32 = 999_999_900; assert_preimage_range(
666 ScalarValue::Decimal32(Some(safe_max_aligned_32), 9, 2),
667 ScalarValue::Decimal32(Some(safe_max_aligned_32), 9, 2),
668 ScalarValue::Decimal32(Some(safe_max_aligned_32 + 100), 9, 2),
669 );
670
671 let min_aligned_32 = -999_999_900; assert_preimage_range(
675 ScalarValue::Decimal32(Some(min_aligned_32), 9, 2),
676 ScalarValue::Decimal32(Some(min_aligned_32), 9, 2),
677 ScalarValue::Decimal32(Some(min_aligned_32 + 100), 9, 2),
678 );
679 }
680
681 #[test]
682 fn test_floor_preimage_decimal_null() {
683 assert_preimage_none(ScalarValue::Decimal32(None, 9, 2));
684 assert_preimage_none(ScalarValue::Decimal64(None, 18, 2));
685 assert_preimage_none(ScalarValue::Decimal128(None, 38, 2));
686 assert_preimage_none(ScalarValue::Decimal256(None, 76, 2));
687 }
688}