Adds support of BIND evaluation

pull/10/head
Tpt 6 years ago
parent 53ffd231a0
commit ab43ff1f48
  1. 38
      lib/src/sparql/eval.rs
  2. 11
      lib/src/sparql/plan.rs
  3. 2
      lib/tests/rdf_test_cases.rs
  4. 2
      lib/tests/sparql_test_cases.rs

@ -135,6 +135,27 @@ impl<S: EncodedQuadsStore> SimpleEvaluator<S> {
iter iter
})) }))
} }
PlanNode::Extend {
child,
position,
expression,
} => {
let eval = self.clone();
Box::new(
self.eval_plan(*child, from)
.filter_map(move |tuple| match tuple {
Ok(mut tuple) => {
put_value(
position,
eval.eval_expression(&expression, &tuple)?,
&mut tuple,
);
Some(Ok(tuple))
}
Err(error) => Some(Err(error)),
}),
)
}
PlanNode::HashDeduplicate { child } => { PlanNode::HashDeduplicate { child } => {
let iter = self.eval_plan(*child, from); let iter = self.eval_plan(*child, from);
let mut values = HashSet::with_capacity(iter.size_hint().0); let mut values = HashSet::with_capacity(iter.size_hint().0);
@ -335,16 +356,17 @@ fn get_pattern_value(
fn put_pattern_value(selector: &PatternValue, value: EncodedTerm, tuple: &mut EncodedTuple) { fn put_pattern_value(selector: &PatternValue, value: EncodedTerm, tuple: &mut EncodedTuple) {
match selector { match selector {
PatternValue::Constant(_) => (), PatternValue::Constant(_) => (),
PatternValue::Variable(v) => { PatternValue::Variable(v) => put_value(*v, value, tuple),
let v = *v; }
if tuple.len() > v { }
tuple[v] = Some(value)
fn put_value(position: usize, value: EncodedTerm, tuple: &mut EncodedTuple) {
if tuple.len() > position {
tuple[position] = Some(value)
} else { } else {
if tuple.len() < v { if tuple.len() < position {
tuple.resize(v, None); tuple.resize(position, None);
} }
tuple.push(Some(value)) tuple.push(Some(value))
} }
}
}
} }

@ -26,6 +26,11 @@ pub enum PlanNode {
entry: Box<PlanNode>, entry: Box<PlanNode>,
children: Vec<PlanNode>, children: Vec<PlanNode>,
}, },
Extend {
child: Box<PlanNode>,
position: usize,
expression: PlanExpression,
},
HashDeduplicate { HashDeduplicate {
child: Box<PlanNode>, child: Box<PlanNode>,
}, },
@ -222,7 +227,11 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
} }
} }
GraphPattern::Graph(g, p) => unimplemented!(), GraphPattern::Graph(g, p) => unimplemented!(),
GraphPattern::Extend(p, v, e) => unimplemented!(), GraphPattern::Extend(p, v, e) => PlanNode::Extend {
child: Box::new(self.build_for_graph_pattern(p, input, variables)?),
position: variable_key(variables, &v),
expression: self.build_for_expression(e, variables)?,
},
GraphPattern::Minus(a, b) => unimplemented!(), GraphPattern::Minus(a, b) => unimplemented!(),
GraphPattern::Service(n, p, s) => unimplemented!(), GraphPattern::Service(n, p, s) => unimplemented!(),
GraphPattern::AggregateJoin(g, a) => unimplemented!(), GraphPattern::AggregateJoin(g, a) => unimplemented!(),

@ -365,7 +365,7 @@ impl<'a> Iterator for TestManifest<'a> {
Some(Term::BlankNode(list)) => { Some(Term::BlankNode(list)) => {
self.manifests_to_do.extend( self.manifests_to_do.extend(
RdfListIterator::iter(&self.graph, list.clone().into()) RdfListIterator::iter(&self.graph, list.clone().into())
.flat_map(|m| match m { .filter_map(|m| match m {
Term::NamedNode(nm) => Some(nm.as_url().clone()), Term::NamedNode(nm) => Some(nm.as_url().clone()),
_ => None, _ => None,
}), }),

@ -481,7 +481,7 @@ impl<'a> Iterator for TestManifest<'a> {
Some(Term::BlankNode(list)) => { Some(Term::BlankNode(list)) => {
self.manifests_to_do.extend( self.manifests_to_do.extend(
RdfListIterator::iter(&self.graph, list.clone().into()) RdfListIterator::iter(&self.graph, list.clone().into())
.flat_map(|m| match m { .filter_map(|m| match m {
Term::NamedNode(nm) => Some(nm.as_url().clone()), Term::NamedNode(nm) => Some(nm.as_url().clone()),
_ => None, _ => None,
}), }),

Loading…
Cancel
Save