diff --git a/datafusion/__init__.py b/datafusion/__init__.py index 3a6482d2..f5583c29 100644 --- a/datafusion/__init__.py +++ b/datafusion/__init__.py @@ -63,6 +63,15 @@ IsNotFalse, IsNotUnknown, Negative, + ScalarFunction, + BuiltinScalarFunction, + InList, + Exists, + Subquery, + InSubquery, + ScalarSubquery, + GroupingSet, + Placeholder, Case, Cast, TryCast, @@ -105,6 +114,15 @@ "IsNotFalse", "IsNotUnknown", "Negative", + "ScalarFunction", + "BuiltinScalarFunction", + "InList", + "Exists", + "Subquery", + "InSubquery", + "ScalarSubquery", + "GroupingSet", + "Placeholder", "Case", "Cast", "TryCast", diff --git a/datafusion/tests/test_imports.py b/datafusion/tests/test_imports.py index 3d4a0d95..20e7abbc 100644 --- a/datafusion/tests/test_imports.py +++ b/datafusion/tests/test_imports.py @@ -59,6 +59,15 @@ IsNotFalse, IsNotUnknown, Negative, + ScalarFunction, + BuiltinScalarFunction, + InList, + Exists, + Subquery, + InSubquery, + ScalarSubquery, + GroupingSet, + Placeholder, Case, Cast, TryCast, @@ -111,6 +120,15 @@ def test_class_module_is_datafusion(): IsNotFalse, IsNotUnknown, Negative, + ScalarFunction, + BuiltinScalarFunction, + InList, + Exists, + Subquery, + InSubquery, + ScalarSubquery, + GroupingSet, + Placeholder, Case, Cast, TryCast, diff --git a/src/expr.rs b/src/expr.rs index 350eb664..a288b389 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -48,15 +48,24 @@ pub mod case; pub mod cast; pub mod column; pub mod empty_relation; +pub mod exists; pub mod filter; +pub mod grouping_set; +pub mod in_list; +pub mod in_subquery; pub mod indexed_field; pub mod like; pub mod limit; pub mod literal; pub mod logical_node; +pub mod placeholder; pub mod projection; +pub mod scalar_function; +pub mod scalar_subquery; pub mod scalar_variable; +pub mod signature; pub mod sort; +pub mod subquery; pub mod table_scan; /// A PyExpr that can be used on a DataFrame @@ -234,6 +243,15 @@ pub(crate) fn init_module(m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_class::()?; m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; m.add_class::()?; m.add_class::()?; m.add_class::()?; diff --git a/src/expr/exists.rs b/src/expr/exists.rs new file mode 100644 index 00000000..7df9a6e8 --- /dev/null +++ b/src/expr/exists.rs @@ -0,0 +1,45 @@ +// 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::Subquery; +use pyo3::prelude::*; + +use super::subquery::PySubquery; + +#[pyclass(name = "Exists", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyExists { + subquery: Subquery, + negated: bool, +} + +impl PyExists { + pub fn new(subquery: Subquery, negated: bool) -> Self { + Self { subquery, negated } + } +} + +#[pymethods] +impl PyExists { + fn subquery(&self) -> PySubquery { + self.subquery.clone().into() + } + + fn negated(&self) -> bool { + self.negated + } +} diff --git a/src/expr/grouping_set.rs b/src/expr/grouping_set.rs new file mode 100644 index 00000000..b7393286 --- /dev/null +++ b/src/expr/grouping_set.rs @@ -0,0 +1,37 @@ +// 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::GroupingSet; +use pyo3::prelude::*; + +#[pyclass(name = "GroupingSet", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyGroupingSet { + grouping_set: GroupingSet, +} + +impl From for GroupingSet { + fn from(grouping_set: PyGroupingSet) -> Self { + grouping_set.grouping_set + } +} + +impl From for PyGroupingSet { + fn from(grouping_set: GroupingSet) -> PyGroupingSet { + PyGroupingSet { grouping_set } + } +} diff --git a/src/expr/in_list.rs b/src/expr/in_list.rs new file mode 100644 index 00000000..840eee2c --- /dev/null +++ b/src/expr/in_list.rs @@ -0,0 +1,53 @@ +// 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 crate::expr::PyExpr; +use datafusion_expr::Expr; +use pyo3::prelude::*; + +#[pyclass(name = "InList", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyInList { + expr: Box, + list: Vec, + negated: bool, +} + +impl PyInList { + pub fn new(expr: Box, list: Vec, negated: bool) -> Self { + Self { + expr, + list, + negated, + } + } +} + +#[pymethods] +impl PyInList { + fn expr(&self) -> PyExpr { + (*self.expr).clone().into() + } + + fn list(&self) -> Vec { + self.list.iter().map(|e| e.clone().into()).collect() + } + + fn negated(&self) -> bool { + self.negated + } +} diff --git a/src/expr/in_subquery.rs b/src/expr/in_subquery.rs new file mode 100644 index 00000000..6cee4a1f --- /dev/null +++ b/src/expr/in_subquery.rs @@ -0,0 +1,54 @@ +// 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, Subquery}; +use pyo3::prelude::*; + +use super::{subquery::PySubquery, PyExpr}; + +#[pyclass(name = "InSubquery", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyInSubquery { + expr: Box, + subquery: Subquery, + negated: bool, +} + +impl PyInSubquery { + pub fn new(expr: Box, subquery: Subquery, negated: bool) -> Self { + Self { + expr, + subquery, + negated, + } + } +} + +#[pymethods] +impl PyInSubquery { + fn expr(&self) -> PyExpr { + (*self.expr).clone().into() + } + + fn subquery(&self) -> PySubquery { + self.subquery.clone().into() + } + + fn negated(&self) -> bool { + self.negated + } +} diff --git a/src/expr/placeholder.rs b/src/expr/placeholder.rs new file mode 100644 index 00000000..e37c8b56 --- /dev/null +++ b/src/expr/placeholder.rs @@ -0,0 +1,48 @@ +// 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::arrow::datatypes::DataType; +use pyo3::prelude::*; + +use crate::common::data_type::PyDataType; + +#[pyclass(name = "Placeholder", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyPlaceholder { + id: String, + data_type: Option, +} + +impl PyPlaceholder { + pub fn new(id: String, data_type: DataType) -> Self { + Self { + id, + data_type: Some(data_type), + } + } +} + +#[pymethods] +impl PyPlaceholder { + fn id(&self) -> String { + self.id.clone() + } + + fn data_type(&self) -> Option { + self.data_type.as_ref().map(|e| e.clone().into()) + } +} diff --git a/src/expr/scalar_function.rs b/src/expr/scalar_function.rs new file mode 100644 index 00000000..1a71d569 --- /dev/null +++ b/src/expr/scalar_function.rs @@ -0,0 +1,65 @@ +// 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 crate::expr::PyExpr; +use datafusion_expr::{BuiltinScalarFunction, Expr}; +use pyo3::prelude::*; + +#[pyclass(name = "ScalarFunction", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyScalarFunction { + scalar_function: BuiltinScalarFunction, + args: Vec, +} + +impl PyScalarFunction { + pub fn new(scalar_function: BuiltinScalarFunction, args: Vec) -> Self { + Self { + scalar_function, + args, + } + } +} + +#[pyclass(name = "BuiltinScalarFunction", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyBuiltinScalarFunction { + scalar_function: BuiltinScalarFunction, +} + +impl From for PyBuiltinScalarFunction { + fn from(scalar_function: BuiltinScalarFunction) -> PyBuiltinScalarFunction { + PyBuiltinScalarFunction { scalar_function } + } +} + +impl From for BuiltinScalarFunction { + fn from(scalar_function: PyBuiltinScalarFunction) -> Self { + scalar_function.scalar_function + } +} + +#[pymethods] +impl PyScalarFunction { + fn fun(&self) -> PyResult { + Ok(self.scalar_function.clone().into()) + } + + fn args(&self) -> PyResult> { + Ok(self.args.iter().map(|e| e.clone().into()).collect()) + } +} diff --git a/src/expr/scalar_subquery.rs b/src/expr/scalar_subquery.rs new file mode 100644 index 00000000..c71bb990 --- /dev/null +++ b/src/expr/scalar_subquery.rs @@ -0,0 +1,46 @@ +// 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::Subquery; +use pyo3::prelude::*; + +use super::subquery::PySubquery; + +#[pyclass(name = "ScalarSubquery", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PyScalarSubquery { + subquery: Subquery, +} + +impl From for Subquery { + fn from(subquery: PyScalarSubquery) -> Self { + subquery.subquery + } +} + +impl From for PyScalarSubquery { + fn from(subquery: Subquery) -> PyScalarSubquery { + PyScalarSubquery { subquery } + } +} + +#[pymethods] +impl PyScalarSubquery { + fn subquery(&self) -> PySubquery { + self.subquery.clone().into() + } +} diff --git a/src/expr/signature.rs b/src/expr/signature.rs new file mode 100644 index 00000000..c59c9900 --- /dev/null +++ b/src/expr/signature.rs @@ -0,0 +1,38 @@ +// 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::{TypeSignature, Volatility}; +use pyo3::prelude::*; + +#[pyclass(name = "Signature", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PySignature { + type_signature: TypeSignature, + volatility: Volatility, +} + +impl PySignature { + pub fn new(type_signature: TypeSignature, volatility: Volatility) -> Self { + Self { + type_signature, + volatility, + } + } +} + +#[pymethods] +impl PySignature {} diff --git a/src/expr/subquery.rs b/src/expr/subquery.rs new file mode 100644 index 00000000..93ff244f --- /dev/null +++ b/src/expr/subquery.rs @@ -0,0 +1,37 @@ +// 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::Subquery; +use pyo3::prelude::*; + +#[pyclass(name = "Subquery", module = "datafusion.expr", subclass)] +#[derive(Clone)] +pub struct PySubquery { + subquery: Subquery, +} + +impl From for Subquery { + fn from(subquery: PySubquery) -> Self { + subquery.subquery + } +} + +impl From for PySubquery { + fn from(subquery: Subquery) -> PySubquery { + PySubquery { subquery } + } +}