Skip to content

Commit 4869a86

Browse files
authored
Empty relation bindings (apache#208)
1 parent 75dea3d commit 4869a86

14 files changed

Lines changed: 110 additions & 22 deletions

File tree

datafusion/cudf.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ def register_parquet(self, name, path):
3030
self.datafusion_ctx.register_parquet(name, path)
3131

3232
def to_cudf_expr(self, expr):
33-
3433
# get Python wrapper for logical expression
3534
expr = expr.to_variant()
3635

datafusion/tests/test_expr.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def test_projection(test_ctx):
6060
assert col3.op() == "<"
6161
assert isinstance(col3.right().to_variant(), Literal)
6262

63-
plan = plan.input().to_variant()
63+
plan = plan.input()[0].to_variant()
6464
assert isinstance(plan, TableScan)
6565

6666

@@ -71,7 +71,7 @@ def test_filter(test_ctx):
7171
plan = plan.to_variant()
7272
assert isinstance(plan, Projection)
7373

74-
plan = plan.input().to_variant()
74+
plan = plan.input()[0].to_variant()
7575
assert isinstance(plan, Filter)
7676

7777

@@ -90,7 +90,7 @@ def test_aggregate_query(test_ctx):
9090
projection = plan.to_variant()
9191
assert isinstance(projection, Projection)
9292

93-
aggregate = projection.input().to_variant()
93+
aggregate = projection.input()[0].to_variant()
9494
assert isinstance(aggregate, Aggregate)
9595

9696
col1 = aggregate.group_by_exprs()[0].to_variant()

src/common/df_schema.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@ impl PyDFSchema {
4949
schema: Arc::new(DFSchema::empty()),
5050
})
5151
}
52+
53+
#[pyo3(name = "field_names")]
54+
fn py_field_names(&self) -> PyResult<Vec<String>> {
55+
Ok(self.schema.field_names())
56+
}
5257
}

src/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub mod aggregate_expr;
3434
pub mod analyze;
3535
pub mod binary_expr;
3636
pub mod column;
37+
pub mod empty_relation;
3738
pub mod filter;
3839
pub mod limit;
3940
pub mod literal;
@@ -185,5 +186,6 @@ pub(crate) fn init_module(m: &PyModule) -> PyResult<()> {
185186
m.add_class::<aggregate::PyAggregate>()?;
186187
m.add_class::<sort::PySort>()?;
187188
m.add_class::<analyze::PyAnalyze>()?;
189+
m.add_class::<empty_relation::PyEmptyRelation>()?;
188190
Ok(())
189191
}

src/expr/aggregate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ impl PyAggregate {
8585
}
8686

