From d69d9c526ec54892423b8b7bab3c79ab71fffd49 Mon Sep 17 00:00:00 2001 From: Tpt Date: Tue, 2 Oct 2018 16:41:33 +0200 Subject: [PATCH] Makes SPARQL 1.0 triple pattern tests pass --- src/store/sparql.rs | 51 ++++++++++++++++++++++++++++++-------- tests/sparql_test_cases.rs | 13 +++++++--- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/store/sparql.rs b/src/store/sparql.rs index 4edf5525..447174f7 100644 --- a/src/store/sparql.rs +++ b/src/store/sparql.rs @@ -165,6 +165,10 @@ impl SparqlEvaluator { let object = self.binding_value_lookup_from_term_or_variable(&pattern.object, &mut variables)?; + let filter_sp = subject.is_var() && subject == predicate; + let filter_so = subject.is_var() && subject == object; + let filter_po = predicate.is_var() && predicate == object; + let store = self.store.clone(); let variables_len = variables.len(); Ok(EncodedBindingsIterator { @@ -178,15 +182,35 @@ impl SparqlEvaluator { object.get(&binding), None, //TODO ) { - Ok(iter) => Box::new(iter.map(move |quad| { - let quad = quad?; - let mut binding = binding.clone(); - binding.resize(variables_len, None); - subject.put(quad.subject, &mut binding); - predicate.put(quad.predicate, &mut binding); - object.put(quad.object, &mut binding); - Ok(binding) - })), + Ok(mut iter) => { + if filter_sp { + iter = Box::new(iter.filter(|quad| match quad { + Err(_) => true, + Ok(quad) => quad.subject == quad.predicate, + })) + } + if filter_so { + iter = Box::new(iter.filter(|quad| match quad { + Err(_) => true, + Ok(quad) => quad.subject == quad.object, + })) + } + if filter_po { + iter = Box::new(iter.filter(|quad| match quad { + Err(_) => true, + Ok(quad) => quad.predicate == quad.object, + })) + } + Box::new(iter.map(move |quad| { + let quad = quad?; + let mut binding = binding.clone(); + binding.resize(variables_len, None); + subject.put(quad.subject, &mut binding); + predicate.put(quad.predicate, &mut binding); + object.put(quad.object, &mut binding); + Ok(binding) + })) + } Err(error) => Box::new(once(Err(error))), } } @@ -288,7 +312,7 @@ impl SparqlEvaluator { } } -#[derive(Clone, Copy)] +#[derive(PartialEq, Eq, Clone, Copy)] enum BindingValueLookup { Constant(EncodedTerm), Variable(usize), @@ -312,4 +336,11 @@ impl BindingValueLookup { BindingValueLookup::Variable(v) => binding[*v] = Some(value), } } + + fn is_var(&self) -> bool { + match self { + BindingValueLookup::Constant(_) => false, + BindingValueLookup::Variable(_) => true, + } + } } diff --git a/tests/sparql_test_cases.rs b/tests/sparql_test_cases.rs index e6a3e427..0c957bc0 100644 --- a/tests/sparql_test_cases.rs +++ b/tests/sparql_test_cases.rs @@ -78,14 +78,19 @@ fn sparql_w3c_syntax_testsuite() { #[test] fn sparql_w3c_query_evaluation_testsuite() { - let manifest_10_url = + let manifest_10_urls = vec![ Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/basic/manifest.ttl") - .unwrap(); - + .unwrap(), + Url::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/triple-match/manifest.ttl") + .unwrap(), + ]; let test_blacklist = vec![]; let client = RDFClient::default(); - for test_result in TestManifest::new(&client, manifest_10_url) { + for test_result in manifest_10_urls + .into_iter() + .flat_map(|manifest| TestManifest::new(&client, manifest)) + { let test = test_result.unwrap(); if test_blacklist.contains(&test.id) { continue;