alamb commented on code in PR #14307:
URL: https://github.com/apache/datafusion/pull/14307#discussion_r1932476643


##########
datafusion/functions/src/math/monotonicity.rs:
##########
@@ -558,3 +558,405 @@ pub fn get_tanh_doc() -> &'static Documentation {
         .build()
     })
 }
+
+#[cfg(test)]
+mod tests {
+    use arrow::compute::SortOptions;
+    use datafusion_common::Result;
+
+    use super::*;
+
+    #[derive(Debug)]
+    struct MonotonicityTestCase {
+        name: &'static str,
+        func: fn(&[ExprProperties]) -> Result<SortProperties>,
+        lower: f64,
+        upper: f64,
+        input_sort: SortProperties,
+        expected: Result<SortProperties>,
+    }
+
+    #[test]
+    fn test_monotonicity_table() {
+        fn create_ep(lower: f64, upper: f64, sp: SortProperties) -> 
ExprProperties {
+            ExprProperties {
+                range: Interval::try_new(
+                    ScalarValue::from(lower),
+                    ScalarValue::from(upper),
+                )
+                .unwrap(),
+                sort_properties: sp,
+                preserves_lex_ordering: false,
+            }
+        }
+
+        let test_cases = vec![
+            MonotonicityTestCase {
+                name: "acos_order within domain",
+                func: acos_order,
+                lower: -0.5,
+                upper: 0.5,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "acos_order out of domain",
+                func: acos_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: exec_err!("Input range of ACOS contains 
out-of-domain values"),
+            },
+            MonotonicityTestCase {
+                name: "acosh_order within domain",
+                func: acosh_order,
+                lower: 2.0,
+                upper: 100.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: true,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: true,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "acosh_order out of domain",
+                func: acosh_order,
+                lower: 0.5,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: false,
+                }),
+                expected: exec_err!("Input range of ACOSH contains 
out-of-domain values"),
+            },
+            MonotonicityTestCase {
+                name: "asin_order within domain",
+                func: asin_order,
+                lower: -0.5,
+                upper: 0.5,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "asin_order out of domain",
+                func: asin_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: exec_err!("Input range of ASIN contains 
out-of-domain values"),
+            },
+            MonotonicityTestCase {
+                name: "asinh_order within domain",
+                func: asinh_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "asinh_order out of domain",
+                func: asinh_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "atan_order within domain",
+                func: atan_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "atan_order out of domain",
+                func: atan_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "atanh_order within domain",
+                func: atanh_order,
+                lower: -0.6,
+                upper: 0.6,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "atanh_order out of domain",
+                func: atanh_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: exec_err!("Input range of ATANH contains 
out-of-domain values"),
+            },
+            MonotonicityTestCase {
+                name: "cbrt_order within domain",
+                func: cbrt_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "cbrt_order out of domain",
+                func: cbrt_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "ceil_order within domain",
+                func: ceil_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "ceil_order out of domain",
+                func: ceil_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "cos_order within domain",
+                func: cos_order,
+                lower: 0.0,
+                upper: 2.0 * std::f64::consts::PI,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Unordered),
+            },
+            MonotonicityTestCase {
+                name: "cos_order out of domain",
+                func: cos_order,
+                lower: -2.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Unordered),
+            },
+            MonotonicityTestCase {
+                name: "cosh_order within domain positive",
+                func: cosh_order,
+                lower: 5.0,
+                upper: 100.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "cosh_order within domain negative",
+                func: cosh_order,
+                lower: -100.0,
+                upper: -5.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "cosh_order out of domain so unordered",
+                func: cosh_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Unordered),
+            },
+            MonotonicityTestCase {
+                name: "degrees_order",
+                func: degrees_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: true,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: true,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "exp_order",
+                func: exp_order,
+                lower: -1000.0,
+                upper: 1000.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "floor_order",
+                func: floor_order,
+                lower: -1.0,
+                upper: 1.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: true,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: true,
+                    nulls_first: true,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "ln_order within domain",
+                func: ln_order,
+                lower: 1.0,
+                upper: 2.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: Ok(SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                })),
+            },
+            MonotonicityTestCase {
+                name: "ln_order out of domain",
+                func: ln_order,
+                lower: -5.0,
+                upper: -4.0,
+                input_sort: SortProperties::Ordered(SortOptions {
+                    descending: false,
+                    nulls_first: false,
+                }),
+                expected: exec_err!("Input range of LN contains out-of-domain 
values"),

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: github-unsubscr...@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org

Reply via email to