Skip to content

Conversation

@NGA-TRAN
Copy link
Contributor

@NGA-TRAN NGA-TRAN commented May 27, 2021

Which issue does this PR close?

Closes #430

Rationale for this change

What changes are included in this PR?

There are 2 main changes:

  1. Fix the display of all LogicalPlan's display_ functions to have them display the plan content for not only executing plans but also the explain ones
  2. Propagate the optimization down the plan of for the explain

Are there any user-facing changes?

. Number 1 won't because they are currently used for debug only
. Number 2 will help other TableProvider to push their predicate down correctly (ref: https://github.com/influxdata/influxdb_iox/issues/1538)

let actual = format!("{}", plan.display_indent_schema());
assert_eq!(expected, actual);
// Verify the text format of the plan
let expected = "Explain";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the output of the logical plan for explain only incldues the word "Explain". Should we add the plan of the explain's select?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think including the plan tree like

Explain
  Project
    Filter
      Scan

Makes more sense than the current output of:

Explain

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree. I actually made this happen in a different branch but want to verify with you first. Will bring it in here

4[shape=box label=\"Explain\\nSchema: [plan_type:Utf8, plan:Utf8]\"]\n
}\n
}\n
// End DataFusion GraphViz Plan";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, the graphviz has nothing but Explain and the explain's schema node. Should it includes full explain of its plan's nodes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should include the actual plan that is being explained

let actual = format!("{}", plan.display_indent_schema());
assert_eq!(expected, actual);
// Verify the text format of the plan
let expected = "Explain";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, display of optimized logical plan has almost nothing in there

graph[label=\"Detailed LogicalPlan\"]\n
4[shape=box label=\"Explain\\nSchema: [plan_type:Utf8, plan:Utf8]\"]\n
}\n
}\n
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, graphviz does not have any useful info

let msg = format!("Creating physical plan for '{}': {:?}", sql, plan);
let plan = ctx.create_physical_plan(&plan).expect(&msg);
// Verify the text format of the plan
let expected = "ExplainExec";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, display of physical plan has no useful info at all

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think including the input to the Explain node makes sense. Any thoughts @Dandandan or @andygrove ?

let actual = format!("{}", plan.display_indent_schema());
assert_eq!(expected, actual);
// Verify the text format of the plan
let expected = "Explain";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think including the plan tree like

Explain
  Project
    Filter
      Scan

Makes more sense than the current output of:

Explain

4[shape=box label=\"Explain\\nSchema: [plan_type:Utf8, plan:Utf8]\"]\n
}\n
}\n
// End DataFusion GraphViz Plan";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should include the actual plan that is being explained

@andygrove
Copy link
Member

I think including the input to the Explain node makes sense. Any thoughts @Dandandan or @andygrove ?

Makes sense to me

}
true
}
LogicalPlan::Explain { plan, .. } => plan.accept(visitor)?,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the fix that enables LogicalPlan's display_... functions to show all info of the plan. The newly added tests capture this fix.

LogicalPlan::Limit { input, .. } => vec![input],
LogicalPlan::Extension { node } => node.inputs(),
LogicalPlan::Union { inputs, .. } => inputs.iter().collect(),
LogicalPlan::Explain { plan, .. } => vec![plan],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the fix that progpagates the optimization down the plan explain

