pub struct OptionalMatchNode {
pub outer: Arc<LogicalPlan>,
pub optional: Arc<LogicalPlan>,
pub join_keys: Vec<(usize, usize)>,
pub inner_keep_idx: Vec<usize>,
/* private fields */
}Expand description
Physical node for OPTIONAL MATCH (LEFT OUTER semantics with openCypher
null-shaping over a sub-plan).
The physical layer (OptionalMatchExec in M13) left-joins the
outer (mandatory) input against the optional sub-plan on the shared
pattern variables (join_keys), preserving every outer
row and setting the optional-side columns to null when there is no match
— distinct from a SQL LEFT JOIN only in that the shared join-key columns
are not duplicated on the output (they belong to the outer side).
§Output schema
outer fields, followed by the optional fields that are not join keys,
each made nullable (an unmatched outer row nulls them all).
Fields§
§outer: Arc<LogicalPlan>The outer (mandatory) input.
optional: Arc<LogicalPlan>The optional sub-plan.
join_keys: Vec<(usize, usize)>Shared-variable join keys as (outer_col_idx, inner_col_idx) pairs,
resolved against the qualified input schemas at lowering time.
inner_keep_idx: Vec<usize>Inner (optional-side) column indices to append to the output, in order.
Excludes every shared-variable column — not merely the join-key
columns — because a shared variable’s whole node (e.g. a in
MATCH (a) OPTIONAL MATCH (a)-[:R]->(b)) is carried by the outer side;
appending its columns again would duplicate the var_<shared> fields.
Implementations§
Source§impl OptionalMatchNode
impl OptionalMatchNode
Sourcepub fn new(
outer: Arc<LogicalPlan>,
optional: Arc<LogicalPlan>,
join_keys: Vec<(usize, usize)>,
inner_keep_idx: Vec<usize>,
) -> Self
pub fn new( outer: Arc<LogicalPlan>, optional: Arc<LogicalPlan>, join_keys: Vec<(usize, usize)>, inner_keep_idx: Vec<usize>, ) -> Self
Create an optional-match node.
inner_keep_idx lists the optional plan’s column indices to append to
the output (every column of a shared variable already excluded — those
live on the outer side). Passed by the lowerer, which resolves them
against the qualified inner schema, so this crate needs no
graphforge-rel/graphforge-storage dependency. The node appends the corresponding
fields to the outer schema as nullable columns (an unmatched outer
row nulls them all).
Trait Implementations§
Source§impl Clone for OptionalMatchNode
impl Clone for OptionalMatchNode
Source§impl Debug for OptionalMatchNode
impl Debug for OptionalMatchNode
impl Eq for OptionalMatchNode
Source§impl Hash for OptionalMatchNode
impl Hash for OptionalMatchNode
Source§impl PartialEq for OptionalMatchNode
impl PartialEq for OptionalMatchNode
Source§impl PartialOrd for OptionalMatchNode
impl PartialOrd for OptionalMatchNode
impl StructuralPartialEq for OptionalMatchNode
Source§impl UserDefinedLogicalNodeCore for OptionalMatchNode
impl UserDefinedLogicalNodeCore for OptionalMatchNode
Source§fn inputs(&self) -> Vec<&LogicalPlan>
fn inputs(&self) -> Vec<&LogicalPlan>
Source§fn schema(&self) -> &DFSchemaRef
fn schema(&self) -> &DFSchemaRef
Source§fn expressions(&self) -> Vec<Expr>
fn expressions(&self) -> Vec<Expr>
Source§fn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result
fn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result
f for use in explain plan. Read moreSource§fn with_exprs_and_inputs(
&self,
_exprs: Vec<Expr>,
inputs: Vec<LogicalPlan>,
) -> DfResult<Self>
fn with_exprs_and_inputs( &self, _exprs: Vec<Expr>, inputs: Vec<LogicalPlan>, ) -> DfResult<Self>
UserDefinedLogicalNode with the specified children
and expressions. This function is used during optimization
when the plan is being rewritten and a new instance of the
UserDefinedLogicalNode must be created. Read moreSource§fn check_invariants(
&self,
_check: InvariantLevel,
) -> Result<(), DataFusionError>
fn check_invariants( &self, _check: InvariantLevel, ) -> Result<(), DataFusionError>
Source§fn prevent_predicate_push_down_columns(&self) -> HashSet<String>
fn prevent_predicate_push_down_columns(&self) -> HashSet<String>
Source§fn necessary_children_exprs(
&self,
_output_columns: &[usize],
) -> Option<Vec<Vec<usize>>>
fn necessary_children_exprs( &self, _output_columns: &[usize], ) -> Option<Vec<Vec<usize>>>
Source§fn supports_limit_pushdown(&self) -> bool
fn supports_limit_pushdown(&self) -> bool
true if a limit can be safely pushed down through this
UserDefinedLogicalNode node. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for OptionalMatchNode
impl !UnwindSafe for OptionalMatchNode
impl Freeze for OptionalMatchNode
impl Send for OptionalMatchNode
impl Sync for OptionalMatchNode
impl Unpin for OptionalMatchNode
impl UnsafeUnpin for OptionalMatchNode
Blanket Implementations§
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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 moreimpl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> UserDefinedLogicalNode for Twhere
T: UserDefinedLogicalNodeCore,
impl<T> UserDefinedLogicalNode for Twhere
T: UserDefinedLogicalNodeCore,
Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Source§fn inputs(&self) -> Vec<&LogicalPlan>
fn inputs(&self) -> Vec<&LogicalPlan>
Source§fn check_invariants(&self, check: InvariantLevel) -> Result<(), DataFusionError>
fn check_invariants(&self, check: InvariantLevel) -> Result<(), DataFusionError>
Source§fn expressions(&self) -> Vec<Expr>
fn expressions(&self) -> Vec<Expr>
Source§fn prevent_predicate_push_down_columns(&self) -> HashSet<String>
fn prevent_predicate_push_down_columns(&self) -> HashSet<String>
Source§fn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn fmt_for_explain(&self, f: &mut Formatter<'_>) -> Result<(), Error>
f for use in explain plan. Read moreSource§fn with_exprs_and_inputs(
&self,
exprs: Vec<Expr>,
inputs: Vec<LogicalPlan>,
) -> Result<Arc<dyn UserDefinedLogicalNode>, DataFusionError>
fn with_exprs_and_inputs( &self, exprs: Vec<Expr>, inputs: Vec<LogicalPlan>, ) -> Result<Arc<dyn UserDefinedLogicalNode>, DataFusionError>
UserDefinedLogicalNode with the specified children
and expressions. This function is used during optimization
when the plan is being rewritten and a new instance of the
UserDefinedLogicalNode must be created. Read moreSource§fn necessary_children_exprs(
&self,
output_columns: &[usize],
) -> Option<Vec<Vec<usize>>>
fn necessary_children_exprs( &self, output_columns: &[usize], ) -> Option<Vec<Vec<usize>>>
Source§fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool
fn dyn_eq(&self, other: &dyn UserDefinedLogicalNode) -> bool
Source§fn dyn_ord(&self, other: &dyn UserDefinedLogicalNode) -> Option<Ordering>
fn dyn_ord(&self, other: &dyn UserDefinedLogicalNode) -> Option<Ordering>
other, respecting requirements from PartialOrd.
Must return Some(Equal) if and only if self.dyn_eq(other).Source§fn supports_limit_pushdown(&self) -> bool
fn supports_limit_pushdown(&self) -> bool
true if a limit can be safely pushed down through this
UserDefinedLogicalNode node. Read more