Skip to main content

EliminateOuterJoin

Struct EliminateOuterJoin 

Source
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 = 100

For 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

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for EliminateOuterJoin

Source§

fn default() -> EliminateOuterJoin

Returns the “default value” for a type. Read more
Source§

impl OptimizerRule for EliminateOuterJoin

Attempt to eliminate outer joins.

Source§

fn name(&self) -> &str

A human readable name for this optimizer rule
Source§

fn apply_order(&self) -> Option<ApplyOrder>

How should the rule be applied by the optimizer? See comments on ApplyOrder for details. Read more
Source§

fn supports_rewrite(&self) -> bool

👎Deprecated since 47.0.0:

This method is no longer used

Does this rule support rewriting owned plans (rather than by reference)?
Source§

fn rewrite( &self, plan: LogicalPlan, _config: &dyn OptimizerConfig, ) -> Result<Transformed<LogicalPlan>>

Try to rewrite plan to an optimized form, returning Transformed::yes if the plan was rewritten and Transformed::no if it was not. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.