Fixes support of SPARQL "GRAPH" keyword

pull/10/head
Tpt 6 years ago
parent f1554b7d4d
commit d8de4eaf7a
  1. 7
      lib/src/sparql/algebra.rs
  2. 49
      lib/src/sparql/eval.rs
  3. 11
      lib/src/sparql/plan.rs
  4. 4
      lib/tests/sparql_test_cases.rs

@ -1049,7 +1049,12 @@ impl GraphPattern {
a.add_visible_variables(vars); a.add_visible_variables(vars);
b.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, _) => { GraphPattern::Extend(p, v, _) => {
p.add_visible_variables(vars); p.add_visible_variables(vars);
adds_if_has_name(vars, &v); adds_if_has_name(vars, &v);

@ -114,9 +114,7 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
get_pattern_value(&subject, &tuple), get_pattern_value(&subject, &tuple),
get_pattern_value(&predicate, &tuple), get_pattern_value(&predicate, &tuple),
get_pattern_value(&object, &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) => { Ok(mut iter) => {
if subject.is_var() && subject == predicate { if subject.is_var() && subject == predicate {
@ -137,22 +135,31 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
Ok(quad) => quad.predicate == quad.object, Ok(quad) => quad.predicate == quad.object,
})) }))
} }
if let Some(graph_name) = graph_name { if graph_name.is_var() {
if graph_name.is_var() {
iter = Box::new(iter.filter(|quad| match quad {
Err(_) => true,
Ok(quad) => {
quad.graph_name != ENCODED_DEFAULT_GRAPH
}
}))
}
} else {
iter = Box::new(iter.filter(|quad| match quad { iter = Box::new(iter.filter(|quad| match quad {
Err(_) => true, Err(_) => true,
Ok(quad) => { 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| { Box::new(iter.map(move |quad| {
let quad = quad?; let quad = quad?;
@ -168,13 +175,11 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
&mut new_tuple, &mut new_tuple,
); );
put_pattern_value(&object, quad.object, &mut new_tuple); put_pattern_value(&object, quad.object, &mut new_tuple);
if let Some(graph_name) = graph_name { put_pattern_value(
put_pattern_value( &graph_name,
&graph_name, quad.graph_name,
quad.graph_name, &mut new_tuple,
&mut new_tuple, );
);
}
Ok(new_tuple) Ok(new_tuple)
})) }))
} }

@ -4,6 +4,7 @@ use sparql::algebra::*;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use store::encoded::EncodedQuadsStore; use store::encoded::EncodedQuadsStore;
use store::numeric_encoder::EncodedTerm; use store::numeric_encoder::EncodedTerm;
use store::numeric_encoder::ENCODED_DEFAULT_GRAPH;
use Result; use Result;
pub type EncodedTuple = Vec<Option<EncodedTerm>>; pub type EncodedTuple = Vec<Option<EncodedTerm>>;
@ -19,7 +20,7 @@ pub enum PlanNode {
subject: PatternValue, subject: PatternValue,
predicate: PatternValue, predicate: PatternValue,
object: PatternValue, object: PatternValue,
graph_name: Option<PatternValue>, graph_name: PatternValue,
}, },
Join { Join {
left: Box<PlanNode>, left: Box<PlanNode>,
@ -99,7 +100,7 @@ impl PlanNode {
if let PatternValue::Variable(var) = object { if let PatternValue::Variable(var) = object {
set.insert(*var); set.insert(*var);
} }
if let Some(PatternValue::Variable(var)) = graph_name { if let PatternValue::Variable(var) = graph_name {
set.insert(*var); set.insert(*var);
} }
child.add_variables(set); child.add_variables(set);
@ -353,7 +354,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
pattern, pattern,
PlanNode::Init, PlanNode::Init,
&mut variables, &mut variables,
None, PatternValue::Constant(ENCODED_DEFAULT_GRAPH),
)?; )?;
Ok((plan, variables)) Ok((plan, variables))
} }
@ -371,7 +372,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
pattern: &GraphPattern, pattern: &GraphPattern,
input: PlanNode, input: PlanNode,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: Option<PatternValue>, graph_name: PatternValue,
) -> Result<PlanNode> { ) -> Result<PlanNode> {
Ok(match pattern { Ok(match pattern {
GraphPattern::BGP(p) => { GraphPattern::BGP(p) => {
@ -459,7 +460,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
} }
GraphPattern::Graph(g, p) => { GraphPattern::Graph(g, p) => {
let graph_name = self.pattern_value_from_named_node_or_variable(g, variables)?; 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 { GraphPattern::Extend(p, v, e) => PlanNode::Extend {
child: Box::new(self.build_for_graph_pattern(p, input, variables, graph_name)?), child: Box::new(self.build_for_graph_pattern(p, input, variables, graph_name)?),

@ -82,7 +82,7 @@ fn sparql_w3c_syntax_testsuite() {
#[test] #[test]
fn sparql_w3c_query_evaluation_testsuite() { fn sparql_w3c_query_evaluation_testsuite() {
//TODO: dataset graph open-world //TODO: dataset open-world
let manifest_10_urls = vec![ let manifest_10_urls = vec![
Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/algebra/manifest.ttl") Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/algebra/manifest.ttl")
.unwrap(), .unwrap(),
@ -110,6 +110,8 @@ fn sparql_w3c_query_evaluation_testsuite() {
.unwrap(), .unwrap(),
Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-ops/manifest.ttl") Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-ops/manifest.ttl")
.unwrap(), .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/i18n/manifest.ttl").unwrap(),
Url::parse( Url::parse(
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/optional-filter/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/optional-filter/manifest.ttl",

Loading…
Cancel
Save