Skip to content

Differentiate 0-row and 1-row EmptyRelation in EXPLAIN #17145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ info:
args:
- "--command"
- EXPLAIN FORMAT indent SELECT 123
snapshot_kind: text
---
success: true
exit_code: 0
Expand All @@ -15,7 +14,7 @@ exit_code: 0
| plan_type | plan |
+---------------+------------------------------------------+
| logical_plan | Projection: Int64(123) |
| | EmptyRelation |
| | EmptyRelation: rows=1 |
| physical_plan | ProjectionExec: expr=[123 as Int64(123)] |
| | PlaceholderRowExec |
| | |
Expand Down
42 changes: 21 additions & 21 deletions datafusion/core/tests/dataframe/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ async fn join_on_filter_datatype() -> Result<()> {
JoinType::Inner,
Some(Expr::Literal(ScalarValue::Null, None)),
)?;
assert_snapshot!(join.into_optimized_plan().unwrap(), @"EmptyRelation");
assert_snapshot!(join.into_optimized_plan().unwrap(), @"EmptyRelation: rows=0");

// JOIN ON expression must be boolean type
let join = left.join_on(right, JoinType::Inner, Some(lit("TRUE")))?;
Expand Down Expand Up @@ -2751,7 +2751,7 @@ async fn test_count_wildcard_on_where_exist() -> Result<()> {
| logical_plan | LeftSemi Join: |
| | TableScan: t1 projection=[a, b] |
| | SubqueryAlias: __correlated_sq_1 |
| | EmptyRelation |
| | EmptyRelation: rows=1 |
| physical_plan | NestedLoopJoinExec: join_type=RightSemi |
| | PlaceholderRowExec |
| | DataSourceExec: partitions=1, partition_sizes=[1] |
Expand Down Expand Up @@ -2787,7 +2787,7 @@ async fn test_count_wildcard_on_where_exist() -> Result<()> {
| logical_plan | LeftSemi Join: |
| | TableScan: t1 projection=[a, b] |
| | SubqueryAlias: __correlated_sq_1 |
| | EmptyRelation |
| | EmptyRelation: rows=1 |
| physical_plan | NestedLoopJoinExec: join_type=RightSemi |
| | PlaceholderRowExec |
| | DataSourceExec: partitions=1, partition_sizes=[1] |
Expand Down Expand Up @@ -4934,11 +4934,11 @@ async fn test_dataframe_placeholder_missing_param_values() -> Result<()> {

assert_snapshot!(
actual,
@r###"
@r"
Filter: a = $0 [a:Int32]
Projection: Int32(1) AS a [a:Int32]
EmptyRelation []
"###
EmptyRelation: rows=1 []
"
);

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

assert_snapshot!(
actual,
@r###"
@r"
Filter: a = Int32(3) [a:Int32]
Projection: Int32(1) AS a [a:Int32]
EmptyRelation []
"###
EmptyRelation: rows=1 []
"
);

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

assert_snapshot!(
actual,
@r###"
@r"
Projection: $1 [$1:Null;N]
EmptyRelation []
"###
EmptyRelation: rows=1 []
"
);

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

assert_snapshot!(
actual,
@r###"
@r"
Projection: Int32(3) AS $1 [$1:Null;N]
EmptyRelation []
"###
EmptyRelation: rows=1 []
"
);

assert_snapshot!(
Expand Down Expand Up @@ -5067,11 +5067,11 @@ async fn test_dataframe_placeholder_like_expression() -> Result<()> {

assert_snapshot!(
actual,
@r###"
@r#"
Filter: a LIKE $1 [a:Utf8]
Projection: Utf8("foo") AS a [a:Utf8]
EmptyRelation []
"###
EmptyRelation: rows=1 []
"#
);

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

assert_snapshot!(
actual,
@r###"
@r#"
Filter: a LIKE Utf8("f%") [a:Utf8]
Projection: Utf8("foo") AS a [a:Utf8]
EmptyRelation []
"###
EmptyRelation: rows=1 []
"#
);

assert_snapshot!(
Expand Down
2 changes: 1 addition & 1 deletion datafusion/core/tests/execution/logical_plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ fn inline_scan_projection_test() -> Result<()> {
@r"
SubqueryAlias: ?table?
Projection: a
EmptyRelation
EmptyRelation: rows=0
"
);

Expand Down
2 changes: 1 addition & 1 deletion datafusion/core/tests/optimizer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ fn select_arrow_cast() {
plan,
@r#"
Projection: Float64(1234) AS f64, LargeUtf8("foo") AS large
EmptyRelation
EmptyRelation: rows=1
"#
);
}
Expand Down
5 changes: 4 additions & 1 deletion datafusion/expr/src/logical_plan/plan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1720,7 +1720,10 @@ impl LogicalPlan {
impl Display for Wrapper<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self.0 {
LogicalPlan::EmptyRelation(_) => write!(f, "EmptyRelation"),
LogicalPlan::EmptyRelation(EmptyRelation { produce_one_row, schema: _ }) => {
let rows = if *produce_one_row { 1 } else { 0 };
write!(f, "EmptyRelation: rows={rows}")
},
LogicalPlan::RecursiveQuery(RecursiveQuery {
is_distinct, ..
}) => {
Expand Down
Loading