Makes most open-word SPARQL tests pass

Do not make pass the one that distinguish simple literals and xsd:string
pull/10/head
Tpt 5 years ago
parent 8e87396d5e
commit 06c0773e5a
  1. 38
      lib/src/model/literal.rs
  2. 200
      lib/src/sparql/eval.rs
  3. 32
      lib/src/store/numeric_encoder.rs
  4. 38
      lib/tests/sparql_test_cases.rs

@ -1,6 +1,7 @@
use crate::model::named_node::NamedNode;
use crate::model::vocab::rdf;
use crate::model::vocab::xsd;
use chrono::format::{parse, Parsed, StrftimeItems};
use chrono::prelude::*;
use num_traits::identities::Zero;
use num_traits::FromPrimitive;
@ -47,6 +48,7 @@ enum LiteralContent {
Double(OrderedFloat<f64>),
Integer(i128),
Decimal(Decimal),
Date(Date<FixedOffset>),
NaiveDate(NaiveDate),
NaiveTime(NaiveTime),
DateTime(DateTime<FixedOffset>),
@ -106,9 +108,21 @@ impl Literal {
Err(_) => LiteralContent::TypedLiteral { value, datatype },
}
} else if datatype == *xsd::DATE {
match NaiveDate::parse_from_str(&value, "%Y-%m-%d") {
let mut parsed = Parsed::new();
match parse(&mut parsed, &value, StrftimeItems::new("%Y-%m-%d%:z")).and_then(|_| {
Ok(Date::from_utc(
parsed.to_naive_date()?,
parsed.to_fixed_offset()?,
))
}) {
Ok(value) => LiteralContent::Date(value),
Err(_) => match NaiveDate::parse_from_str(&value, "%Y-%m-%dZ") {
Ok(value) => LiteralContent::Date(Date::from_utc(value, FixedOffset::east(0))),
Err(_) => match NaiveDate::parse_from_str(&value, "%Y-%m-%d") {
Ok(value) => LiteralContent::NaiveDate(value),
Err(_) => LiteralContent::TypedLiteral { value, datatype },
},
},
}
} else if datatype == *xsd::TIME {
match NaiveTime::parse_from_str(&value, "%H:%M:%S") {
@ -152,6 +166,7 @@ impl Literal {
LiteralContent::Double(value) => Cow::Owned(value.to_string()),
LiteralContent::Integer(value) => Cow::Owned(value.to_string()),
LiteralContent::Decimal(value) => Cow::Owned(value.to_string()),
LiteralContent::Date(value) => Cow::Owned(value.to_string()),
LiteralContent::NaiveDate(value) => Cow::Owned(value.to_string()),
LiteralContent::NaiveTime(value) => Cow::Owned(value.to_string()),
LiteralContent::DateTime(value) => Cow::Owned(value.to_string()),
@ -183,7 +198,7 @@ impl Literal {
LiteralContent::Double(_) => &xsd::DOUBLE,
LiteralContent::Integer(_) => &xsd::INTEGER,
LiteralContent::Decimal(_) => &xsd::DECIMAL,
LiteralContent::NaiveDate(_) => &xsd::DATE,
LiteralContent::Date(_) | LiteralContent::NaiveDate(_) => &xsd::DATE,
LiteralContent::NaiveTime(_) => &xsd::TIME,
LiteralContent::DateTime(_) | LiteralContent::NaiveDateTime(_) => &xsd::DATE_TIME,
LiteralContent::TypedLiteral { ref datatype, .. } => datatype,
@ -252,7 +267,7 @@ impl Literal {
/// Checks if the literal has the datatype [xsd:date](http://www.w3.org/2001/XMLSchema#date) and is valid
pub fn is_date(&self) -> bool {
match self.0 {
LiteralContent::NaiveDate(_) => true,
LiteralContent::Date(_) | LiteralContent::NaiveDate(_) => true,
_ => false,
}
}
@ -351,13 +366,22 @@ impl Literal {
}
/// Returns the value of this literal as NaiveDate if possible
pub(crate) fn to_date(&self) -> Option<NaiveDate> {
pub(crate) fn to_naive_date(&self) -> Option<NaiveDate> {
match self.0 {
LiteralContent::Date(value) => Some(value.naive_utc()),
LiteralContent::NaiveDate(value) => Some(value),
_ => None,
}
}
/// Returns the value of this literal as Date if possible
pub(crate) fn to_date(&self) -> Option<Date<FixedOffset>> {
match self.0 {
LiteralContent::Date(value) => Some(value),
_ => None,
}
}
/// Returns the value of this literal as NaiveTime if possible
pub(crate) fn to_time(&self) -> Option<NaiveTime> {
match self.0 {
@ -498,6 +522,12 @@ impl From<Decimal> for Literal {
}
}
impl From<Date<FixedOffset>> for Literal {
fn from(value: Date<FixedOffset>) -> Self {
Literal(LiteralContent::Date(value))
}
}
impl From<NaiveDate> for Literal {
fn from(value: NaiveDate) -> Self {
Literal(LiteralContent::NaiveDate(value))

@ -319,31 +319,44 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
match expression {
PlanExpression::Constant(t) => Some(*t),
PlanExpression::Variable(v) => get_tuple_value(*v, tuple),
PlanExpression::Or(a, b) => match self.to_bool(self.eval_expression(a, tuple)?) {
PlanExpression::Or(a, b) => {
match self.eval_expression(a, tuple).and_then(|v| self.to_bool(v)) {
Some(true) => Some(true.into()),
Some(false) => self.eval_expression(b, tuple),
None => match self.to_bool(self.eval_expression(b, tuple)?) {
Some(true) => Some(true.into()),
_ => None,
},
},
PlanExpression::And(a, b) => match self.to_bool(self.eval_expression(a, tuple)?) {
None => {
if Some(true)
== self.eval_expression(b, tuple).and_then(|v| self.to_bool(v))
{
Some(true.into())
} else {
None
}
}
}
}
PlanExpression::And(a, b) => match self
.eval_expression(a, tuple)
.and_then(|v| self.to_bool(v))
{
Some(true) => self.eval_expression(b, tuple),
Some(false) => Some(false.into()),
None => match self.to_bool(self.eval_expression(b, tuple)?) {
Some(false) => Some(false.into()),
_ => None,
},
None => {
if Some(false) == self.eval_expression(b, tuple).and_then(|v| self.to_bool(v)) {
Some(false.into())
} else {
None
}
}
},
PlanExpression::Equal(a, b) => {
let a = self.eval_expression(a, tuple)?;
let b = self.eval_expression(b, tuple)?;
Some(self.equals(a, b).into())
self.equals(a, b).map(|v| v.into())
}
PlanExpression::NotEqual(a, b) => {
let a = self.eval_expression(a, tuple)?;
let b = self.eval_expression(b, tuple)?;
Some(self.not_equals(a, b).into())
self.equals(a, b).map(|v| (!v).into())
}
PlanExpression::Greater(a, b) => Some(
(self.partial_cmp_literals(
@ -384,7 +397,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
let mut error = false;
for possible in l {
if let Some(possible) = self.eval_expression(possible, tuple) {
if self.equals(needed, possible) {
if Some(true) == self.equals(needed, possible) {
return Some(true.into());
}
} else {
@ -475,18 +488,21 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
None => Some(BlankNode::default().into()),
},
PlanExpression::Year(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::Date(date) => Some(date.year().into()),
EncodedTerm::NaiveDate(date) => Some(date.year().into()),
EncodedTerm::DateTime(date_time) => Some(date_time.year().into()),
EncodedTerm::NaiveDateTime(date_time) => Some(date_time.year().into()),
_ => None,
},
PlanExpression::Month(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::Date(date) => Some(date.year().into()),
EncodedTerm::NaiveDate(date) => Some(date.month().into()),
EncodedTerm::DateTime(date_time) => Some(date_time.month().into()),
EncodedTerm::NaiveDateTime(date_time) => Some(date_time.month().into()),
_ => None,
},
PlanExpression::Day(e) => match self.eval_expression(e, tuple)? {
EncodedTerm::Date(date) => Some(date.year().into()),
EncodedTerm::NaiveDate(date) => Some(date.day().into()),
EncodedTerm::DateTime(date_time) => Some(date_time.day().into()),
EncodedTerm::NaiveDateTime(date_time) => Some(date_time.day().into()),
@ -753,6 +769,7 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::DoubleLiteral(value) => self.store.insert_str(&value.to_string()).ok(),
EncodedTerm::IntegerLiteral(value) => self.store.insert_str(&value.to_string()).ok(),
EncodedTerm::DecimalLiteral(value) => self.store.insert_str(&value.to_string()).ok(),
EncodedTerm::Date(value) => self.store.insert_str(&value.to_string()).ok(),
EncodedTerm::NaiveDate(value) => self.store.insert_str(&value.to_string()).ok(),
EncodedTerm::NaiveTime(value) => self.store.insert_str(&value.to_string()).ok(),
EncodedTerm::DateTime(value) => self.store.insert_str(&value.to_string()).ok(),
@ -874,12 +891,116 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
)
}
fn equals(&self, a: EncodedTerm, b: EncodedTerm) -> bool {
(a == b || self.partial_cmp_literals(a, b) == Some(Ordering::Equal))
#[allow(clippy::float_cmp)]
fn equals(&self, a: EncodedTerm, b: EncodedTerm) -> Option<bool> {
match a {
EncodedTerm::DefaultGraph
| EncodedTerm::NamedNode { .. }
| EncodedTerm::BlankNode(_)
| EncodedTerm::LangStringLiteral { .. } => Some(a == b),
EncodedTerm::StringLiteral { value_id: a } => match b {
EncodedTerm::StringLiteral { value_id: b } => Some(a == b),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::BooleanLiteral(a) => match b {
EncodedTerm::BooleanLiteral(b) => Some(a == b),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::FloatLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(a == b),
EncodedTerm::DoubleLiteral(b) => Some(a.to_f64()? == *b),
EncodedTerm::IntegerLiteral(b) => Some(*a == b.to_f32()?),
EncodedTerm::DecimalLiteral(b) => Some(*a == b.to_f32()?),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::DoubleLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(*a == b.to_f64()?),
EncodedTerm::DoubleLiteral(b) => Some(a == b),
EncodedTerm::IntegerLiteral(b) => Some(*a == b.to_f64()?),
EncodedTerm::DecimalLiteral(b) => Some(*a == b.to_f64()?),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::IntegerLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(a.to_f32()? == *b),
EncodedTerm::DoubleLiteral(b) => Some(a.to_f64()? == *b),
EncodedTerm::IntegerLiteral(b) => Some(a == b),
EncodedTerm::DecimalLiteral(b) => Some(Decimal::from_i128(a)? == b),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::DecimalLiteral(a) => match b {
EncodedTerm::FloatLiteral(b) => Some(a.to_f32()? == *b),
EncodedTerm::DoubleLiteral(b) => Some(a.to_f64()? == *b),
EncodedTerm::IntegerLiteral(b) => Some(a == Decimal::from_i128(b)?),
EncodedTerm::DecimalLiteral(b) => Some(a == b),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::TypedLiteral { .. } => match b {
EncodedTerm::TypedLiteral { .. } if a == b => Some(true),
EncodedTerm::NamedNode { .. }
| EncodedTerm::BlankNode { .. }
| EncodedTerm::LangStringLiteral { .. } => Some(false),
_ => None,
},
EncodedTerm::Date(a) => match b {
EncodedTerm::Date(b) => Some(a == b),
EncodedTerm::NaiveDate(b) => {
if a.naive_utc() == b {
None
} else {
Some(false)
}
}
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::NaiveDate(a) => match b {
EncodedTerm::NaiveDate(b) => Some(a == b),
EncodedTerm::Date(b) => {
if a == b.naive_utc() {
None
} else {
Some(false)
}
}
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::NaiveTime(a) => match b {
EncodedTerm::NaiveTime(b) => Some(a == b),
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::DateTime(a) => match b {
EncodedTerm::DateTime(b) => Some(a == b),
EncodedTerm::NaiveDateTime(b) => {
if a.naive_utc() == b {
None
} else {
Some(false)
}
}
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
EncodedTerm::NaiveDateTime(a) => match b {
EncodedTerm::NaiveDateTime(b) => Some(a == b),
EncodedTerm::DateTime(b) => {
if a == b.naive_utc() {
None
} else {
Some(false)
}
}
EncodedTerm::TypedLiteral { .. } => None,
_ => Some(false),
},
}
fn not_equals(&self, a: EncodedTerm, b: EncodedTerm) -> bool {
(a != b && self.partial_cmp_literals(a, b) != Some(Ordering::Equal))
}
fn cmp_according_to_expression(
@ -955,13 +1076,16 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
EncodedTerm::DecimalLiteral(b) => a.partial_cmp(&b),
_ => None,
},
EncodedTerm::NaiveDate(a) => {
if let EncodedTerm::NaiveDate(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::Date(a) => match b {
EncodedTerm::Date(ref b) => a.partial_cmp(b),
EncodedTerm::NaiveDate(ref b) => a.naive_utc().partial_cmp(b), //TODO: check edges
_ => None,
},
EncodedTerm::NaiveDate(a) => match b {
EncodedTerm::NaiveDate(ref b) => a.partial_cmp(b),
EncodedTerm::Date(ref b) => a.partial_cmp(&b.naive_utc()), //TODO: check edges
_ => None,
},
EncodedTerm::NaiveTime(a) => {
if let EncodedTerm::NaiveTime(ref b) = b {
a.partial_cmp(b)
@ -969,20 +1093,16 @@ impl<'a, S: StoreConnection + 'a> SimpleEvaluator<S> {
None
}
}
EncodedTerm::DateTime(a) => {
if let EncodedTerm::DateTime(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::NaiveDateTime(a) => {
if let EncodedTerm::NaiveDateTime(ref b) = b {
a.partial_cmp(b)
} else {
None
}
}
EncodedTerm::DateTime(a) => match b {
EncodedTerm::DateTime(ref b) => a.partial_cmp(b),
EncodedTerm::NaiveDateTime(ref b) => a.naive_utc().partial_cmp(b), //TODO: check edges
_ => None,
},
EncodedTerm::NaiveDateTime(a) => match b {
EncodedTerm::NaiveDateTime(ref b) => a.partial_cmp(b),
EncodedTerm::DateTime(ref b) => a.partial_cmp(&b.naive_utc()), //TODO: check edges
_ => None,
},
_ => None,
}
}

@ -126,8 +126,9 @@ const TYPE_INTEGER_LITERAL: u8 = 11;
const TYPE_DECIMAL_LITERAL: u8 = 12;
const TYPE_DATE_TIME_LITERAL: u8 = 13;
const TYPE_NAIVE_DATE_TIME_LITERAL: u8 = 14;
const TYPE_NAIVE_DATE_LITERAL: u8 = 15;
const TYPE_NAIVE_TIME_LITERAL: u8 = 16;
const TYPE_DATE_LITERAL: u8 = 15;
const TYPE_NAIVE_DATE_LITERAL: u8 = 16;
const TYPE_NAIVE_TIME_LITERAL: u8 = 17;
pub static ENCODED_DEFAULT_GRAPH: EncodedTerm = EncodedTerm::DefaultGraph;
pub static ENCODED_EMPTY_STRING_LITERAL: EncodedTerm = EncodedTerm::StringLiteral {
@ -177,6 +178,7 @@ pub enum EncodedTerm {
DoubleLiteral(OrderedFloat<f64>),
IntegerLiteral(i128),
DecimalLiteral(Decimal),
Date(Date<FixedOffset>),
NaiveDate(NaiveDate),
NaiveTime(NaiveTime),
DateTime(DateTime<FixedOffset>),
@ -208,6 +210,7 @@ impl EncodedTerm {
| EncodedTerm::DoubleLiteral(_)
| EncodedTerm::IntegerLiteral(_)
| EncodedTerm::DecimalLiteral(_)
| EncodedTerm::Date(_)
| EncodedTerm::NaiveDate(_)
| EncodedTerm::NaiveTime(_)
| EncodedTerm::DateTime(_)
@ -228,6 +231,7 @@ impl EncodedTerm {
EncodedTerm::DoubleLiteral(..) => Some(ENCODED_XSD_DOUBLE_NAMED_NODE),
EncodedTerm::IntegerLiteral(..) => Some(ENCODED_XSD_INTEGER_NAMED_NODE),
EncodedTerm::DecimalLiteral(..) => Some(ENCODED_XSD_DECIMAL_NAMED_NODE),
EncodedTerm::Date(..) => Some(ENCODED_XSD_DATE_NAMED_NODE),
EncodedTerm::NaiveDate(..) => Some(ENCODED_XSD_DATE_NAMED_NODE),
EncodedTerm::NaiveTime(..) => Some(ENCODED_XSD_TIME_NAMED_NODE),
EncodedTerm::DateTime(..) | EncodedTerm::NaiveDateTime(..) => {
@ -251,6 +255,7 @@ impl EncodedTerm {
EncodedTerm::DoubleLiteral(_) => TYPE_DOUBLE_LITERAL,
EncodedTerm::IntegerLiteral(_) => TYPE_INTEGER_LITERAL,
EncodedTerm::DecimalLiteral(_) => TYPE_DECIMAL_LITERAL,
EncodedTerm::Date(_) => TYPE_DATE_LITERAL,
EncodedTerm::NaiveDate(_) => TYPE_NAIVE_DATE_LITERAL,
EncodedTerm::NaiveTime(_) => TYPE_NAIVE_TIME_LITERAL,
EncodedTerm::DateTime(_) => TYPE_DATE_TIME_LITERAL,
@ -301,6 +306,12 @@ impl From<Decimal> for EncodedTerm {
}
}
impl From<Date<FixedOffset>> for EncodedTerm {
fn from(value: Date<FixedOffset>) -> Self {
EncodedTerm::Date(value)
}
}
impl From<NaiveDate> for EncodedTerm {
fn from(value: NaiveDate) -> Self {
EncodedTerm::NaiveDate(value)
@ -401,6 +412,12 @@ impl<R: Read> TermReader for R {
self.read_exact(&mut buffer)?;
Ok(EncodedTerm::DecimalLiteral(Decimal::deserialize(buffer)))
}
TYPE_DATE_LITERAL => Ok(EncodedTerm::Date(Date::from_utc(
NaiveDate::from_num_days_from_ce_opt(self.read_i32::<LittleEndian>()?)
.ok_or_else(|| format_err!("Invalid date serialization"))?,
FixedOffset::east_opt(self.read_i32::<LittleEndian>()?)
.ok_or_else(|| format_err!("Invalid timezone offset"))?,
))),
TYPE_NAIVE_DATE_LITERAL => Ok(EncodedTerm::NaiveDate(
NaiveDate::from_num_days_from_ce_opt(self.read_i32::<LittleEndian>()?)
.ok_or_else(|| format_err!("Invalid date serialization"))?,
@ -508,6 +525,10 @@ impl<R: Write> TermWriter for R {
EncodedTerm::DoubleLiteral(value) => self.write_f64::<LittleEndian>(*value)?,
EncodedTerm::IntegerLiteral(value) => self.write_i128::<LittleEndian>(value)?,
EncodedTerm::DecimalLiteral(value) => self.write_all(&value.serialize())?,
EncodedTerm::Date(value) => {
self.write_i32::<LittleEndian>(value.num_days_from_ce())?;
self.write_i32::<LittleEndian>(value.timezone().local_minus_utc())?;
}
EncodedTerm::NaiveDate(value) => {
self.write_i32::<LittleEndian>(value.num_days_from_ce())?;
}
@ -608,10 +629,14 @@ impl<S: StringStore> Encoder<S> {
.ok_or_else(|| format_err!("decimal literal without decimal value"))?
.into()
} else if literal.is_date() {
if let Some(date) = literal.to_date() {
date.into()
} else {
literal
.to_date()
.to_naive_date()
.ok_or_else(|| format_err!("date literal without date value"))?
.into()
}
} else if literal.is_time() {
literal
.to_time()
@ -808,6 +833,7 @@ impl<S: StringStore> Encoder<S> {
EncodedTerm::DoubleLiteral(value) => Ok(Literal::from(*value).into()),
EncodedTerm::IntegerLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::DecimalLiteral(value) => Ok(Literal::from(value).into()),
EncodedTerm::Date(value) => Ok(Literal::from(value).into()),
EncodedTerm::NaiveDate(value) => Ok(Literal::from(value).into()),
EncodedTerm::NaiveTime(value) => Ok(Literal::from(value).into()),
EncodedTerm::DateTime(value) => Ok(Literal::from(value).into()),

@ -50,7 +50,7 @@ fn sparql_w3c_syntax_testsuite() -> Result<()> {
#[test]
fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
//TODO: dataset open-world
//TODO: dataset
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/ask/manifest.ttl",
@ -66,6 +66,7 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-ops/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/graph/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/i18n/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/optional/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/reduced/manifest.ttl",
"http://www.w3.org/2001/sw/DataAccess/tests/data-r2/regex/manifest.ttl",
@ -82,6 +83,8 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest#dawg-str-2").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-equals/manifest#eq-graph-1").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-equals/manifest#eq-graph-2").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest#open-eq-01").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest#open-eq-04").unwrap(),
//Multiple writing of the same xsd:double. Our system does strong normalization.
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest#sameTerm").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest#sameTerm-simple").unwrap(),
@ -89,12 +92,15 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest#sameTerm-not-eq").unwrap(),
//Simple literal vs xsd:string. We apply RDF 1.1
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/distinct/manifest#distinct-2").unwrap(),
//Test on curly brace scoping with OPTIONAL filter
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/optional-filter/manifest#dawg-optional-filter-005-not-simplified").unwrap(),
//DATATYPE("foo"@en) returns rdf:langString in SPARQL 1.1
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest#dawg-datatype-2").unwrap()
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest#open-eq-08").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest#open-eq-10").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest#open-eq-11").unwrap(),
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/open-world/manifest#open-eq-12").unwrap(),
//DATATYPE("foo"@en) returns rdf:langString in RDF 1.1
NamedNode::parse("http://www.w3.org/2001/sw/DataAccess/tests/data-r2/expr-builtin/manifest#dawg-datatype-2").unwrap(),
];
let mut failed = Vec::default();
for test_result in manifest_10_urls
.into_iter()
.flat_map(|manifest| TestManifest::new(manifest))
@ -119,17 +125,15 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
.connection()?
.prepare_query(&read_file_to_string(&test.query)?, Some(&test.query))
{
Err(error) => assert!(
false,
Err(error) => failed.push(format!(
"Failure to parse query of {} with error: {}",
test, error
),
)),
Ok(query) => match query.exec() {
Err(error) => assert!(
false,
Err(error) => failed.push(format!(
"Failure to execute query of {} with error: {}",
test, error
),
)),
Ok(result) => {
let expected_graph =
load_sparql_query_result_graph(test.result.as_ref().unwrap())?;
@ -139,15 +143,13 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
.is_some();
let actual_graph = to_graph(result, with_order)?;
if !actual_graph.is_isomorphic(&expected_graph) {
assert!(
false,
"Failure on {}.\nExpected file:\n{}\nOutput file:\n{}\nParsed query:\n{}\nData:\n{}\n",
failed.push(format!("Failure on {}.\nExpected file:\n{}\nOutput file:\n{}\nParsed query:\n{}\nData:\n{}\n",
test,
expected_graph,
actual_graph,
Query::parse(&read_file_to_string(&test.query)?, Some(&test.query)).unwrap(),
repository_to_string(&repository)
)
))
}
}
},
@ -156,6 +158,12 @@ fn sparql_w3c_query_evaluation_testsuite() -> Result<()> {
assert!(false, "Not supported test: {}", test);
}
}
assert!(
failed.is_empty(),
"{} tests failed:\n{}",
failed.len(),
failed.join("\n")
);
Ok(())
}

Loading…
Cancel
Save