Skip to content

Commit fc7154e

Browse files
razeghi71alamb
authored andcommitted
Split EmptyExec into PlaceholderRowExec (#8446)
* add PlaceHolderRowExec * Change produce_one_row=true calls to use PlaceHolderRowExec * remove produce_one_row from EmptyExec, changes in proto serializer, working tests * PlaceHolder => Placeholder --------- Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
1 parent 834da74 commit fc7154e

23 files changed

Lines changed: 459 additions & 183 deletions

File tree

datafusion/core/src/datasource/empty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl TableProvider for EmptyTable {
7777
// even though there is no data, projections apply
7878
let projected_schema = project_schema(&self.schema, projection)?;
7979
Ok(Arc::new(
80-
EmptyExec::new(false, projected_schema).with_partitions(self.partitions),
80+
EmptyExec::new(projected_schema).with_partitions(self.partitions),
8181
))
8282
}
8383
}

datafusion/core/src/datasource/listing/table.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ impl TableProvider for ListingTable {
685685
if partitioned_file_lists.is_empty() {
686686
let schema = self.schema();
687687
let projected_schema = project_schema(&schema, projection)?;
688-
return Ok(Arc::new(EmptyExec::new(false, projected_schema)));
688+
return Ok(Arc::new(EmptyExec::new(projected_schema)));
689689
}
690690

691691
// extract types of partition columns
@@ -713,7 +713,7 @@ impl TableProvider for ListingTable {
713713
let object_store_url = if let Some(url) = self.table_paths.first() {
714714
url.object_store()
715715
} else {
716-
return Ok(Arc::new(EmptyExec::new(false, Arc::new(Schema::empty()))));
716+
return Ok(Arc::new(EmptyExec::new(Arc::new(Schema::empty()))));
717717
};
718718
// create the execution plan
719719
self.options

datafusion/core/src/physical_optimizer/aggregate_statistics.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ use super::optimizer::PhysicalOptimizerRule;
2222
use crate::config::ConfigOptions;
2323
use crate::error::Result;
2424
use crate::physical_plan::aggregates::AggregateExec;
25-
use crate::physical_plan::empty::EmptyExec;
2625
use crate::physical_plan::projection::ProjectionExec;
2726
use crate::physical_plan::{expressions, AggregateExpr, ExecutionPlan, Statistics};
2827
use crate::scalar::ScalarValue;
2928

3029
use datafusion_common::stats::Precision;
3130
use datafusion_common::tree_node::TreeNode;
3231
use datafusion_expr::utils::COUNT_STAR_EXPANSION;
32+
use datafusion_physical_plan::placeholder_row::PlaceholderRowExec;
3333

3434
/// Optimizer that uses available statistics for aggregate functions
3535
#[derive(Default)]
@@ -82,7 +82,7 @@ impl PhysicalOptimizerRule for AggregateStatistics {
8282
// input can be entirely removed
8383
Ok(Arc::new(ProjectionExec::try_new(
8484
projections,
85-
Arc::new(EmptyExec::new(true, plan.schema())),
85+
Arc::new(PlaceholderRowExec::new(plan.schema())),
8686
)?))
8787
} else {
8888
plan.map_children(|child| self.optimize(child, _config))

datafusion/core/src/physical_optimizer/join_selection.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1623,12 +1623,12 @@ mod hash_join_tests {
16231623

16241624
let children = vec![
16251625
PipelineStatePropagator {
1626-
plan: Arc::new(EmptyExec::new(false, Arc::new(Schema::empty()))),
1626+
plan: Arc::new(EmptyExec::new(Arc::new(Schema::empty()))),
16271627
unbounded: left_unbounded,
16281628
children: vec![],
16291629
},
16301630
PipelineStatePropagator {
1631-
plan: Arc::new(EmptyExec::new(false, Arc::new(Schema::empty()))),
1631+
plan: Arc::new(EmptyExec::new(Arc::new(Schema::empty()))),
16321632
unbounded: right_unbounded,
16331633
children: vec![],
16341634
},

datafusion/core/src/physical_planner.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ use datafusion_expr::{
9191
WindowFrameBound, WriteOp,
9292
};
9393
use datafusion_physical_expr::expressions::Literal;
94+
use datafusion_physical_plan::placeholder_row::PlaceholderRowExec;
9495
use datafusion_sql::utils::window_expr_common_partition_keys;
9596

9697
use async_trait::async_trait;
@@ -1196,10 +1197,15 @@ impl DefaultPhysicalPlanner {
11961197
}
11971198
LogicalPlan::Subquery(_) => todo!(),
11981199
LogicalPlan::EmptyRelation(EmptyRelation {
1199-
produce_one_row,
1200+
produce_one_row: false,
12001201
schema,
12011202
}) => Ok(Arc::new(EmptyExec::new(
1202-
*produce_one_row,
1203+
SchemaRef::new(schema.as_ref().to_owned().into()),
1204+
))),
1205+
LogicalPlan::EmptyRelation(EmptyRelation {
1206+
produce_one_row: true,
1207+
schema,
1208+
}) => Ok(Arc::new(PlaceholderRowExec::new(
12031209
SchemaRef::new(schema.as_ref().to_owned().into()),
12041210
))),
12051211
LogicalPlan::SubqueryAlias(SubqueryAlias { input, .. }) => {
@@ -2767,7 +2773,7 @@ mod tests {
27672773
27682774
digraph {
27692775
1[shape=box label="ProjectionExec: expr=[id@0 + 2 as employee.id + Int32(2)]", tooltip=""]
2770-
2[shape=box label="EmptyExec: produce_one_row=false", tooltip=""]
2776+
2[shape=box label="EmptyExec", tooltip=""]
27712777
1 -> 2 [arrowhead=none, arrowtail=normal, dir=back]
27722778
}
27732779
// End DataFusion GraphViz Plan

datafusion/core/tests/custom_sources.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use datafusion::execution::context::{SessionContext, SessionState, TaskContext};
3030
use datafusion::logical_expr::{
3131
col, Expr, LogicalPlan, LogicalPlanBuilder, TableScan, UNNAMED_TABLE,
3232
};
33-
use datafusion::physical_plan::empty::EmptyExec;
3433
use datafusion::physical_plan::expressions::PhysicalSortExpr;
3534
use datafusion::physical_plan::{
3635
collect, ColumnStatistics, DisplayAs, DisplayFormatType, ExecutionPlan, Partitioning,
@@ -42,6 +41,7 @@ use datafusion_common::project_schema;
4241
use datafusion_common::stats::Precision;
4342

4443
use async_trait::async_trait;
44+
use datafusion_physical_plan::placeholder_row::PlaceholderRowExec;
4545
use futures::stream::Stream;
4646

4747
/// Also run all tests that are found in the `custom_sources_cases` directory
@@ -256,9 +256,9 @@ async fn optimizers_catch_all_statistics() {
256256

257257
let physical_plan = df.create_physical_plan().await.unwrap();
258258

259-
// when the optimization kicks in, the source is replaced by an EmptyExec
259+
// when the optimization kicks in, the source is replaced by an PlaceholderRowExec
260260
assert!(
261-
contains_empty_exec(Arc::clone(&physical_plan)),
261+
contains_place_holder_exec(Arc::clone(&physical_plan)),
262262
"Expected aggregate_statistics optimizations missing: {physical_plan:?}"
263263
);
264264

@@ -283,12 +283,12 @@ async fn optimizers_catch_all_statistics() {
283283
assert_eq!(format!("{:?}", actual[0]), format!("{expected:?}"));
284284
}
285285

286-
fn contains_empty_exec(plan: Arc<dyn ExecutionPlan>) -> bool {
287-
if plan.as_any().is::<EmptyExec>() {
286+
fn contains_place_holder_exec(plan: Arc<dyn ExecutionPlan>) -> bool {
287+
if plan.as_any().is::<PlaceholderRowExec>() {
288288
true
289289
} else if plan.children().len() != 1 {
290290
false
291291
} else {
292-
contains_empty_exec(Arc::clone(&plan.children()[0]))
292+
contains_place_holder_exec(Arc::clone(&plan.children()[0]))
293293
}
294294
}

datafusion/core/tests/sql/explain_analyze.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ async fn explain_analyze_runs_optimizers() {
575575

576576
// This happens as an optimization pass where count(*) can be
577577
// answered using statistics only.
578-
let expected = "EmptyExec: produce_one_row=true";
578+
let expected = "PlaceholderRowExec";
579579

580580
let sql = "EXPLAIN SELECT count(*) from alltypes_plain";
581581
let actual = execute_to_batches(&ctx, sql).await;
@@ -806,7 +806,7 @@ async fn explain_physical_plan_only() {
806806
let expected = vec![vec![
807807
"physical_plan",
808808
"ProjectionExec: expr=[2 as COUNT(*)]\
809-
\n EmptyExec: produce_one_row=true\
809+
\n PlaceholderRowExec\
810810
\n",
811811
]];
812812
assert_eq!(expected, actual);

datafusion/expr/src/logical_plan/plan.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,7 @@ impl LogicalPlan {
12081208
self.with_new_exprs(new_exprs, &new_inputs_with_values)
12091209
}
12101210

1211-
/// Walk the logical plan, find any `PlaceHolder` tokens, and return a map of their IDs and DataTypes
1211+
/// Walk the logical plan, find any `Placeholder` tokens, and return a map of their IDs and DataTypes
12121212
pub fn get_parameter_types(
12131213
&self,
12141214
) -> Result<HashMap<String, Option<DataType>>, DataFusionError> {

datafusion/optimizer/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Looking at the `EXPLAIN` output we can see that the optimizer has effectively re
153153
| logical_plan | Projection: Int64(3) AS Int64(1) + Int64(2) |
154154
| | EmptyRelation |
155155
| physical_plan | ProjectionExec: expr=[3 as Int64(1) + Int64(2)] |
156-
| | EmptyExec: produce_one_row=true |
156+
| | PlaceholderRowExec |
157157
| | |
158158
+---------------+-------------------------------------------------+
159159
```
@@ -318,15 +318,15 @@ In the following example, the `type_coercion` and `simplify_expressions` passes
318318
| logical_plan | Projection: Utf8("3.2") AS foo |
319319
| | EmptyRelation |
320320
| initial_physical_plan | ProjectionExec: expr=[3.2 as foo] |
321-
| | EmptyExec: produce_one_row=true |
321+
| | PlaceholderRowExec |
322322
| | |
323323
| physical_plan after aggregate_statistics | SAME TEXT AS ABOVE |
324324
| physical_plan after join_selection | SAME TEXT AS ABOVE |
325325
| physical_plan after coalesce_batches | SAME TEXT AS ABOVE |
326326
| physical_plan after repartition | SAME TEXT AS ABOVE |
327327
| physical_plan after add_merge_exec | SAME TEXT AS ABOVE |
328328
| physical_plan | ProjectionExec: expr=[3.2 as foo] |
329-
| | EmptyExec: produce_one_row=true |
329+
| | PlaceholderRowExec |
330330
| | |
331331
+------------------------------------------------------------+---------------------------------------------------------------------------+
332332
```

datafusion/physical-plan/src/display.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
132132
/// ```dot
133133
/// strict digraph dot_plan {
134134
// 0[label="ProjectionExec: expr=[id@0 + 2 as employee.id + Int32(2)]",tooltip=""]
135-
// 1[label="EmptyExec: produce_one_row=false",tooltip=""]
135+
// 1[label="EmptyExec",tooltip=""]
136136
// 0 -> 1
137137
// }
138138
/// ```

0 commit comments

Comments
 (0)