LogicalPlan::Explain { .. } => {
// push the optimization to the plan of this explain
push_down(&state, plan)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is related to the fix to propagate the optimization down

@NGA-TRAN NGA-TRAN changed the title test: display of each query plan during plan generation fix: display the content of debug explain May 28, 2021
Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes look good to me @NGA-TRAN -- thank you.

I had a suggestion on how to make the tests perhaps easier to maintain (and easier to see what was different)

| LogicalPlan::EmptyRelation { .. }
| LogicalPlan::CreateExternalTable { .. }
| LogicalPlan::Explain { .. } => vec![],
//| LogicalPlan::Explain { .. }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//| LogicalPlan::Explain { .. }

I think we can remove this line entirely (no need to leave it in)

Filter: #c2 Gt Int64(10) [c1:Utf8, c2:Int32]\n
TableScan: aggregate_test_100 projection=Some([0, 1]) [c1:Utf8, c2:Int32]";
let actual = format!("{}", plan.display_indent_schema());
assert_eq!(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests look somewhat challenging to maintain. What do you think about the following pattern (mostly copied from assert_batches_eq!:

let expected_lines = vec![
  "Explain [plan_type:Utf8, plan:Utf8]",
  "  Projection: #c1 [c1:Utf8]",
  ...
 ];

let formatted = plan.display_indent_schema().to_string();
let actual_lines: Vec<&str> = formatted.trim().lines().collect();

assert_eq!(
  expected_lines, actual_lines,
  "\n\nexpected:\n\n{:#?}\nactual:\n\n{:#?}\n\n",
  expected_lines, actual_lines
);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

Copy link
Contributor Author

@NGA-TRAN NGA-TRAN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @alamb for your review comments. I have addressed them.

Filter: #c2 Gt Int64(10) [c1:Utf8, c2:Int32]\n
TableScan: aggregate_test_100 projection=Some([0, 1]) [c1:Utf8, c2:Int32]";
let actual = format!("{}", plan.display_indent_schema());
assert_eq!(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

Copy link
Contributor

@alamb alamb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is looking great @NGA-TRAN -- thank you

Copy link
Member

@jorgecarleitao jorgecarleitao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Impressive testing, @NGA-TRAN 💯

@alamb
Copy link
Contributor

alamb commented Jun 1, 2021

@NGA-TRAN it looks like this may have failed on windows: https://github.com/apache/arrow-datafusion/pull/434/checks?check_run_id=2720284528

@NGA-TRAN
Copy link
Contributor Author

NGA-TRAN commented Jun 1, 2021

| @NGA-TRAN it looks like this may have failed on windows: https://github.com/apache/arrow-datafusion/pull/434/checks?check_run_id=2720284528

Silly me. Working on it. Thanks @alamb

@codecov-commenter
Copy link

Codecov Report

Merging #434 (373a347) into master (6c050b8) will increase coverage by 0.11%.
The diff coverage is 88.79%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #434      +/-   ##
==========================================
+ Coverage   75.72%   75.84%   +0.11%     
==========================================
  Files         143      153      +10     
  Lines       23910    25872    +1962     
==========================================
+ Hits        18107    19622    +1515     
- Misses       5803     6250     +447     
Impacted Files Coverage Δ
datafusion/src/logical_plan/plan.rs 80.62% <50.00%> (-0.58%) ⬇️
datafusion/tests/sql.rs 99.27% <90.00%> (-0.62%) ⬇️
datafusion/src/optimizer/filter_push_down.rs 97.79% <100.00%> (+0.05%) ⬆️
datafusion-cli/src/print_format.rs 81.25% <0.00%> (-9.17%) ⬇️
...ta/rust/core/src/serde/physical_plan/from_proto.rs 39.78% <0.00%> (-7.62%) ⬇️
datafusion/src/physical_plan/mod.rs 78.70% <0.00%> (-6.01%) ⬇️
...lista/rust/core/src/serde/logical_plan/to_proto.rs 62.40% <0.00%> (-5.43%) ⬇️
...sta/rust/core/src/serde/logical_plan/from_proto.rs 36.22% <0.00%> (-3.97%) ⬇️
datafusion/src/physical_plan/parquet.rs 82.19% <0.00%> (-3.61%) ⬇️
datafusion/src/logical_plan/operators.rs 77.14% <0.00%> (-2.86%) ⬇️
... and 57 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6c050b8...373a347. Read the comment docs.

@NGA-TRAN
Copy link
Contributor Author

NGA-TRAN commented Jun 1, 2021

@alamb Finally all checks have passed :)

@alamb alamb merged commit 1601112 into apache:master Jun 1, 2021
@houqp houqp added datafusion enhancement New feature or request labels Jul 30, 2021
H0TB0X420 pushed a commit to H0TB0X420/datafusion that referenced this pull request Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LogicalPlan::inputs function should return the input plan for Explain enum

6 participants