Fixes hash left join into for loop left join optimization

It can inject variables into projections
pull/519/head
Tpt 2 years ago committed by Thomas Tanon
parent 4cc9e4008b
commit 22f990344f
  1. 25
      lib/src/sparql/plan_builder.rs

@ -1237,7 +1237,7 @@ impl<'a> PlanBuilder<'a> {
} }
fn can_use_for_loop_left_join(node: &PlanNode) -> bool { fn can_use_for_loop_left_join(node: &PlanNode) -> bool {
// We forbid MINUS and SERVICE in for loop left joins // We forbid MINUS, SERVICE and everything that affects cardinality in for loop left joins
match node { match node {
PlanNode::StaticBindings { .. } PlanNode::StaticBindings { .. }
| PlanNode::QuadPattern { .. } | PlanNode::QuadPattern { .. }
@ -1245,10 +1245,6 @@ impl<'a> PlanBuilder<'a> {
PlanNode::Filter { child, .. } PlanNode::Filter { child, .. }
| PlanNode::Extend { child, .. } | PlanNode::Extend { child, .. }
| PlanNode::Sort { child, .. } | PlanNode::Sort { child, .. }
| PlanNode::HashDeduplicate { child }
| PlanNode::Reduced { child }
| PlanNode::Skip { child, .. }
| PlanNode::Limit { child, .. }
| PlanNode::Project { child, .. } | PlanNode::Project { child, .. }
| PlanNode::Aggregate { child, .. } => Self::can_use_for_loop_left_join(child), | PlanNode::Aggregate { child, .. } => Self::can_use_for_loop_left_join(child),
PlanNode::Union { children } => { PlanNode::Union { children } => {
@ -1260,7 +1256,12 @@ impl<'a> PlanBuilder<'a> {
| PlanNode::HashLeftJoin { left, right, .. } => { | PlanNode::HashLeftJoin { left, right, .. } => {
Self::can_use_for_loop_left_join(left) && Self::can_use_for_loop_left_join(right) Self::can_use_for_loop_left_join(left) && Self::can_use_for_loop_left_join(right)
} }
PlanNode::AntiJoin { .. } | PlanNode::Service { .. } => false, PlanNode::AntiJoin { .. }
| PlanNode::Service { .. }
| PlanNode::HashDeduplicate { .. }
| PlanNode::Reduced { .. }
| PlanNode::Skip { .. }
| PlanNode::Limit { .. } => false,
} }
} }
@ -1326,7 +1327,8 @@ impl<'a> PlanBuilder<'a> {
} }
PlanNode::Sort { child, .. } PlanNode::Sort { child, .. }
| PlanNode::HashDeduplicate { child } | PlanNode::HashDeduplicate { child }
| PlanNode::Reduced { child } => { | PlanNode::Reduced { child }
| PlanNode::Project { child, .. } => {
Self::add_left_join_problematic_variables(child, set); Self::add_left_join_problematic_variables(child, set);
} }
PlanNode::Skip { child, .. } | PlanNode::Limit { child, .. } => { PlanNode::Skip { child, .. } | PlanNode::Limit { child, .. } => {
@ -1344,15 +1346,6 @@ impl<'a> PlanBuilder<'a> {
Self::add_left_join_problematic_variables(child, set) Self::add_left_join_problematic_variables(child, set)
} }
} }
PlanNode::Project { mapping, child } => {
let mut child_bound = BTreeSet::new();
Self::add_left_join_problematic_variables(child, &mut child_bound);
for (child_i, output_i) in mapping.iter() {
if child_bound.contains(&child_i.encoded) {
set.insert(output_i.encoded);
}
}
}
PlanNode::Aggregate { PlanNode::Aggregate {
key_variables, key_variables,
aggregates, aggregates,

Loading…
Cancel
Save