This is an automated email from the ASF dual-hosted git repository.

timsaucer pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion-python.git


The following commit(s) were added to refs/heads/main by this push:
     new 02d4453  feat: expose between (#868)
02d4453 is described below

commit 02d4453af1c18d7e31c21d60574456226b71793e
Author: Daniel Mesejo <[email protected]>
AuthorDate: Wed Sep 11 19:28:10 2024 +0200

    feat: expose between (#868)
    
    closes #809
---
 python/datafusion/expr.py                 | 16 ++++++++++++++++
 python/datafusion/tests/test_functions.py | 31 +++++++++++++++++++++++++++++++
 src/expr.rs                               | 11 +++++++++++
 3 files changed, 58 insertions(+)

diff --git a/python/datafusion/expr.py b/python/datafusion/expr.py
index bd6a86f..f6a51ce 100644
--- a/python/datafusion/expr.py
+++ b/python/datafusion/expr.py
@@ -393,6 +393,22 @@ class Expr:
 
         return Expr(self.expr.cast(to))
 
+    def between(self, low: Any, high: Any, negated: bool = False) -> Expr:
+        """Returns ``True`` if this expression is between a given range.
+
+        Args:
+            low: lower bound of the range (inclusive).
+            high: higher bound of the range (inclusive).
+            negated: negates whether the expression is between a given range
+        """
+        if not isinstance(low, Expr):
+            low = Expr.literal(low)
+
+        if not isinstance(high, Expr):
+            high = Expr.literal(high)
+
+        return Expr(self.expr.between(low.expr, high.expr, negated=negated))
+
     def rex_type(self) -> RexType:
         """Return the Rex Type of this expression.
 
diff --git a/python/datafusion/tests/test_functions.py 
b/python/datafusion/tests/test_functions.py
index 8e3c513..9353f87 100644
--- a/python/datafusion/tests/test_functions.py
+++ b/python/datafusion/tests/test_functions.py
@@ -1024,3 +1024,34 @@ def test_cast(df, python_datatype, name: str, expected):
     result = df.collect()
     result = result[0]
     assert result.column(0) == result.column(1)
+
+
[email protected](
+    "negated, low, high, expected",
+    [
+        pytest.param(False, 3, 5, {"filtered": [4, 5]}),
+        pytest.param(False, 4, 5, {"filtered": [4, 5]}),
+        pytest.param(True, 3, 5, {"filtered": [6]}),
+        pytest.param(True, 4, 6, []),
+    ],
+)
+def test_between(df, negated, low, high, expected):
+    df = df.filter(column("b").between(low, high, negated=negated)).select(
+        column("b").alias("filtered")
+    )
+
+    actual = df.collect()
+
+    if expected:
+        actual = actual[0].to_pydict()
+        assert actual == expected
+    else:
+        assert len(actual) == 0  # the rows are empty
+
+
+def test_between_default(df):
+    df = df.filter(column("b").between(3, 
5)).select(column("b").alias("filtered"))
+    expected = {"filtered": [4, 5]}
+
+    actual = df.collect()[0].to_pydict()
+    assert actual == expected
diff --git a/src/expr.rs b/src/expr.rs
index ab16f28..0e1a193 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -293,6 +293,17 @@ impl PyExpr {
         expr.into()
     }
 
+    #[pyo3(signature = (low, high, negated=false))]
+    pub fn between(&self, low: PyExpr, high: PyExpr, negated: bool) -> PyExpr {
+        let expr = Expr::Between(Between::new(
+            Box::new(self.expr.clone()),
+            negated,
+            Box::new(low.into()),
+            Box::new(high.into()),
+        ));
+        expr.into()
+    }
+
     /// A Rex (Row Expression) specifies a single row of data. That 
specification
     /// could include user defined functions or types. RexType identifies the 
row
     /// as one of the possible valid `RexTypes`.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to