8787
// Retrieves the input `LogicalPlan` to this `Aggregate` node
88-
fn input(&self) -> PyLogicalPlan {
89-
PyLogicalPlan::from((*self.aggregate.input).clone())
88+
fn input(&self) -> PyResult<Vec<PyLogicalPlan>> {
89+
Ok(Self::inputs(self))
9090
}
9191

9292
// Resulting Schema for this `Aggregate` node instance
@@ -100,7 +100,7 @@ impl PyAggregate {
100100
}
101101

102102
impl LogicalNode for PyAggregate {
103-
fn input(&self) -> Vec<PyLogicalPlan> {
103+
fn inputs(&self) -> Vec<PyLogicalPlan> {
104104
vec![PyLogicalPlan::from((*self.aggregate.input).clone())]
105105
}
106106
}

src/expr/analyze.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ impl PyAnalyze {
5959
Ok(self.analyze.verbose)
6060
}
6161

62+
fn input(&self) -> PyResult<Vec<PyLogicalPlan>> {
63+
Ok(Self::inputs(self))
64+
}
65+
6266
/// Resulting Schema for this `Analyze` node instance
6367
fn schema(&self) -> PyResult<PyDFSchema> {
6468
Ok((*self.analyze.schema).clone().into())
@@ -70,7 +74,7 @@ impl PyAnalyze {
7074
}
7175

7276
impl LogicalNode for PyAnalyze {
73-
fn input(&self) -> Vec<PyLogicalPlan> {
77+
fn inputs(&self) -> Vec<PyLogicalPlan> {
7478
vec![PyLogicalPlan::from((*self.analyze.input).clone())]
7579
}
7680
}

src/expr/empty_relation.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
use crate::common::df_schema::PyDFSchema;
19+
use datafusion_expr::EmptyRelation;
20+
use pyo3::prelude::*;
21+
use std::fmt::{self, Display, Formatter};
22+
23+
#[pyclass(name = "EmptyRelation", module = "datafusion.expr", subclass)]
24+
#[derive(Clone)]
25+
pub struct PyEmptyRelation {
26+
empty: EmptyRelation,
27+
}
28+
29+
impl From<PyEmptyRelation> for EmptyRelation {
30+
fn from(empty_relation: PyEmptyRelation) -> Self {
31+
empty_relation.empty
32+
}
33+
}
34+
35+
impl From<EmptyRelation> for PyEmptyRelation {
36+
fn from(empty: EmptyRelation) -> PyEmptyRelation {
37+
PyEmptyRelation { empty }
38+
}
39+
}
40+
41+
impl Display for PyEmptyRelation {
42+
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
43+
write!(
44+
f,
45+
"Empty Relation
46+
\nProduce One Row: {:?}
47+
\nSchema: {:?}",
48+
&self.empty.produce_one_row, &self.empty.schema
49+
)
50+
}
51+
}
52+
53+
#[pymethods]
54+
impl PyEmptyRelation {
55+
fn produce_one_row(&self) -> PyResult<bool> {
56+
Ok(self.empty.produce_one_row)
57+
}
58+
59+
/// Resulting Schema for this `EmptyRelation` node instance
60+
fn schema(&self) -> PyResult<PyDFSchema> {
61+
Ok((*self.empty.schema).clone().into())
62+
}
63+
64+
/// Get a String representation of this column
65+
fn __repr__(&self) -> String {
66+
format!("{}", self)
67+
}
68+
69+
fn __name__(&self) -> PyResult<String> {
70+
Ok("EmptyRelation".to_string())
71+
}
72+
}

src/expr/filter.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ impl PyFilter {
6262
}
6363

6464
/// Retrieves the input `LogicalPlan` to this `Filter` node
65-
fn input(&self) -> PyLogicalPlan {
66-
PyLogicalPlan::from((*self.filter.input).clone())
65+
fn input(&self) -> PyResult<Vec<PyLogicalPlan>> {
66+
Ok(Self::inputs(self))
6767
}
6868

6969
/// Resulting Schema for this `Filter` node instance
@@ -77,7 +77,7 @@ impl PyFilter {
7777
}
7878

7979
impl LogicalNode for PyFilter {
80-
fn input(&self) -> Vec<PyLogicalPlan> {
80+
fn inputs(&self) -> Vec<PyLogicalPlan> {
8181
vec![PyLogicalPlan::from((*self.filter.input).clone())]
8282
}
8383
}

src/expr/limit.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ impl PyLimit {
6767
}
6868

6969
/// Retrieves the input `LogicalPlan` to this `Limit` node
70-
fn input(&self) -> PyLogicalPlan {
71-
PyLogicalPlan::from((*self.limit.input).clone())
70+
fn input(&self) -> PyResult<Vec<PyLogicalPlan>> {
71+
Ok(Self::inputs(self))
7272
}
7373

7474
/// Resulting Schema for this `Limit` node instance
@@ -82,7 +82,7 @@ impl PyLimit {
8282
}
8383

8484
impl LogicalNode for PyLimit {
85-
fn input(&self) -> Vec<PyLogicalPlan> {
85+
fn inputs(&self) -> Vec<PyLogicalPlan> {
8686
vec![PyLogicalPlan::from((*self.limit.input).clone())]
8787
}
8888
}

src/expr/logical_node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ use crate::sql::logical::PyLogicalPlan;
2121
/// any "node" shares these common traits in common.
2222
pub trait LogicalNode {
2323
/// The input plan to the current logical node instance.
24-
fn input(&self) -> Vec<PyLogicalPlan>;
24+
fn inputs(&self) -> Vec<PyLogicalPlan>;
2525
}

0 commit comments

Comments
 (0)