Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Interface for physical plan invariant checking. #13986
Interface for physical plan invariant checking. #13986
Changes from 1 commit
3b03f6c
da6cc17
5760792
94482d1
ad15c85
5e065e1
4a6718f
10af0bd
e71ef9f
9d854a6
7b2f54b
8da07d0
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure what should be the default set. The SanityCheckPlan does exactly what I had been thinking:
datafusion/datafusion/core/src/physical_optimizer/sanity_checker.rs
Lines 41 to 47 in 38ccb00
Also, I think this optimizer pass does not mutate anything and instead validates?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we change the SanityPlanChecker be an invariant checker instead, and then (a) run after the other optimizer rules are applied (current behavior) as well as (b) after each optimizer rule in debug mode -- would this be useful?
The added debug mode check could help isolate when a user-defined optimizer rule extension, or a user defined ExecutionPlan node, does not work well with the DF upgrade (e.g. changes in DF plan nodes or optimizer rules).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conceptually, sanity checking is a "more general" process -- it verifies that any two operators that exchange data (i.e. one's output feeds the other's input) are compatible. So I don't think we can "change" it to be an invariant checker, but we can extend it to also check "invariants" of each individual operator (however they are defined by an
ExecutionPlan
) as it traverses the plan tree.However, we can not blindly run sanity checking after every rule. Why? Because rules have the following types regarding their input/output plan validity:
ProjectionPushdown
). These are typically applied at later stages in the optimization/plan construction process.EnforceSorting
andEnforceDistribution
). These can be applied any time, but are typically applied in the middle of the optimization/plan construction process.JoinSelection
is this way). These are typically applied early in the optimization/plan construction process.As of this writing, we don't have a formal cut-off point in our list of rules whereafter plans remain valid, but I suspect they do after
EnforceSorting
. In debug/upgrade mode, we can applySanityCheckPlan
after every rule after that point.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the logical planner we have a split between
AnalyzerRule
s that make plans Executable (e.g. by coercing types, etc)OptimizerRule
s that don't change the plan semantics (e.g. output types are the same, etc)It seems like maybe we could make the same separation for physical optimizer rules as well ("not yet executable") and ("read to execute"),
This was surprising to me (I am not doubting it). It looked at the other passes, and it seems there are a few others
datafusion/datafusion/core/src/physical_optimizer/optimizer.rs
Lines 56 to 72 in 264f4c5
🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this sentiment. It seems to me that the "SanityChecker" is verifying invariants that should be true for all nodes (regardless of what they do -- for example that the declared required input sort is the same as the produced output sort)
Thus, focusing on ExecutionPlan specific invariants might be a good first step.
Some simple invariants to start with I could imagine are:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you both for the reviews. Apologies on the delayed response.
To summarize this nice explanation from @ozankabak , the
Executable
-ness of the output plan (post optimizer run) is dependent upon what each optimizer run does and if the input plan was valid. Although it is surprising, we currently permit optimizer rules to output invalid plans.As such, I added a
PhysicalOptimizerRule::executable_check
which defines the expected behavior per optimizer rule (see commit here). This also helps us surface which rules may produce unexecutable plans, as well as when we can define an output plan as "executable".Next, the
InvariantChecker
was expanded to conditionally check the executableness based upon the declared expectations. If the plan is expected to be executable, then the invariants are checked for both (a) Datafusion internal definition of "executable" from the sanity plan check, as well as (b) any defined invariants on ExecutionPlan nodes (including user extension nodes).Finally, there is an example test case added which demonstrates how this could be useful for catching incompatibilities with users' PhysicalOptimizerRule extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When running our current sqllogic test suite, I found that most rules were passing through the same validity of plan. For example, the
ProjectionPushdown
usually had an "unexecutable" plan (due to an early OutputRequirements rule output) and the pushdown rule itself did not change the validity.That is why the default impl behavior of the
PhysicalOptimizerRule::executable_check
is to pass through the current plan validity expectation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has now changed per #13986 (review).