diff --git a/lib/src/sparql/mod.rs b/lib/src/sparql/mod.rs index 0042421e..16c17f85 100644 --- a/lib/src/sparql/mod.rs +++ b/lib/src/sparql/mod.rs @@ -48,7 +48,7 @@ pub(crate) fn evaluate_query( spargebra::Query::Select { pattern, base_iri, .. } => { - let (plan, variables) = PlanBuilder::build(&dataset, &pattern)?; + let (plan, variables) = PlanBuilder::build(&dataset, &pattern, true)?; Ok(SimpleEvaluator::new( Rc::new(dataset), base_iri.map(Rc::new), @@ -67,7 +67,7 @@ pub(crate) fn evaluate_query( spargebra::Query::Ask { pattern, base_iri, .. } => { - let (plan, _) = PlanBuilder::build(&dataset, &pattern)?; + let (plan, _) = PlanBuilder::build(&dataset, &pattern, false)?; SimpleEvaluator::new( Rc::new(dataset), base_iri.map(Rc::new), @@ -81,7 +81,7 @@ pub(crate) fn evaluate_query( base_iri, .. } => { - let (plan, variables) = PlanBuilder::build(&dataset, &pattern)?; + let (plan, variables) = PlanBuilder::build(&dataset, &pattern, false)?; let construct = PlanBuilder::build_graph_template(&dataset, &template, variables); Ok(SimpleEvaluator::new( Rc::new(dataset), @@ -93,7 +93,7 @@ pub(crate) fn evaluate_query( spargebra::Query::Describe { pattern, base_iri, .. } => { - let (plan, _) = PlanBuilder::build(&dataset, &pattern)?; + let (plan, _) = PlanBuilder::build(&dataset, &pattern, false)?; Ok(SimpleEvaluator::new( Rc::new(dataset), base_iri.map(Rc::new), diff --git a/lib/src/sparql/plan_builder.rs b/lib/src/sparql/plan_builder.rs index d5b4da72..8afb8396 100644 --- a/lib/src/sparql/plan_builder.rs +++ b/lib/src/sparql/plan_builder.rs @@ -19,6 +19,7 @@ impl<'a> PlanBuilder<'a> { pub fn build( dataset: &'a DatasetView, pattern: &GraphPattern, + is_cardinality_meaningful: bool, ) -> Result<(PlanNode, Vec), EvaluationError> { let mut variables = Vec::default(); let plan = PlanBuilder { dataset }.build_for_graph_pattern( @@ -26,6 +27,15 @@ impl<'a> PlanBuilder<'a> { &mut variables, &PatternValue::Constant(EncodedTerm::DefaultGraph), )?; + let plan = if is_cardinality_meaningful { + plan + } else { + // let's reduce downstream task. + // TODO: avoid if already REDUCED or DISTINCT + PlanNode::Reduced { + child: Box::new(plan), + } + }; Ok((plan, variables)) } @@ -1253,6 +1263,7 @@ impl<'a> PlanBuilder<'a> { expression, position, } => { + //TODO: handle the case where the filter generates an expression variable if filter_variables.iter().all(|v| child.is_variable_bound(*v)) { PlanNode::Extend { child: Box::new(Self::push_filter(child, filter)), diff --git a/lib/src/sparql/update.rs b/lib/src/sparql/update.rs index 744d9592..59628216 100644 --- a/lib/src/sparql/update.rs +++ b/lib/src/sparql/update.rs @@ -120,7 +120,7 @@ impl<'a> SimpleUpdateEvaluator<'a> { algebra: &GraphPattern, ) -> Result<(), EvaluationError> { let dataset = Rc::new(DatasetView::new(self.storage.clone(), using)); - let (plan, variables) = PlanBuilder::build(dataset.as_ref(), algebra)?; + let (plan, variables) = PlanBuilder::build(dataset.as_ref(), algebra, false)?; let evaluator = SimpleEvaluator::new( dataset.clone(), self.base_iri.clone(),