diff --git a/lib/src/sparql/algebra.rs b/lib/src/sparql/algebra.rs index bd90bbdd..b09654ec 100644 --- a/lib/src/sparql/algebra.rs +++ b/lib/src/sparql/algebra.rs @@ -1049,7 +1049,12 @@ impl GraphPattern { a.add_visible_variables(vars); b.add_visible_variables(vars); } - GraphPattern::Graph(_, p) => p.add_visible_variables(vars), + GraphPattern::Graph(g, p) => { + if let NamedNodeOrVariable::Variable(ref g) = g { + adds_if_has_name(vars, g); + } + p.add_visible_variables(vars); + } GraphPattern::Extend(p, v, _) => { p.add_visible_variables(vars); adds_if_has_name(vars, &v); diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index 8b9f4d32..31f425a2 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -114,9 +114,7 @@ impl SimpleEvaluator { get_pattern_value(&subject, &tuple), get_pattern_value(&predicate, &tuple), get_pattern_value(&object, &tuple), - graph_name.and_then(|graph_name| { - get_pattern_value(&graph_name, &tuple) - }), + get_pattern_value(&graph_name, &tuple), ) { Ok(mut iter) => { if subject.is_var() && subject == predicate { @@ -137,22 +135,31 @@ impl SimpleEvaluator { Ok(quad) => quad.predicate == quad.object, })) } - if let Some(graph_name) = graph_name { - if graph_name.is_var() { - iter = Box::new(iter.filter(|quad| match quad { - Err(_) => true, - Ok(quad) => { - quad.graph_name != ENCODED_DEFAULT_GRAPH - } - })) - } - } else { + if graph_name.is_var() { iter = Box::new(iter.filter(|quad| match quad { Err(_) => true, Ok(quad) => { - quad.graph_name == ENCODED_DEFAULT_GRAPH + quad.graph_name != ENCODED_DEFAULT_GRAPH } - })) + })); + if graph_name == subject { + iter = Box::new(iter.filter(|quad| match quad { + Err(_) => true, + Ok(quad) => quad.graph_name == quad.subject, + })) + } + if graph_name == predicate { + iter = Box::new(iter.filter(|quad| match quad { + Err(_) => true, + Ok(quad) => quad.graph_name == quad.predicate, + })) + } + if graph_name == object { + iter = Box::new(iter.filter(|quad| match quad { + Err(_) => true, + Ok(quad) => quad.graph_name == quad.object, + })) + } } Box::new(iter.map(move |quad| { let quad = quad?; @@ -168,13 +175,11 @@ impl SimpleEvaluator { &mut new_tuple, ); put_pattern_value(&object, quad.object, &mut new_tuple); - if let Some(graph_name) = graph_name { - put_pattern_value( - &graph_name, - quad.graph_name, - &mut new_tuple, - ); - } + put_pattern_value( + &graph_name, + quad.graph_name, + &mut new_tuple, + ); Ok(new_tuple) })) } diff --git a/lib/src/sparql/plan.rs b/lib/src/sparql/plan.rs index cb29732f..32a6d843 100644 --- a/lib/src/sparql/plan.rs +++ b/lib/src/sparql/plan.rs @@ -4,6 +4,7 @@ use sparql::algebra::*; use std::collections::BTreeSet; use store::encoded::EncodedQuadsStore; use store::numeric_encoder::EncodedTerm; +use store::numeric_encoder::ENCODED_DEFAULT_GRAPH; use Result; pub type EncodedTuple = Vec>; @@ -19,7 +20,7 @@ pub enum PlanNode { subject: PatternValue, predicate: PatternValue, object: PatternValue, - graph_name: Option, + graph_name: PatternValue, }, Join { left: Box, @@ -99,7 +100,7 @@ impl PlanNode { if let PatternValue::Variable(var) = object { set.insert(*var); } - if let Some(PatternValue::Variable(var)) = graph_name { + if let PatternValue::Variable(var) = graph_name { set.insert(*var); } child.add_variables(set); @@ -353,7 +354,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> { pattern, PlanNode::Init, &mut variables, - None, + PatternValue::Constant(ENCODED_DEFAULT_GRAPH), )?; Ok((plan, variables)) } @@ -371,7 +372,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> { pattern: &GraphPattern, input: PlanNode, variables: &mut Vec, - graph_name: Option, + graph_name: PatternValue, ) -> Result { Ok(match pattern { GraphPattern::BGP(p) => { @@ -459,7 +460,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> { } GraphPattern::Graph(g, p) => { let graph_name = self.pattern_value_from_named_node_or_variable(g, variables)?; - self.build_for_graph_pattern(p, input, variables, Some(graph_name))? + self.build_for_graph_pattern(p, input, variables, graph_name)? } GraphPattern::Extend(p, v, e) => PlanNode::Extend { child: Box::new(self.build_for_graph_pattern(p, input, variables, graph_name)?), diff --git a/lib/tests/sparql_test_cases.rs b/lib/tests/sparql_test_cases.rs index 68e4300b..df066336 100644 --- a/lib/tests/sparql_test_cases.rs +++ b/lib/tests/sparql_test_cases.rs @@ -82,7 +82,7 @@ fn sparql_w3c_syntax_testsuite() { #[test] fn sparql_w3c_query_evaluation_testsuite() { - //TODO: dataset graph open-world + //TODO: dataset open-world let manifest_10_urls = vec![ Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/algebra/manifest.ttl") .unwrap(), @@ -110,6 +110,8 @@ fn sparql_w3c_query_evaluation_testsuite() { .unwrap(), Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-ops/manifest.ttl") .unwrap(), + Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/graph/manifest.ttl") + .unwrap(), Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/i18n/manifest.ttl").unwrap(), Url::parse( "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/optional-filter/manifest.ttl",