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