pub struct EliminateOuterJoin;Expand description
Attempt to simplify outer joins when filters make their null-padded rows impossible to observe.
Outer joins are generally more expensive than inner joins and can block predicate pushdown and other optimizations. When a filter above an outer join removes every row the join would add for unmatched input rows, the join can be changed to a cheaper join type.
For example:
SELECT ...
FROM a LEFT JOIN b ON ...
WHERE b.xx = 100For unmatched rows from a, the LEFT JOIN would produce a row with
b.xx set to NULL. The predicate b.xx = 100 does not pass for those
rows, so the query does not need the LEFT JOIN’s null-padded output and
the join can be rewritten as an inner join.
The same reasoning can also simplify FULL joins to LEFT, RIGHT, or INNER joins when filters remove the rows padded on one or both sides.
This rule looks for a filter above an outer join:
Filter(predicate)
Join(LEFT/RIGHT/FULL)It also handles plan shapes where projection pruning has inserted one or more Projection nodes between the filter and join:
Filter(predicate over projection output)
Projection(...)
...
Join(LEFT/RIGHT/FULL)In the projection case, the rule rewrites a copy of the predicate through each Projection so it can analyze the predicate against the Join inputs. The original filter predicate and Projection nodes are preserved when the plan is rebuilt.
Implementations§
Trait Implementations§
Source§impl Debug for EliminateOuterJoin
impl Debug for EliminateOuterJoin
Source§impl Default for EliminateOuterJoin
impl Default for EliminateOuterJoin
Source§fn default() -> EliminateOuterJoin
fn default() -> EliminateOuterJoin
Source§impl OptimizerRule for EliminateOuterJoin
Attempt to eliminate outer joins.
impl OptimizerRule for EliminateOuterJoin
Attempt to eliminate outer joins.
Source§fn apply_order(&self) -> Option<ApplyOrder>
fn apply_order(&self) -> Option<ApplyOrder>
ApplyOrder for details. Read moreSource§fn supports_rewrite(&self) -> bool
fn supports_rewrite(&self) -> bool
This method is no longer used
Source§fn rewrite(
&self,
plan: LogicalPlan,
_config: &dyn OptimizerConfig,
) -> Result<Transformed<LogicalPlan>>
fn rewrite( &self, plan: LogicalPlan, _config: &dyn OptimizerConfig, ) -> Result<Transformed<LogicalPlan>>
plan to an optimized form, returning Transformed::yes
if the plan was rewritten and Transformed::no if it was not. Read moreAuto Trait Implementations§
impl Freeze for EliminateOuterJoin
impl RefUnwindSafe for EliminateOuterJoin
impl Send for EliminateOuterJoin
impl Sync for EliminateOuterJoin
impl Unpin for EliminateOuterJoin
impl UnsafeUnpin for EliminateOuterJoin
impl UnwindSafe for EliminateOuterJoin
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more