Adds support for EXISTS and NOT EXISTS

pull/10/head
Tpt 5 years ago
parent f2f3b8785d
commit 4f00ed8266
  1. 3
      lib/src/sparql/eval.rs
  2. 2
      lib/src/sparql/plan.rs
  3. 271
      lib/src/sparql/plan_builder.rs
  4. 7
      lib/tests/sparql_test_cases.rs

@ -321,6 +321,9 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
match expression { match expression {
PlanExpression::Constant(t) => Some(*t), PlanExpression::Constant(t) => Some(*t),
PlanExpression::Variable(v) => get_tuple_value(*v, tuple), PlanExpression::Variable(v) => get_tuple_value(*v, tuple),
PlanExpression::Exists(node) => {
Some(self.eval_plan(node, tuple.to_vec()).next().is_some().into())
}
PlanExpression::Or(a, b) => { PlanExpression::Or(a, b) => {
match self.eval_expression(a, tuple).and_then(|v| self.to_bool(v)) { match self.eval_expression(a, tuple).and_then(|v| self.to_bool(v)) {
Some(true) => Some(true.into()), Some(true) => Some(true.into()),

@ -155,6 +155,7 @@ impl PatternValue {
pub enum PlanExpression { pub enum PlanExpression {
Constant(EncodedTerm), Constant(EncodedTerm),
Variable(usize), Variable(usize),
Exists(Box<PlanNode>),
Or(Box<PlanExpression>, Box<PlanExpression>), Or(Box<PlanExpression>, Box<PlanExpression>),
And(Box<PlanExpression>, Box<PlanExpression>), And(Box<PlanExpression>, Box<PlanExpression>),
Equal(Box<PlanExpression>, Box<PlanExpression>), Equal(Box<PlanExpression>, Box<PlanExpression>),
@ -324,6 +325,7 @@ impl PlanExpression {
e.add_variables(set); e.add_variables(set);
} }
} }
PlanExpression::Exists(n) => n.add_variables(set),
} }
} }
} }

@ -61,7 +61,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
} else { } else {
PlanNode::Filter { PlanNode::Filter {
child: Box::new(right), child: Box::new(right),
expression: self.build_for_expression(e, variables)?, expression: self.build_for_expression(e, variables, graph_name)?,
} }
}; };
let possible_problem_vars = right let possible_problem_vars = right
@ -78,7 +78,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
} }
GraphPattern::Filter(e, p) => PlanNode::Filter { GraphPattern::Filter(e, p) => PlanNode::Filter {
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)?),
expression: self.build_for_expression(e, variables)?, expression: self.build_for_expression(e, variables, graph_name)?,
}, },
GraphPattern::Union(a, b) => { GraphPattern::Union(a, b) => {
//We flatten the UNIONs //We flatten the UNIONs
@ -111,7 +111,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
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)?),
position: variable_key(variables, &v), position: variable_key(variables, &v),
expression: self.build_for_expression(e, variables)?, expression: self.build_for_expression(e, variables, graph_name)?,
}, },
GraphPattern::Minus(_a, _b) => unimplemented!(), GraphPattern::Minus(_a, _b) => unimplemented!(),
GraphPattern::Service(_n, _p, _s) => unimplemented!(), GraphPattern::Service(_n, _p, _s) => unimplemented!(),
@ -123,12 +123,12 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
let by: Result<Vec<_>> = o let by: Result<Vec<_>> = o
.iter() .iter()
.map(|comp| match comp { .map(|comp| match comp {
OrderComparator::Asc(e) => { OrderComparator::Asc(e) => Ok(Comparator::Asc(
Ok(Comparator::Asc(self.build_for_expression(e, variables)?)) self.build_for_expression(e, variables, graph_name)?,
} )),
OrderComparator::Desc(e) => { OrderComparator::Desc(e) => Ok(Comparator::Desc(
Ok(Comparator::Desc(self.build_for_expression(e, variables)?)) self.build_for_expression(e, variables, graph_name)?,
} )),
}) })
.collect(); .collect();
PlanNode::Sort { PlanNode::Sort {
@ -202,6 +202,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
&self, &self,
expression: &Expression, expression: &Expression,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue,
) -> Result<PlanExpression> { ) -> Result<PlanExpression> {
Ok(match expression { Ok(match expression {
Expression::Constant(t) => match t { Expression::Constant(t) => match t {
@ -211,144 +212,172 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
TermOrVariable::Variable(v) => PlanExpression::Variable(variable_key(variables, v)), TermOrVariable::Variable(v) => PlanExpression::Variable(variable_key(variables, v)),
}, },
Expression::Or(a, b) => PlanExpression::Or( Expression::Or(a, b) => PlanExpression::Or(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::And(a, b) => PlanExpression::And( Expression::And(a, b) => PlanExpression::And(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::Equal(a, b) => PlanExpression::Equal( Expression::Equal(a, b) => PlanExpression::Equal(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::NotEqual(a, b) => PlanExpression::NotEqual( Expression::NotEqual(a, b) => PlanExpression::NotEqual(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::Greater(a, b) => PlanExpression::Greater( Expression::Greater(a, b) => PlanExpression::Greater(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::GreaterOrEq(a, b) => PlanExpression::GreaterOrEq( Expression::GreaterOrEq(a, b) => PlanExpression::GreaterOrEq(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::Lower(a, b) => PlanExpression::Lower( Expression::Lower(a, b) => PlanExpression::Lower(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::LowerOrEq(a, b) => PlanExpression::LowerOrEq( Expression::LowerOrEq(a, b) => PlanExpression::LowerOrEq(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::In(e, l) => PlanExpression::In( Expression::In(e, l) => PlanExpression::In(
Box::new(self.build_for_expression(e, variables)?), Box::new(self.build_for_expression(e, variables, graph_name)?),
self.expression_list(l, variables)?, self.expression_list(l, variables, graph_name)?,
), ),
Expression::NotIn(e, l) => PlanExpression::UnaryNot(Box::new(PlanExpression::In( Expression::NotIn(e, l) => PlanExpression::UnaryNot(Box::new(PlanExpression::In(
Box::new(self.build_for_expression(e, variables)?), Box::new(self.build_for_expression(e, variables, graph_name)?),
self.expression_list(l, variables)?, self.expression_list(l, variables, graph_name)?,
))), ))),
Expression::Add(a, b) => PlanExpression::Add( Expression::Add(a, b) => PlanExpression::Add(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::Sub(a, b) => PlanExpression::Sub( Expression::Sub(a, b) => PlanExpression::Sub(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::Mul(a, b) => PlanExpression::Mul( Expression::Mul(a, b) => PlanExpression::Mul(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::Div(a, b) => PlanExpression::Div( Expression::Div(a, b) => PlanExpression::Div(
Box::new(self.build_for_expression(a, variables)?), Box::new(self.build_for_expression(a, variables, graph_name)?),
Box::new(self.build_for_expression(b, variables)?), Box::new(self.build_for_expression(b, variables, graph_name)?),
), ),
Expression::UnaryPlus(e) => { Expression::UnaryPlus(e) => PlanExpression::UnaryPlus(Box::new(
PlanExpression::UnaryPlus(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(e, variables, graph_name)?,
} )),
Expression::UnaryMinus(e) => { Expression::UnaryMinus(e) => PlanExpression::UnaryMinus(Box::new(
PlanExpression::UnaryMinus(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(e, variables, graph_name)?,
} )),
Expression::UnaryNot(e) => { Expression::UnaryNot(e) => PlanExpression::UnaryNot(Box::new(
PlanExpression::UnaryNot(Box::new(self.build_for_expression(e, variables)?)) self.build_for_expression(e, variables, graph_name)?,
} )),
Expression::FunctionCall(function, parameters) => match function { Expression::FunctionCall(function, parameters) => match function {
Function::Str => PlanExpression::Str(Box::new( Function::Str => PlanExpression::Str(Box::new(self.build_for_expression(
self.build_for_expression(&parameters[0], variables)?, &parameters[0],
)), variables,
Function::Lang => PlanExpression::Lang(Box::new( graph_name,
self.build_for_expression(&parameters[0], variables)?, )?)),
)), Function::Lang => PlanExpression::Lang(Box::new(self.build_for_expression(
&parameters[0],
variables,
graph_name,
)?)),
Function::LangMatches => PlanExpression::LangMatches( Function::LangMatches => PlanExpression::LangMatches(
Box::new(self.build_for_expression(&parameters[0], variables)?), Box::new(self.build_for_expression(&parameters[0], variables, graph_name)?),
Box::new(self.build_for_expression(&parameters[1], variables)?), Box::new(self.build_for_expression(&parameters[1], variables, graph_name)?),
), ),
Function::Datatype => PlanExpression::Datatype(Box::new( Function::Datatype => PlanExpression::Datatype(Box::new(
self.build_for_expression(&parameters[0], variables)?, self.build_for_expression(&parameters[0], variables, graph_name)?,
)),
Function::IRI => PlanExpression::IRI(Box::new(
self.build_for_expression(&parameters[0], variables)?,
)), )),
Function::IRI => PlanExpression::IRI(Box::new(self.build_for_expression(
&parameters[0],
variables,
graph_name,
)?)),
Function::BNode => PlanExpression::BNode(match parameters.get(0) { Function::BNode => PlanExpression::BNode(match parameters.get(0) {
Some(e) => Some(Box::new(self.build_for_expression(e, variables)?)), Some(e) => Some(Box::new(
self.build_for_expression(e, variables, graph_name)?,
)),
None => None, None => None,
}), }),
Function::Year => PlanExpression::Year(Box::new( Function::Year => PlanExpression::Year(Box::new(self.build_for_expression(
self.build_for_expression(&parameters[0], variables)?, &parameters[0],
)), variables,
Function::Month => PlanExpression::Month(Box::new( graph_name,
self.build_for_expression(&parameters[0], variables)?, )?)),
)), Function::Month => PlanExpression::Month(Box::new(self.build_for_expression(
Function::Day => PlanExpression::Day(Box::new( &parameters[0],
self.build_for_expression(&parameters[0], variables)?, variables,
)), graph_name,
Function::Hours => PlanExpression::Hours(Box::new( )?)),
self.build_for_expression(&parameters[0], variables)?, Function::Day => PlanExpression::Day(Box::new(self.build_for_expression(
)), &parameters[0],
Function::Minutes => PlanExpression::Minutes(Box::new( variables,
self.build_for_expression(&parameters[0], variables)?, graph_name,
)), )?)),
Function::Seconds => PlanExpression::Seconds(Box::new( Function::Hours => PlanExpression::Hours(Box::new(self.build_for_expression(
self.build_for_expression(&parameters[0], variables)?, &parameters[0],
)), variables,
graph_name,
)?)),
Function::Minutes => PlanExpression::Minutes(Box::new(self.build_for_expression(
&parameters[0],
variables,
graph_name,
)?)),
Function::Seconds => PlanExpression::Seconds(Box::new(self.build_for_expression(
&parameters[0],
variables,
graph_name,
)?)),
Function::UUID => PlanExpression::UUID(), Function::UUID => PlanExpression::UUID(),
Function::StrUUID => PlanExpression::StrUUID(), Function::StrUUID => PlanExpression::StrUUID(),
Function::Coalesce => { Function::Coalesce => PlanExpression::Coalesce(self.expression_list(
PlanExpression::Coalesce(self.expression_list(&parameters, variables)?) &parameters,
} variables,
graph_name,
)?),
Function::If => PlanExpression::If( Function::If => PlanExpression::If(
Box::new(self.build_for_expression(&parameters[0], variables)?), Box::new(self.build_for_expression(&parameters[0], variables, graph_name)?),
Box::new(self.build_for_expression(&parameters[1], variables)?), Box::new(self.build_for_expression(&parameters[1], variables, graph_name)?),
Box::new(self.build_for_expression(&parameters[2], variables)?), Box::new(self.build_for_expression(&parameters[2], variables, graph_name)?),
), ),
Function::StrLang => PlanExpression::StrLang( Function::StrLang => PlanExpression::StrLang(
Box::new(self.build_for_expression(&parameters[0], variables)?), Box::new(self.build_for_expression(&parameters[0], variables, graph_name)?),
Box::new(self.build_for_expression(&parameters[1], variables)?), Box::new(self.build_for_expression(&parameters[1], variables, graph_name)?),
), ),
Function::SameTerm => PlanExpression::SameTerm( Function::SameTerm => PlanExpression::SameTerm(
Box::new(self.build_for_expression(&parameters[0], variables)?), Box::new(self.build_for_expression(&parameters[0], variables, graph_name)?),
Box::new(self.build_for_expression(&parameters[1], variables)?), Box::new(self.build_for_expression(&parameters[1], variables, graph_name)?),
), ),
Function::IsIRI => PlanExpression::IsIRI(Box::new( Function::IsIRI => PlanExpression::IsIRI(Box::new(self.build_for_expression(
self.build_for_expression(&parameters[0], variables)?, &parameters[0],
)), variables,
Function::IsBlank => PlanExpression::IsBlank(Box::new( graph_name,
self.build_for_expression(&parameters[0], variables)?, )?)),
)), Function::IsBlank => PlanExpression::IsBlank(Box::new(self.build_for_expression(
&parameters[0],
variables,
graph_name,
)?)),
Function::IsLiteral => PlanExpression::IsLiteral(Box::new( Function::IsLiteral => PlanExpression::IsLiteral(Box::new(
self.build_for_expression(&parameters[0], variables)?, self.build_for_expression(&parameters[0], variables, graph_name)?,
)), )),
Function::IsNumeric => PlanExpression::IsNumeric(Box::new( Function::IsNumeric => PlanExpression::IsNumeric(Box::new(
self.build_for_expression(&parameters[0], variables)?, self.build_for_expression(&parameters[0], variables, graph_name)?,
)), )),
Function::Regex => PlanExpression::Regex( Function::Regex => PlanExpression::Regex(
Box::new(self.build_for_expression(&parameters[0], variables)?), Box::new(self.build_for_expression(&parameters[0], variables, graph_name)?),
Box::new(self.build_for_expression(&parameters[1], variables)?), Box::new(self.build_for_expression(&parameters[1], variables, graph_name)?),
match parameters.get(2) { match parameters.get(2) {
Some(flags) => Some(Box::new(self.build_for_expression(flags, variables)?)), Some(flags) => Some(Box::new(
self.build_for_expression(flags, variables, graph_name)?,
)),
None => None, None => None,
}, },
), ),
@ -358,6 +387,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
parameters, parameters,
PlanExpression::BooleanCast, PlanExpression::BooleanCast,
variables, variables,
graph_name,
"boolean", "boolean",
)? )?
} else if *name == *xsd::DOUBLE { } else if *name == *xsd::DOUBLE {
@ -365,15 +395,23 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
parameters, parameters,
PlanExpression::DoubleCast, PlanExpression::DoubleCast,
variables, variables,
graph_name,
"double", "double",
)? )?
} else if *name == *xsd::FLOAT { } else if *name == *xsd::FLOAT {
self.build_cast(parameters, PlanExpression::FloatCast, variables, "float")? self.build_cast(
parameters,
PlanExpression::FloatCast,
variables,
graph_name,
"float",
)?
} else if *name == *xsd::DECIMAL { } else if *name == *xsd::DECIMAL {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DecimalCast, PlanExpression::DecimalCast,
variables, variables,
graph_name,
"decimal", "decimal",
)? )?
} else if *name == *xsd::INTEGER { } else if *name == *xsd::INTEGER {
@ -381,17 +419,31 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
parameters, parameters,
PlanExpression::IntegerCast, PlanExpression::IntegerCast,
variables, variables,
graph_name,
"integer", "integer",
)? )?
} else if *name == *xsd::DATE { } else if *name == *xsd::DATE {
self.build_cast(parameters, PlanExpression::DateCast, variables, "date")? self.build_cast(
parameters,
PlanExpression::DateCast,
variables,
graph_name,
"date",
)?
} else if *name == *xsd::TIME { } else if *name == *xsd::TIME {
self.build_cast(parameters, PlanExpression::TimeCast, variables, "time")? self.build_cast(
parameters,
PlanExpression::TimeCast,
variables,
graph_name,
"time",
)?
} else if *name == *xsd::DATE_TIME { } else if *name == *xsd::DATE_TIME {
self.build_cast( self.build_cast(
parameters, parameters,
PlanExpression::DateTimeCast, PlanExpression::DateTimeCast,
variables, variables,
graph_name,
"dateTime", "dateTime",
)? )?
} else if *name == *xsd::STRING { } else if *name == *xsd::STRING {
@ -399,6 +451,7 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
parameters, parameters,
PlanExpression::StringCast, PlanExpression::StringCast,
variables, variables,
graph_name,
"string", "string",
)? )?
} else { } else {
@ -408,7 +461,9 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
_ => unimplemented!(), _ => unimplemented!(),
}, },
Expression::Bound(v) => PlanExpression::Bound(variable_key(variables, v)), Expression::Bound(v) => PlanExpression::Bound(variable_key(variables, v)),
Expression::Exists(_) => unimplemented!(), Expression::Exists(n) => PlanExpression::Exists(Box::new(
self.build_for_graph_pattern(n, PlanNode::Init, variables, graph_name)?,
)),
}) })
} }
@ -417,12 +472,15 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
parameters: &[Expression], parameters: &[Expression],
constructor: impl Fn(Box<PlanExpression>) -> PlanExpression, constructor: impl Fn(Box<PlanExpression>) -> PlanExpression,
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue,
name: &'static str, name: &'static str,
) -> Result<PlanExpression> { ) -> Result<PlanExpression> {
if parameters.len() == 1 { if parameters.len() == 1 {
Ok(constructor(Box::new( Ok(constructor(Box::new(self.build_for_expression(
self.build_for_expression(&parameters[0], variables)?, &parameters[0],
))) variables,
graph_name,
)?)))
} else { } else {
Err(format_err!( Err(format_err!(
"The xsd:{} casting takes only one parameter", "The xsd:{} casting takes only one parameter",
@ -435,9 +493,10 @@ impl<'a, S: StoreConnection> PlanBuilder<'a, S> {
&self, &self,
l: &[Expression], l: &[Expression],
variables: &mut Vec<Variable>, variables: &mut Vec<Variable>,
graph_name: PatternValue,
) -> Result<Vec<PlanExpression>> { ) -> Result<Vec<PlanExpression>> {
l.iter() l.iter()
.map(|e| self.build_for_expression(e, variables)) .map(|e| self.build_for_expression(e, variables, graph_name))
.collect() .collect()
} }

@ -50,7 +50,6 @@ fn sparql_w3c_syntax_testsuite() -> Result<()> {
#[test] #[test]
fn sparql_w3c_query_evaluation_testsuite() -> Result<()> { fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
//TODO: dataset
let manifest_10_urls = vec![ let manifest_10_urls = vec![
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/algebra/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/algebra/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/ask/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/ask/manifest.ttl",
@ -60,6 +59,7 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/bound/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/bound/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/cast/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/cast/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/construct/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/construct/manifest.ttl",
// FROM and FROM NAMED "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/construct/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/distinct/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/distinct/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-equals/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-equals/manifest.ttl",
@ -75,6 +75,10 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/triple-match/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/triple-match/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/type-promotion/manifest.ttl", "http://www.w3.org/2001/sw/DataAccess/tests/data-r2/type-promotion/manifest.ttl",
]; ];
let manifest_11_urls =
vec!["http://www.w3.org/2009/sparql/docs/tests/data-sparql11/exists/manifest.ttl"];
let test_blacklist = vec![ let test_blacklist = vec![
//Multiple writing of the same xsd:integer. Our system does strong normalization. //Multiple writing of the same xsd:integer. Our system does strong normalization.
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/distinct/manifest#distinct-1").unwrap(), NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/distinct/manifest#distinct-1").unwrap(),
@ -103,6 +107,7 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
let mut failed = Vec::default(); let mut failed = Vec::default();
for test_result in manifest_10_urls for test_result in manifest_10_urls
.into_iter() .into_iter()
.chain(manifest_11_urls.into_iter())
.flat_map(|manifest| TestManifest::new(manifest)) .flat_map(|manifest| TestManifest::new(manifest))
{ {
let test = test_result?; let test = test_result?;

Loading…
Cancel
Save