-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Planning: Rule to push projection through join into TableScan #27175
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
base: master
Are you sure you want to change the base?
Planning: Rule to push projection through join into TableScan #27175
Conversation
Reviewer's GuideIntroduces a new optimizer rule that pushes deterministic, single-side Project expressions through a Join into the underlying TableScans (especially useful for cross-connector joins), updates the planner to register the rule, and adds/adjusts tests to validate and reflect the new behavior. Sequence diagram for projection pushdown through join during planningsequenceDiagram
participant "Planner"
participant "PushProjectionThroughJoinIntoTableScan"
participant "ProjectNode"
participant "JoinNode"
participant "TableScan (Left)"
participant "TableScan (Right)"
"Planner"->>"PushProjectionThroughJoinIntoTableScan": Apply rule to ProjectNode above JoinNode
"PushProjectionThroughJoinIntoTableScan"->>"ProjectNode": Inspect assignments
"PushProjectionThroughJoinIntoTableScan"->>"JoinNode": Inspect join type and criteria
alt Projections are deterministic and reference only one side
"PushProjectionThroughJoinIntoTableScan"->>"TableScan (Left)": Push left-side projections
"PushProjectionThroughJoinIntoTableScan"->>"TableScan (Right)": Push right-side projections
end
"PushProjectionThroughJoinIntoTableScan"->>"JoinNode": Create new JoinNode with projected children
alt Remaining projections
"PushProjectionThroughJoinIntoTableScan"->>"ProjectNode": Add remaining projections above join
end
"PushProjectionThroughJoinIntoTableScan"-->>"Planner": Return transformed plan
Class diagram for the new PushProjectionThroughJoinIntoTableScan ruleclassDiagram
class PushProjectionThroughJoinIntoTableScan {
+apply(ProjectNode, Captures, Context) Result
+getPattern() Pattern<ProjectNode>
}
PushProjectionThroughJoinIntoTableScan --|> Rule
class Rule {
}
class ProjectNode {
}
class JoinNode {
}
class Assignments {
}
class PlanNode {
}
PushProjectionThroughJoinIntoTableScan o-- ProjectNode
PushProjectionThroughJoinIntoTableScan o-- JoinNode
PushProjectionThroughJoinIntoTableScan o-- Assignments
PushProjectionThroughJoinIntoTableScan o-- PlanNode
Class diagram for updated PlanOptimizers registrationclassDiagram
class PlanOptimizers {
+PlanOptimizers(...)
}
class PushProjectionThroughJoinIntoTableScan {
}
PlanOptimizers o-- PushProjectionThroughJoinIntoTableScan
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
7d6fbf9 to
503519c
Compare
A new rule `PushProjectionThroughJoinIntoTableScan` is introduced to push projections that appear above a join down to the table scans on either side of the join. This optimization is particularly beneficial for cross-connector joins where the join itself cannot be pushed down to the connectors. The rule applies when: - All projection expressions are deterministic. - Each projection expression references columns from only one side of the join. - For outer joins, projections on the non-preserved side are not pushed to maintain correctness. This transformation creates new `ProjectNode`s on each side of the join, potentially followed by the original `ProjectNode` if some expressions could not be pushed down. The rule also ensures that symbols required by the join criteria and filter, as well as the original project's output symbols, are preserved through identity projections on the respective sides.
503519c to
af993f1
Compare
| * expression references columns from only one side of the join - For outer joins, projections on | ||
| * the non-preserved side are not pushed (to maintain correctness) | ||
| */ | ||
| public class PushProjectionThroughJoinIntoTableScan |
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 is more of a push projection through join right ? TableScan would be a bit redundant here
| * Project(x, y) -- identity projections | ||
| * Join(a = b) | ||
| * Project(x := f(a), a) -- pushed down | ||
| * TableScan(a, ...) | ||
| * Project(y := g(b), b) -- pushed down | ||
| * TableScan(b, ...) |
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.
But if the Join filters the data then these projection would be redundant right ?
Warning
This is still work in progress, working on some test cases.
Description
A new rule
PushProjectionThroughJoinIntoTableScanwas introduced to push projections that appear above a join down to the table scans on either side of the join. This optimization is particularly beneficial for cross-connector joins where the join itself cannot be pushed down to the connectors.The rule applies when:
This transformation creates new
ProjectNodes on each side of the join, potentially followed by the originalProjectNodeif some expressions could not be pushed down. The rule also ensures that symbols required by the join criteria and filter, as well as the original project's output symbols, are preserved through identity projections on the respective sides.Additional context and related issues
Release notes
( ) This is not user-visible or is docs only, and no release notes are required.
( ) Release notes are required. Please propose a release note for me.
( ) Release notes are required, with the following suggested text: