refactored prepare_query

pull/11/head
Dustin Whitney 5 years ago
parent 2aa9114deb
commit 0e12edfdc9
  1. 16
      lib/src/repository.rs
  2. 96
      lib/src/sparql/eval.rs
  3. 21
      lib/src/sparql/mod.rs
  4. 7
      lib/src/sparql/plan.rs
  5. 12
      lib/src/store/mod.rs
  6. 9
      lib/tests/service_test_cases.rs
  7. 2
      lib/tests/sparql_test_cases.rs

@ -1,6 +1,7 @@
use crate::model::*;
use crate::sparql::{GraphPattern, PreparedQuery, QueryOptions};
use crate::{DatasetSyntax, GraphSyntax, Result};
use rio_api::iri::Iri;
use std::io::BufRead;
/// A `Repository` stores a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
@ -81,7 +82,13 @@ pub trait RepositoryConnection: Clone {
/// assert_eq!(results.into_values_iter().next().unwrap().unwrap()[0], Some(ex.into()));
/// }
/// ```
fn prepare_query<'a>(&'a self, query: &str, options: &'a QueryOptions<'a>) -> Result<Self::PreparedQuery>;
fn prepare_query<'a>(&'a self, query: &str, base_iri: Option<&'a str>) -> Result<Self::PreparedQuery>;
fn prepare_query_from_pattern<'a>(
&'a self,
graph_pattern: &'a GraphPattern,
) -> Result<Self::PreparedQuery>;
/// Retrieves quads with a filter on each quad component
///
@ -112,13 +119,6 @@ pub trait RepositoryConnection: Clone {
where
Self: 'a;
fn prepare_query_from_pattern<'a>(
&'a self,
graph_pattern: &'a GraphPattern,
options: &'a QueryOptions<'a>
) -> Result<Self::PreparedQuery>;
/// Loads a graph file (i.e. triples) into the repository
///
/// Usage example:

@ -41,16 +41,14 @@ type EncodedTuplesIterator<'a> = Box<dyn Iterator<Item = Result<EncodedTuple>> +
pub struct SimpleEvaluator<S: StoreConnection> {
dataset: DatasetView<S>,
bnodes_map: Mutex<BTreeMap<u128, u128>>,
base_iri: Option<Iri<String>>,
now: DateTime<FixedOffset>,
}
impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
pub fn new(dataset: DatasetView<S>, base_iri: Option<Iri<String>>) -> Self {
pub fn new(dataset: DatasetView<S>) -> Self {
Self {
dataset,
bnodes_map: Mutex::new(BTreeMap::default()),
base_iri,
now: Utc::now().with_timezone(&FixedOffset::east(0)),
}
}
@ -113,6 +111,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
{
Ok(QueryResult::Graph(Box::new(DescribeIterator {
eval: self,
options,
iter: self.eval_plan(plan, vec![], options),
quads: Box::new(empty()),
})))
@ -198,6 +197,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
get_pattern_value(&predicate, &tuple),
get_pattern_value(&object, &tuple),
get_pattern_value(&graph_name, &tuple),
options.default_graph_as_union
);
if subject.is_var() && subject == predicate {
iter = Box::new(iter.filter(|quad| match quad {
@ -271,7 +271,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
};
match (input_subject, input_object) {
(Some(input_subject), Some(input_object)) => Box::new(
self.eval_path_from(path, input_subject, input_graph_name)
self.eval_path_from(path, input_subject, input_graph_name, options)
.filter_map(move |o| match o {
Ok(o) => {
if o == input_object {
@ -285,7 +285,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
)
as EncodedTuplesIterator<'_>,
(Some(input_subject), None) => Box::new(
self.eval_path_from(path, input_subject, input_graph_name)
self.eval_path_from(path, input_subject, input_graph_name, options)
.map(move |o| {
let mut new_tuple = tuple.clone();
put_pattern_value(&object, o?, &mut new_tuple);
@ -293,7 +293,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
}),
),
(None, Some(input_object)) => Box::new(
self.eval_path_to(path, input_object, input_graph_name)
self.eval_path_to(path, input_object, input_graph_name, options)
.map(move |s| {
let mut new_tuple = tuple.clone();
put_pattern_value(&subject, s?, &mut new_tuple);
@ -301,7 +301,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
}),
),
(None, None) => {
Box::new(self.eval_open_path(path, input_graph_name).map(move |so| {
Box::new(self.eval_open_path(path, input_graph_name, options).map(move |so| {
let mut new_tuple = tuple.clone();
so.map(move |(s, o)| {
put_pattern_value(&subject, s, &mut new_tuple);
@ -580,6 +580,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
path: &'b PlanPropertyPath,
start: EncodedTerm,
graph_name: EncodedTerm,
options: &'b QueryOptions<'b>
) -> Box<dyn Iterator<Item = Result<EncodedTerm>> + 'b>
where
'a: 'b,
@ -587,33 +588,33 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
match path {
PlanPropertyPath::PredicatePath(p) => Box::new(
self.dataset
.quads_for_pattern(Some(start), Some(*p), None, Some(graph_name))
.quads_for_pattern(Some(start), Some(*p), None, Some(graph_name), options.default_graph_as_union)
.map(|t| Ok(t?.object)),
),
PlanPropertyPath::InversePath(p) => self.eval_path_to(&p, start, graph_name),
PlanPropertyPath::InversePath(p) => self.eval_path_to(&p, start, graph_name, options),
PlanPropertyPath::SequencePath(a, b) => Box::new(
self.eval_path_from(&a, start, graph_name)
.flat_map_ok(move |middle| self.eval_path_from(&b, middle, graph_name)),
self.eval_path_from(&a, start, graph_name, options)
.flat_map_ok(move |middle| self.eval_path_from(&b, middle, graph_name, options)),
),
PlanPropertyPath::AlternativePath(a, b) => Box::new(
self.eval_path_from(&a, start, graph_name)
.chain(self.eval_path_from(&b, start, graph_name)),
self.eval_path_from(&a, start, graph_name, options)
.chain(self.eval_path_from(&b, start, graph_name, options)),
),
PlanPropertyPath::ZeroOrMorePath(p) => {
Box::new(transitive_closure(Some(Ok(start)), move |e| {
self.eval_path_from(p, e, graph_name)
self.eval_path_from(p, e, graph_name, options)
}))
}
PlanPropertyPath::OneOrMorePath(p) => Box::new(transitive_closure(
self.eval_path_from(p, start, graph_name),
move |e| self.eval_path_from(p, e, graph_name),
self.eval_path_from(p, start, graph_name, options),
move |e| self.eval_path_from(p, e, graph_name, options),
)),
PlanPropertyPath::ZeroOrOnePath(p) => Box::new(hash_deduplicate(
once(Ok(start)).chain(self.eval_path_from(&p, start, graph_name)),
once(Ok(start)).chain(self.eval_path_from(&p, start, graph_name, options)),
)),
PlanPropertyPath::NegatedPropertySet(ps) => Box::new(
self.dataset
.quads_for_pattern(Some(start), None, None, Some(graph_name))
.quads_for_pattern(Some(start), None, None, Some(graph_name), options.default_graph_as_union)
.filter(move |t| match t {
Ok(t) => !ps.contains(&t.predicate),
Err(_) => true,
@ -628,6 +629,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
path: &'b PlanPropertyPath,
end: EncodedTerm,
graph_name: EncodedTerm,
options: &'a QueryOptions<'b>
) -> Box<dyn Iterator<Item = Result<EncodedTerm>> + 'b>
where
'a: 'b,
@ -635,33 +637,33 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
match path {
PlanPropertyPath::PredicatePath(p) => Box::new(
self.dataset
.quads_for_pattern(None, Some(*p), Some(end), Some(graph_name))
.quads_for_pattern(None, Some(*p), Some(end), Some(graph_name), options.default_graph_as_union)
.map(|t| Ok(t?.subject)),
),
PlanPropertyPath::InversePath(p) => self.eval_path_from(&p, end, graph_name),
PlanPropertyPath::InversePath(p) => self.eval_path_from(&p, end, graph_name, options),
PlanPropertyPath::SequencePath(a, b) => Box::new(
self.eval_path_to(&b, end, graph_name)
.flat_map_ok(move |middle| self.eval_path_to(&a, middle, graph_name)),
self.eval_path_to(&b, end, graph_name, options)
.flat_map_ok(move |middle| self.eval_path_to(&a, middle, graph_name, options)),
),
PlanPropertyPath::AlternativePath(a, b) => Box::new(
self.eval_path_to(&a, end, graph_name)
.chain(self.eval_path_to(&b, end, graph_name)),
self.eval_path_to(&a, end, graph_name, options)
.chain(self.eval_path_to(&b, end, graph_name, options)),
),
PlanPropertyPath::ZeroOrMorePath(p) => {
Box::new(transitive_closure(Some(Ok(end)), move |e| {
self.eval_path_to(p, e, graph_name)
self.eval_path_to(p, e, graph_name, options)
}))
}
PlanPropertyPath::OneOrMorePath(p) => Box::new(transitive_closure(
self.eval_path_to(p, end, graph_name),
move |e| self.eval_path_to(p, e, graph_name),
self.eval_path_to(p, end, graph_name, options),
move |e| self.eval_path_to(p, e, graph_name, options),
)),
PlanPropertyPath::ZeroOrOnePath(p) => Box::new(hash_deduplicate(
once(Ok(end)).chain(self.eval_path_to(&p, end, graph_name)),
once(Ok(end)).chain(self.eval_path_to(&p, end, graph_name, options)),
)),
PlanPropertyPath::NegatedPropertySet(ps) => Box::new(
self.dataset
.quads_for_pattern(None, None, Some(end), Some(graph_name))
.quads_for_pattern(None, None, Some(end), Some(graph_name), options.default_graph_as_union)
.filter(move |t| match t {
Ok(t) => !ps.contains(&t.predicate),
Err(_) => true,
@ -675,6 +677,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
&'b self,
path: &'b PlanPropertyPath,
graph_name: EncodedTerm,
options: &'b QueryOptions<'b>
) -> Box<dyn Iterator<Item = Result<(EncodedTerm, EncodedTerm)>> + 'b>
where
'a: 'b,
@ -682,45 +685,45 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
match path {
PlanPropertyPath::PredicatePath(p) => Box::new(
self.dataset
.quads_for_pattern(None, Some(*p), None, Some(graph_name))
.quads_for_pattern(None, Some(*p), None, Some(graph_name), options.default_graph_as_union)
.map(|t| t.map(|t| (t.subject, t.object))),
),
PlanPropertyPath::InversePath(p) => Box::new(
self.eval_open_path(&p, graph_name)
self.eval_open_path(&p, graph_name, options)
.map(|t| t.map(|(s, o)| (o, s))),
),
PlanPropertyPath::SequencePath(a, b) => Box::new(
self.eval_open_path(&a, graph_name)
self.eval_open_path(&a, graph_name, options)
.flat_map_ok(move |(start, middle)| {
self.eval_path_from(&b, middle, graph_name)
self.eval_path_from(&b, middle, graph_name, options)
.map(move |end| Ok((start, end?)))
}),
),
PlanPropertyPath::AlternativePath(a, b) => Box::new(
self.eval_open_path(&a, graph_name)
.chain(self.eval_open_path(&b, graph_name)),
self.eval_open_path(&a, graph_name, options)
.chain(self.eval_open_path(&b, graph_name, options)),
),
PlanPropertyPath::ZeroOrMorePath(p) => Box::new(transitive_closure(
self.get_subject_or_object_identity_pairs(graph_name), //TODO: avoid to inject everything
self.get_subject_or_object_identity_pairs(graph_name, options), //TODO: avoid to inject everything
move |(start, middle)| {
self.eval_path_from(p, middle, graph_name)
self.eval_path_from(p, middle, graph_name, options)
.map(move |end| Ok((start, end?)))
},
)),
PlanPropertyPath::OneOrMorePath(p) => Box::new(transitive_closure(
self.eval_open_path(p, graph_name),
self.eval_open_path(p, graph_name, options),
move |(start, middle)| {
self.eval_path_from(p, middle, graph_name)
self.eval_path_from(p, middle, graph_name, options)
.map(move |end| Ok((start, end?)))
},
)),
PlanPropertyPath::ZeroOrOnePath(p) => Box::new(hash_deduplicate(
self.get_subject_or_object_identity_pairs(graph_name)
.chain(self.eval_open_path(&p, graph_name)),
self.get_subject_or_object_identity_pairs(graph_name, options)
.chain(self.eval_open_path(&p, graph_name, options)),
)),
PlanPropertyPath::NegatedPropertySet(ps) => Box::new(
self.dataset
.quads_for_pattern(None, None, None, Some(graph_name))
.quads_for_pattern(None, None, None, Some(graph_name), options.default_graph_as_union)
.filter(move |t| match t {
Ok(t) => !ps.contains(&t.predicate),
Err(_) => true,
@ -733,9 +736,10 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
fn get_subject_or_object_identity_pairs<'b>(
&'b self,
graph_name: EncodedTerm,
options: &'b QueryOptions<'b>
) -> impl Iterator<Item = Result<(EncodedTerm, EncodedTerm)>> + 'b {
self.dataset
.quads_for_pattern(None, None, None, Some(graph_name))
.quads_for_pattern(None, None, None, Some(graph_name), options.default_graph_as_union)
.flat_map_ok(|t| once(Ok(t.subject)).chain(once(Ok(t.object))))
.map(|e| e.map(|e| (e, e)))
}
@ -929,7 +933,8 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
_ => None,
}?;
let iri = self.dataset.get_str(iri_id).ok()??;
if let Some(base_iri) = &self.base_iri {
let base_iri = options.base_iri.map(|base_iri| Iri::parse(base_iri));
if let Some(Ok(base_iri)) = base_iri {
self.build_named_node(&base_iri.resolve(&iri).ok()?.into_inner())
} else {
Iri::parse(iri).ok()?;
@ -2350,6 +2355,7 @@ fn decode_triple(
struct DescribeIterator<'a, S: StoreConnection + 'a> {
eval: &'a SimpleEvaluator<S>,
options: &'a QueryOptions<'a>,
iter: EncodedTuplesIterator<'a>,
quads: Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a>,
}
@ -2378,7 +2384,7 @@ impl<'a, S: StoreConnection + 'a> Iterator for DescribeIterator<'a, S> {
self.quads =
self.eval
.dataset
.quads_for_pattern(Some(subject), None, None, None);
.quads_for_pattern(Some(subject), None, None, None, self.options.default_graph_as_union);
}
}
}

@ -19,7 +19,6 @@ use crate::sparql::plan_builder::PlanBuilder;
use crate::store::StoreConnection;
use crate::Result;
use std::fmt;
use rio_api::iri::Iri;
pub use crate::sparql::algebra::GraphPattern;
pub use crate::sparql::model::BindingsIterator;
@ -58,10 +57,10 @@ enum SimplePreparedQueryAction<S: StoreConnection> {
}
impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
pub(crate) fn new(connection: S, query: &str, options: &'a QueryOptions<'a>) -> Result<Self> {
let dataset = DatasetView::new(connection, options.default_graph_as_union);
pub(crate) fn new(connection: S, query: &str, base_iri: Option<&'a str>) -> Result<Self> {
let dataset = DatasetView::new(connection);
//TODO avoid inserting terms in the Repository StringStore
Ok(Self(match read_sparql_query(query, options.base_iri)? {
Ok(Self(match read_sparql_query(query, base_iri)? {
QueryVariants::Select {
algebra,
dataset: _,
@ -71,7 +70,7 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
SimplePreparedQueryAction::Select {
plan,
variables,
evaluator: SimpleEvaluator::new(dataset, base_iri),
evaluator: SimpleEvaluator::new(dataset),
}
}
QueryVariants::Ask {
@ -82,7 +81,7 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
let (plan, _) = PlanBuilder::build(dataset.encoder(), &algebra)?;
SimplePreparedQueryAction::Ask {
plan,
evaluator: SimpleEvaluator::new(dataset, base_iri),
evaluator: SimpleEvaluator::new(dataset),
}
}
QueryVariants::Construct {
@ -99,7 +98,7 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
&construct,
variables,
)?,
evaluator: SimpleEvaluator::new(dataset, base_iri),
evaluator: SimpleEvaluator::new(dataset),
}
}
QueryVariants::Describe {
@ -110,7 +109,7 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
let (plan, _) = PlanBuilder::build(dataset.encoder(), &algebra)?;
SimplePreparedQueryAction::Describe {
plan,
evaluator: SimpleEvaluator::new(dataset, base_iri),
evaluator: SimpleEvaluator::new(dataset),
}
}
}))
@ -119,15 +118,13 @@ impl<'a, S: StoreConnection + 'a> SimplePreparedQuery<S> {
pub(crate) fn new_from_pattern(
connection: S,
pattern: &GraphPattern,
options: &'a QueryOptions<'a>
) -> Result<Self> {
let dataset = DatasetView::new(connection, options.default_graph_as_union);
let iri = options.base_iri.map(|i| Iri::parse(i.to_string()).unwrap());
let dataset = DatasetView::new(connection);
let (plan, variables) = PlanBuilder::build(dataset.encoder(), pattern)?;
Ok(Self(SimplePreparedQueryAction::Select {
plan,
variables,
evaluator: SimpleEvaluator::new(dataset, iri),
evaluator: SimpleEvaluator::new(dataset),
}))
}
}

@ -473,15 +473,13 @@ pub enum TripleTemplateValue {
pub struct DatasetView<S: StoreConnection> {
store: S,
extra: RefCell<MemoryStrStore>,
default_graph_as_union: bool,
}
impl<S: StoreConnection> DatasetView<S> {
pub fn new(store: S, default_graph_as_union: bool) -> Self {
pub fn new(store: S) -> Self {
Self {
store,
extra: RefCell::new(MemoryStrStore::default()),
default_graph_as_union,
}
}
@ -491,6 +489,7 @@ impl<S: StoreConnection> DatasetView<S> {
predicate: Option<EncodedTerm>,
object: Option<EncodedTerm>,
graph_name: Option<EncodedTerm>,
default_graph_as_union: bool,
) -> Box<dyn Iterator<Item = Result<EncodedQuad>> + 'a> {
if graph_name == None {
Box::new(
@ -501,7 +500,7 @@ impl<S: StoreConnection> DatasetView<S> {
Ok(quad) => quad.graph_name != ENCODED_DEFAULT_GRAPH,
}),
)
} else if graph_name == Some(ENCODED_DEFAULT_GRAPH) && self.default_graph_as_union {
} else if graph_name == Some(ENCODED_DEFAULT_GRAPH) && default_graph_as_union {
Box::new(
self.store
.quads_for_pattern(subject, predicate, object, None)

@ -11,9 +11,10 @@ pub use crate::store::memory::MemoryRepository;
pub use crate::store::rocksdb::RocksDbRepository;
use crate::model::*;
use crate::sparql::{QueryOptions, SimplePreparedQuery};
use crate::sparql::{SimplePreparedQuery};
use crate::store::numeric_encoder::*;
use crate::{DatasetSyntax, GraphSyntax, RepositoryConnection, Result};
use rio_api::iri::Iri;
use rio_api::parser::{QuadsParser, TriplesParser};
use rio_turtle::{NQuadsParser, NTriplesParser, TriGParser, TurtleParser};
use rio_xml::RdfXmlParser;
@ -72,8 +73,8 @@ impl<S: StoreConnection> From<S> for StoreRepositoryConnection<S> {
impl<S: StoreConnection> RepositoryConnection for StoreRepositoryConnection<S> {
type PreparedQuery = SimplePreparedQuery<S>;
fn prepare_query<'a>(&self, query: &str, options: &'a QueryOptions<'a>) -> Result<SimplePreparedQuery<S>> {
SimplePreparedQuery::new(self.inner.clone(), query, options) //TODO: avoid clone
fn prepare_query<'a>(&self, query: &str, base_iri: Option<&'a str>) -> Result<SimplePreparedQuery<S>> {
SimplePreparedQuery::new(self.inner.clone(), query, base_iri) //TODO: avoid clone
}
fn quads_for_pattern<'a>(
@ -101,13 +102,10 @@ impl<S: StoreConnection> RepositoryConnection for StoreRepositoryConnection<S> {
fn prepare_query_from_pattern<'a>(
&'a self,
pattern: &GraphPattern,
options: &'a QueryOptions<'a>
) -> Result<Self::PreparedQuery> {
SimplePreparedQuery::new_from_pattern(self.inner.clone(), pattern, options) //TODO: avoid clone
SimplePreparedQuery::new_from_pattern(self.inner.clone(), pattern) //TODO: avoid clone
}
fn load_graph(
&mut self,
reader: impl BufRead,

@ -110,7 +110,7 @@ fn silent_service_test() {
#[derive(Clone,Copy)]
struct TwoServiceTest;
impl ServiceHandler for TwoServiceTest {
fn handle<'a>(&'a self, named_node: NamedNode) -> Option<(fn(GraphPattern) -> Result<BindingsIterator<'a>>)> {
fn handle<'a>(&'a self, _named_node: NamedNode) -> Option<(fn(GraphPattern) -> Result<BindingsIterator<'a>>)> {
Some(TwoServiceTest::handle_service)
}
}
@ -174,7 +174,7 @@ fn make_repository(reader: impl BufRead) -> Result<MemoryRepository> {
fn query_repository<'a>(repository: MemoryRepository, query: String, options: QueryOptions<'a>) -> Result<BindingsIterator<'a>> {
let connection = repository.connection()?;
let prepared_query = connection.prepare_query(&query, &options)?;
let prepared_query = connection.prepare_query(&query, None)?;
let result = prepared_query.exec(&options)?;
match result {
QueryResult::Bindings(iterator) => {
@ -186,10 +186,9 @@ fn query_repository<'a>(repository: MemoryRepository, query: String, options: Qu
}
}
//fn pattern_repository<'a>(repository: MemoryRepository, pattern: GraphPattern, options: QueryOptions<'a>) -> Result<Vec<Vec<Option<Term>>>> {
fn pattern_repository<'a>(repository: MemoryRepository, pattern: GraphPattern, options: QueryOptions<'a>) -> Result<BindingsIterator<'a>> {
let connection = repository.connection()?;
let prepared_query = connection.prepare_query_from_pattern(&pattern, &options)?;
let prepared_query = connection.prepare_query_from_pattern(&pattern)?;
let result = prepared_query.exec(&options)?;
match result {
QueryResult::Bindings(iterator) => {
@ -201,13 +200,11 @@ fn pattern_repository<'a>(repository: MemoryRepository, pattern: GraphPattern, o
}
}
//fn do_query<'a>(reader: impl BufRead, query: String, options: QueryOptions<'a>) -> Result<Vec<Vec<Option<Term>>>> {
fn do_query<'a>(reader: impl BufRead, query: String, options: QueryOptions<'a>) -> Result<BindingsIterator<'a>> {
let repository = make_repository(reader)?;
query_repository(repository, query, options)
}
//fn do_pattern<'a>(reader: impl BufRead, pattern: GraphPattern, options: QueryOptions<'a>) -> Result<Vec<Vec<Option<Term>>>> {
fn do_pattern<'a>(reader: impl BufRead, pattern: GraphPattern, options: QueryOptions<'a>) -> Result<BindingsIterator<'a>> {
let repository = make_repository(reader)?;
pattern_repository(repository, pattern, options)

@ -158,7 +158,7 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
}
match repository
.connection()?
.prepare_query(&read_file_to_string(&test.query)?, &QueryOptions::default().with_base_iri(&test.query))
.prepare_query(&read_file_to_string(&test.query)?, None)
{
Err(error) => Err(format_err!(
"Failure to parse query of {} with error: {}",

Loading…
Cancel
Save