This is an automated email from the ASF dual-hosted git repository.
berkay pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 9df766f090 fix: add missing `NotExpr::evaluate_bounds` (#13082)
9df766f090 is described below
commit 9df766f090cf4ecf4011f38afb82f4d70d7d02eb
Author: Marco Neumann <[email protected]>
AuthorDate: Wed Oct 30 08:02:01 2024 +0100
fix: add missing `NotExpr::evaluate_bounds` (#13082)
* fix: add missing `NotExpr::evaluate_bounds`
* Add a test
---------
Co-authored-by: Andrew Lamb <[email protected]>
---
datafusion/physical-expr/src/expressions/not.rs | 55 +++++++++++++++++++++++--
1 file changed, 52 insertions(+), 3 deletions(-)
diff --git a/datafusion/physical-expr/src/expressions/not.rs
b/datafusion/physical-expr/src/expressions/not.rs
index b69954e00b..6d91e9dfdd 100644
--- a/datafusion/physical-expr/src/expressions/not.rs
+++ b/datafusion/physical-expr/src/expressions/not.rs
@@ -27,6 +27,7 @@ use crate::PhysicalExpr;
use arrow::datatypes::{DataType, Schema};
use arrow::record_batch::RecordBatch;
use datafusion_common::{cast::as_boolean_array, Result, ScalarValue};
+use datafusion_expr::interval_arithmetic::Interval;
use datafusion_expr::ColumnarValue;
/// Not expression
@@ -100,6 +101,10 @@ impl PhysicalExpr for NotExpr {
Ok(Arc::new(NotExpr::new(Arc::clone(&children[0]))))
}
+ fn evaluate_bounds(&self, children: &[&Interval]) -> Result<Interval> {
+ children[0].not()
+ }
+
fn dyn_hash(&self, state: &mut dyn Hasher) {
let mut s = state;
self.hash(&mut s);
@@ -125,10 +130,11 @@ mod tests {
use super::*;
use crate::expressions::col;
use arrow::{array::BooleanArray, datatypes::*};
+ use std::sync::OnceLock;
#[test]
fn neg_op() -> Result<()> {
- let schema = Schema::new(vec![Field::new("a", DataType::Boolean,
true)]);
+ let schema = schema();
let expr = not(col("a", &schema)?)?;
assert_eq!(expr.data_type(&schema)?, DataType::Boolean);
@@ -137,8 +143,7 @@ mod tests {
let input = BooleanArray::from(vec![Some(true), None, Some(false)]);
let expected = &BooleanArray::from(vec![Some(false), None,
Some(true)]);
- let batch =
- RecordBatch::try_new(Arc::new(schema.clone()),
vec![Arc::new(input)])?;
+ let batch = RecordBatch::try_new(schema, vec![Arc::new(input)])?;
let result = expr
.evaluate(&batch)?
@@ -150,4 +155,48 @@ mod tests {
Ok(())
}
+
+ #[test]
+ fn test_evaluate_bounds() -> Result<()> {
+ // Note that `None` for boolean intervals is converted to `Some(false)`
+ // / `Some(true)` by `Interval::make`, so it is not explicitly tested
+ // here
+
+ // if the bounds are all booleans (false, true) so is the negation
+ assert_evaluate_bounds(
+ Interval::make(Some(false), Some(true))?,
+ Interval::make(Some(false), Some(true))?,
+ )?;
+ // (true, false) is not tested because it is not a valid interval
(lower
+ // bound is greater than upper bound)
+ assert_evaluate_bounds(
+ Interval::make(Some(true), Some(true))?,
+ Interval::make(Some(false), Some(false))?,
+ )?;
+ assert_evaluate_bounds(
+ Interval::make(Some(false), Some(false))?,
+ Interval::make(Some(true), Some(true))?,
+ )?;
+ Ok(())
+ }
+
+ fn assert_evaluate_bounds(
+ interval: Interval,
+ expected_interval: Interval,
+ ) -> Result<()> {
+ let not_expr = not(col("a", &schema())?)?;
+ assert_eq!(
+ not_expr.evaluate_bounds(&[&interval]).unwrap(),
+ expected_interval
+ );
+ Ok(())
+ }
+
+ fn schema() -> SchemaRef {
+ Arc::clone(SCHEMA.get_or_init(|| {
+ Arc::new(Schema::new(vec![Field::new("a", DataType::Boolean,
true)]))
+ }))
+ }
+
+ static SCHEMA: OnceLock<SchemaRef> = OnceLock::new();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]