This is an automated email from the ASF dual-hosted git repository.
agrove pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion-python.git
The following commit(s) were added to refs/heads/main by this push:
new 1b1300f Bool expr bindings (#223)
1b1300f is described below
commit 1b1300fb8c3e974c47d5764a3cf5bbaf86e33d3a
Author: Jeremy Dyer <[email protected]>
AuthorDate: Thu Feb 23 11:23:14 2023 -0500
Bool expr bindings (#223)
---
datafusion/__init__.py | 18 +++
datafusion/tests/test_imports.py | 18 +++
src/expr.rs | 25 +++
src/expr/bool_expr.rs | 322 +++++++++++++++++++++++++++++++++++++++
4 files changed, 383 insertions(+)
diff --git a/datafusion/__init__.py b/datafusion/__init__.py
index 01680e7..c695bfb 100644
--- a/datafusion/__init__.py
+++ b/datafusion/__init__.py
@@ -53,6 +53,15 @@ from .expr import (
ScalarVariable,
Sort,
TableScan,
+ Not,
+ IsNotNull,
+ IsTrue,
+ IsFalse,
+ IsUnknown,
+ IsNotTrue,
+ IsNotFalse,
+ IsNotUnknown,
+ Negative,
)
__version__ = importlib_metadata.version(__name__)
@@ -81,6 +90,15 @@ __all__ = [
"SimilarTo",
"ScalarVariable",
"Alias",
+ "Not",
+ "IsNotNull",
+ "IsTrue",
+ "IsFalse",
+ "IsUnknown",
+ "IsNotTrue",
+ "IsNotFalse",
+ "IsNotUnknown",
+ "Negative",
]
diff --git a/datafusion/tests/test_imports.py b/datafusion/tests/test_imports.py
index 0e39fd5..b154f56 100644
--- a/datafusion/tests/test_imports.py
+++ b/datafusion/tests/test_imports.py
@@ -49,6 +49,15 @@ from datafusion.expr import (
SimilarTo,
ScalarVariable,
Alias,
+ Not,
+ IsNotNull,
+ IsTrue,
+ IsFalse,
+ IsUnknown,
+ IsNotTrue,
+ IsNotFalse,
+ IsNotUnknown,
+ Negative,
)
@@ -87,6 +96,15 @@ def test_class_module_is_datafusion():
SimilarTo,
ScalarVariable,
Alias,
+ Not,
+ IsNotNull,
+ IsTrue,
+ IsFalse,
+ IsUnknown,
+ IsNotTrue,
+ IsNotFalse,
+ IsNotUnknown,
+ Negative,
]:
assert klass.__module__ == "datafusion.expr"
diff --git a/src/expr.rs b/src/expr.rs
index cdc81e7..f411068 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -30,6 +30,10 @@ use crate::expr::literal::PyLiteral;
use datafusion::scalar::ScalarValue;
use self::alias::PyAlias;
+use self::bool_expr::{
+ PyIsFalse, PyIsNotFalse, PyIsNotNull, PyIsNotTrue, PyIsNotUnknown,
PyIsNull, PyIsTrue,
+ PyIsUnknown, PyNegative, PyNot,
+};
use self::like::{PyILike, PyLike, PySimilarTo};
use self::scalar_variable::PyScalarVariable;
@@ -38,6 +42,7 @@ pub mod aggregate_expr;
pub mod alias;
pub mod analyze;
pub mod binary_expr;
+pub mod bool_expr;
pub mod column;
pub mod empty_relation;
pub mod filter;
@@ -81,6 +86,16 @@ impl PyExpr {
}
Expr::Literal(value) =>
Ok(PyLiteral::from(value.clone()).into_py(py)),
Expr::BinaryExpr(expr) =>
Ok(PyBinaryExpr::from(expr.clone()).into_py(py)),
+ Expr::Not(expr) => Ok(PyNot::new(*expr.clone()).into_py(py)),
+ Expr::IsNotNull(expr) =>
Ok(PyIsNotNull::new(*expr.clone()).into_py(py)),
+ Expr::IsNull(expr) => Ok(PyIsNull::new(*expr.clone()).into_py(py)),
+ Expr::IsTrue(expr) => Ok(PyIsTrue::new(*expr.clone()).into_py(py)),
+ Expr::IsFalse(expr) =>
Ok(PyIsFalse::new(*expr.clone()).into_py(py)),
+ Expr::IsUnknown(expr) =>
Ok(PyIsUnknown::new(*expr.clone()).into_py(py)),
+ Expr::IsNotTrue(expr) =>
Ok(PyIsNotTrue::new(*expr.clone()).into_py(py)),
+ Expr::IsNotFalse(expr) =>
Ok(PyIsNotFalse::new(*expr.clone()).into_py(py)),
+ Expr::IsNotUnknown(expr) =>
Ok(PyIsNotUnknown::new(*expr.clone()).into_py(py)),
+ Expr::Negative(expr) =>
Ok(PyNegative::new(*expr.clone()).into_py(py)),
Expr::AggregateFunction(expr) => {
Ok(PyAggregateFunction::from(expr.clone()).into_py(py))
}
@@ -200,6 +215,16 @@ pub(crate) fn init_module(m: &PyModule) -> PyResult<()> {
m.add_class::<PyBinaryExpr>()?;
m.add_class::<PyLiteral>()?;
m.add_class::<PyAggregateFunction>()?;
+ m.add_class::<PyNot>()?;
+ m.add_class::<PyIsNotNull>()?;
+ m.add_class::<PyIsNull>()?;
+ m.add_class::<PyIsTrue>()?;
+ m.add_class::<PyIsFalse>()?;
+ m.add_class::<PyIsUnknown>()?;
+ m.add_class::<PyIsNotTrue>()?;
+ m.add_class::<PyIsNotFalse>()?;
+ m.add_class::<PyIsNotUnknown>()?;
+ m.add_class::<PyNegative>()?;
m.add_class::<PyLike>()?;
m.add_class::<PyILike>()?;
m.add_class::<PySimilarTo>()?;
diff --git a/src/expr/bool_expr.rs b/src/expr/bool_expr.rs
new file mode 100644
index 0000000..d1502a4
--- /dev/null
+++ b/src/expr/bool_expr.rs
@@ -0,0 +1,322 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use datafusion_expr::Expr;
+use pyo3::prelude::*;
+use std::fmt::{self, Display, Formatter};
+
+use super::PyExpr;
+
+#[pyclass(name = "Not", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyNot {
+ expr: Expr,
+}
+
+impl PyNot {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyNot {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "Not
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyNot {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsNotNull", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsNotNull {
+ expr: Expr,
+}
+
+impl PyIsNotNull {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsNotNull {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsNotNull
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsNotNull {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsNull", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsNull {
+ expr: Expr,
+}
+
+impl PyIsNull {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsNull {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsNull
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsNull {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsTrue", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsTrue {
+ expr: Expr,
+}
+
+impl PyIsTrue {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsTrue {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsTrue
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsTrue {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsFalse", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsFalse {
+ expr: Expr,
+}
+
+impl PyIsFalse {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsFalse {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsFalse
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsFalse {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsUnknown", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsUnknown {
+ expr: Expr,
+}
+
+impl PyIsUnknown {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsUnknown {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsUnknown
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsUnknown {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsNotTrue", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsNotTrue {
+ expr: Expr,
+}
+
+impl PyIsNotTrue {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsNotTrue {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsNotTrue
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsNotTrue {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsNotFalse", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsNotFalse {
+ expr: Expr,
+}
+
+impl PyIsNotFalse {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsNotFalse {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsNotFalse
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsNotFalse {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "IsNotUnknown", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyIsNotUnknown {
+ expr: Expr,
+}
+
+impl PyIsNotUnknown {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyIsNotUnknown {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "IsNotUnknown
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyIsNotUnknown {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}
+
+#[pyclass(name = "Negative", module = "datafusion.expr", subclass)]
+#[derive(Clone, Debug)]
+pub struct PyNegative {
+ expr: Expr,
+}
+
+impl PyNegative {
+ pub fn new(expr: Expr) -> Self {
+ Self { expr }
+ }
+}
+
+impl Display for PyNegative {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(
+ f,
+ "Negative
+ Expr: {}",
+ &self.expr
+ )
+ }
+}
+
+#[pymethods]
+impl PyNegative {
+ fn expr(&self) -> PyResult<PyExpr> {
+ Ok(self.expr.clone().into())
+ }
+}