Skip to content

Commit 5b5b90d

Browse files
committed
Differentiate 0-row and 1-row EmptyRelation in EXPLAIN
The `LogicalPlan::EmptyRelation` can produce no rows or exactly 1 null (placeholder) row of the requested schema. When viewing EXPLAIN output of a LogicalPlan it's good to know which one is the case.
1 parent b786b9a commit 5b5b90d

32 files changed

+338
-338
lines changed

datafusion-cli/tests/snapshots/cli_quick_test@can_see_indent_format.snap

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ info:
55
args:
66
- "--command"
77
- EXPLAIN FORMAT indent SELECT 123
8-
snapshot_kind: text
98
---
109
success: true
1110
exit_code: 0
@@ -15,7 +14,7 @@ exit_code: 0
1514
| plan_type | plan |
1615
+---------------+------------------------------------------+
1716
| logical_plan | Projection: Int64(123) |
18-
| | EmptyRelation |
17+
| | EmptyRelation: rows=1 |
1918
| physical_plan | ProjectionExec: expr=[123 as Int64(123)] |
2019
| | PlaceholderRowExec |
2120
| | |

datafusion/core/tests/dataframe/mod.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,7 @@ async fn join_on_filter_datatype() -> Result<()> {
12131213
JoinType::Inner,
12141214
Some(Expr::Literal(ScalarValue::Null, None)),
12151215
)?;
1216-
assert_snapshot!(join.into_optimized_plan().unwrap(), @"EmptyRelation");
1216+
assert_snapshot!(join.into_optimized_plan().unwrap(), @"EmptyRelation: rows=0");
12171217

12181218
// JOIN ON expression must be boolean type
12191219
let join = left.join_on(right, JoinType::Inner, Some(lit("TRUE")))?;
@@ -2751,7 +2751,7 @@ async fn test_count_wildcard_on_where_exist() -> Result<()> {
27512751
| logical_plan | LeftSemi Join: |
27522752
| | TableScan: t1 projection=[a, b] |
27532753
| | SubqueryAlias: __correlated_sq_1 |
2754-
| | EmptyRelation |
2754+
| | EmptyRelation: rows=1 |
27552755
| physical_plan | NestedLoopJoinExec: join_type=RightSemi |
27562756
| | PlaceholderRowExec |
27572757
| | DataSourceExec: partitions=1, partition_sizes=[1] |
@@ -2787,7 +2787,7 @@ async fn test_count_wildcard_on_where_exist() -> Result<()> {
27872787
| logical_plan | LeftSemi Join: |
27882788
| | TableScan: t1 projection=[a, b] |
27892789
| | SubqueryAlias: __correlated_sq_1 |
2790-
| | EmptyRelation |
2790+
| | EmptyRelation: rows=1 |
27912791
| physical_plan | NestedLoopJoinExec: join_type=RightSemi |
27922792
| | PlaceholderRowExec |
27932793
| | DataSourceExec: partitions=1, partition_sizes=[1] |
@@ -4934,11 +4934,11 @@ async fn test_dataframe_placeholder_missing_param_values() -> Result<()> {
49344934

49354935
assert_snapshot!(
49364936
actual,
4937-
@r###"
4937+
@r"
49384938
Filter: a = $0 [a:Int32]
49394939
Projection: Int32(1) AS a [a:Int32]
4940-
EmptyRelation []
4941-
"###
4940+
EmptyRelation: rows=1 []
4941+
"
49424942
);
49434943

49444944
// Executing LogicalPlans with placeholders that don't have bound values
@@ -4967,11 +4967,11 @@ async fn test_dataframe_placeholder_missing_param_values() -> Result<()> {
49674967

49684968
assert_snapshot!(
49694969
actual,
4970-
@r###"
4970+
@r"
49714971
Filter: a = Int32(3) [a:Int32]
49724972
Projection: Int32(1) AS a [a:Int32]
4973-
EmptyRelation []
4974-
"###
4973+
EmptyRelation: rows=1 []
4974+
"
49754975
);
49764976

49774977
// N.B., the test is basically `SELECT 1 as a WHERE a = 3;` which returns no results.
@@ -4998,10 +4998,10 @@ async fn test_dataframe_placeholder_column_parameter() -> Result<()> {
49984998

49994999
assert_snapshot!(
50005000
actual,
5001-
@r###"
5001+
@r"
50025002
Projection: $1 [$1:Null;N]
5003-
EmptyRelation []
5004-
"###
5003+
EmptyRelation: rows=1 []
5004+
"
50055005
);
50065006

50075007
// Executing LogicalPlans with placeholders that don't have bound values
@@ -5028,10 +5028,10 @@ async fn test_dataframe_placeholder_column_parameter() -> Result<()> {
50285028

50295029
assert_snapshot!(
50305030
actual,
5031-
@r###"
5031+
@r"
50325032
Projection: Int32(3) AS $1 [$1:Null;N]
5033-
EmptyRelation []
5034-
"###
5033+
EmptyRelation: rows=1 []
5034+
"
50355035
);
50365036

50375037
assert_snapshot!(
@@ -5067,11 +5067,11 @@ async fn test_dataframe_placeholder_like_expression() -> Result<()> {
50675067

50685068
assert_snapshot!(
50695069
actual,
5070-
@r###"
5070+
@r#"
50715071
Filter: a LIKE $1 [a:Utf8]
50725072
Projection: Utf8("foo") AS a [a:Utf8]
5073-
EmptyRelation []
5074-
"###
5073+
EmptyRelation: rows=1 []
5074+
"#
50755075
);
50765076

50775077
// Executing LogicalPlans with placeholders that don't have bound values
@@ -5100,11 +5100,11 @@ async fn test_dataframe_placeholder_like_expression() -> Result<()> {
51005100

51015101
assert_snapshot!(
51025102
actual,
5103-
@r###"
5103+
@r#"
51045104
Filter: a LIKE Utf8("f%") [a:Utf8]
51055105
Projection: Utf8("foo") AS a [a:Utf8]
5106-
EmptyRelation []
5107-
"###
5106+
EmptyRelation: rows=1 []
5107+
"#
51085108
);
51095109

51105110
assert_snapshot!(

datafusion/core/tests/execution/logical_plan.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ fn inline_scan_projection_test() -> Result<()> {
128128
@r"
129129
SubqueryAlias: ?table?
130130
Projection: a
131-
EmptyRelation
131+
EmptyRelation: rows=0
132132
"
133133
);
134134

datafusion/core/tests/optimizer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn select_arrow_cast() {
6262
plan,
6363
@r#"
6464
Projection: Float64(1234) AS f64, LargeUtf8("foo") AS large
65-
EmptyRelation
65+
EmptyRelation: rows=1
6666
"#
6767
);
6868
}

datafusion/expr/src/logical_plan/plan.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1720,7 +1720,10 @@ impl LogicalPlan {
17201720
impl Display for Wrapper<'_> {
17211721
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
17221722
match self.0 {
1723-
LogicalPlan::EmptyRelation(_) => write!(f, "EmptyRelation"),
1723+
LogicalPlan::EmptyRelation(EmptyRelation { produce_one_row, schema: _ }) => {
1724+
let rows = if *produce_one_row { 1 } else { 0 };
1725+
write!(f, "EmptyRelation: rows={rows}")
1726+
},
17241727
LogicalPlan::RecursiveQuery(RecursiveQuery {
17251728
is_distinct, ..
17261729
}) => {

0 commit comments

Comments
 (0)