Spargebra: Uses oxrdf terms

pull/190/head
Tpt 3 years ago
parent 621c134ed7
commit 967dbacad7
  1. 1
      Cargo.lock
  2. 2
      Cargo.toml
  3. 2
      lib/Cargo.toml
  4. 2
      lib/oxrdf/src/blank_node.rs
  5. 20
      lib/oxrdf/src/literal.rs
  6. 6
      lib/oxrdf/src/named_node.rs
  7. 107
      lib/oxrdf/src/triple.rs
  8. 5
      lib/spargebra/Cargo.toml
  9. 2
      lib/spargebra/README.md
  10. 72
      lib/spargebra/src/algebra.rs
  11. 0
      lib/spargebra/src/lib.rs
  12. 103
      lib/spargebra/src/parser.rs
  13. 0
      lib/spargebra/src/query.rs
  14. 627
      lib/spargebra/src/term.rs
  15. 6
      lib/spargebra/src/update.rs
  16. 18
      lib/src/sparql/algebra.rs
  17. 10
      lib/src/sparql/mod.rs
  18. 109
      lib/src/sparql/plan_builder.rs
  19. 149
      lib/src/sparql/update.rs

1
Cargo.lock generated

@ -1556,6 +1556,7 @@ version = "0.1.0"
dependencies = [
"oxilangtag",
"oxiri",
"oxrdf",
"peg",
"rand",
]

@ -3,10 +3,10 @@ members = [
"js",
"lib",
"lib/oxrdf",
"lib/spargebra",
"python",
"rocksdb-sys",
"server",
"spargebra",
"testsuite"
]

@ -43,7 +43,7 @@ sophia_api = { version = "0.7", optional = true }
json-event-parser = "0.1"
num_cpus = "1"
oxrdf = { version = "0.1", path="oxrdf", features = ["rdf-star"] }
spargebra = { version = "0.1", path="../spargebra", features = ["rdf-star"] }
spargebra = { version = "0.1", path="spargebra", features = ["rdf-star"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
libc = "0.2"

@ -184,7 +184,7 @@ impl<'a> BlankNodeRef<'a> {
/// use oxrdf::BlankNode;
///
/// assert_eq!(BlankNode::new_from_unique_id(128).as_ref().unique_id(), Some(128));
/// assert_eq!(BlankNode::new("128")?.as_ref().unique_id(), None);
/// assert_eq!(BlankNode::new("foo")?.as_ref().unique_id(), None);
/// # Result::<_,oxrdf::BlankNodeIdParseError>::Ok(())
/// ```
#[inline]

@ -8,7 +8,7 @@ use std::fmt;
use std::fmt::Write;
use std::option::Option;
/// An owned RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
/// An owned RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
@ -43,13 +43,13 @@ enum LiteralContent {
}
impl Literal {
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal)
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal).
#[inline]
pub fn new_simple_literal(value: impl Into<String>) -> Self {
Self(LiteralContent::String(value.into()))
}
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri)
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
#[inline]
pub fn new_typed_literal(value: impl Into<String>, datatype: impl Into<NamedNode>) -> Self {
let value = value.into();
@ -61,7 +61,7 @@ impl Literal {
})
}
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
#[inline]
pub fn new_language_tagged_literal(
value: impl Into<String>,
@ -75,7 +75,7 @@ impl Literal {
))
}
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
///
/// It is the responsibility of the caller to check that `language`
/// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag,
@ -93,7 +93,7 @@ impl Literal {
})
}
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form)
/// The literal [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
#[inline]
pub fn value(&self) -> &str {
self.as_ref().value()
@ -293,7 +293,7 @@ impl From<f64> for Literal {
}
}
/// A borrowed RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal)
/// A borrowed RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
@ -327,13 +327,13 @@ enum LiteralRefContent<'a> {
}
impl<'a> LiteralRef<'a> {
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal)
/// Builds an RDF [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal).
#[inline]
pub fn new_simple_literal(value: &'a str) -> Self {
LiteralRef(LiteralRefContent::String(value))
}
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri)
/// Builds an RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) with a [datatype](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
#[inline]
pub fn new_typed_literal(value: &'a str, datatype: impl Into<NamedNodeRef<'a>>) -> Self {
let datatype = datatype.into();
@ -344,7 +344,7 @@ impl<'a> LiteralRef<'a> {
})
}
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
/// Builds an RDF [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
///
/// It is the responsibility of the caller to check that `language`
/// is valid [BCP47](https://tools.ietf.org/html/bcp47) language tag,

@ -1,7 +1,7 @@
use oxiri::{Iri, IriParseError};
use std::fmt;
/// An owned RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
/// An owned RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
@ -19,7 +19,7 @@ pub struct NamedNode {
}
impl NamedNode {
/// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
/// Builds and validate an RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
pub fn new(iri: impl Into<String>) -> Result<Self, IriParseError> {
Ok(Self::new_from_iri(Iri::parse(iri.into())?))
}
@ -90,7 +90,7 @@ impl PartialEq<NamedNode> for &str {
}
}
/// A borrowed RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri)
/// A borrowed RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```

@ -694,21 +694,36 @@ impl<'a> From<TermRef<'a>> for Term {
}
}
/// An owned [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
/// An owned [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// use oxrdf::{Triple, NamedNode};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o>",
/// Triple {
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Triple {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: Subject,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNode,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: Term,
}
impl Triple {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
#[inline]
pub fn new(
subject: impl Into<Subject>,
@ -722,7 +737,7 @@ impl Triple {
}
}
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline]
pub fn in_graph(self, graph_name: impl Into<GraphName>) -> Quad {
Quad {
@ -750,21 +765,37 @@ impl fmt::Display for Triple {
}
}
/// A borrowed [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
/// A borrowed [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation:
/// ```
/// use oxrdf::{TripleRef, NamedNodeRef};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o>",
/// TripleRef {
/// subject: NamedNodeRef::new("http://example.com/s")?.into(),
/// predicate: NamedNodeRef::new("http://example.com/p")?,
/// object: NamedNodeRef::new("http://example.com/o")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct TripleRef<'a> {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: SubjectRef<'a>,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNodeRef<'a>,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: TermRef<'a>,
}
impl<'a> TripleRef<'a> {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple)
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
#[inline]
pub fn new(
subject: impl Into<SubjectRef<'a>>,
@ -778,7 +809,7 @@ impl<'a> TripleRef<'a> {
}
}
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// Encodes that this triple is in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline]
pub fn in_graph(self, graph_name: impl Into<GraphNameRef<'a>>) -> QuadRef<'a> {
QuadRef {
@ -978,16 +1009,32 @@ impl<'a> From<GraphNameRef<'a>> for GraphName {
}
}
/// An owned [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// An owned [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
///
/// The default string formatter is returning an N-Quads compatible representation:
/// ```
/// use oxrdf::{Quad, NamedNode};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// Quad {
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// graph_name: NamedNode::new("http://example.com/g")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Quad {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: Subject,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNode,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: Term,
/// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is.
@ -995,7 +1042,7 @@ pub struct Quad {
}
impl Quad {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline]
pub fn new(
subject: impl Into<Subject>,
@ -1040,16 +1087,32 @@ impl From<Quad> for Triple {
}
}
/// A borrowed [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// A borrowed [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
///
/// The default string formatter is returning an N-Quads compatible representation:
/// ```
/// use oxrdf::{QuadRef, NamedNodeRef};
///
/// assert_eq!(
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// QuadRef {
/// subject: NamedNodeRef::new("http://example.com/s")?.into(),
/// predicate: NamedNodeRef::new("http://example.com/p")?,
/// object: NamedNodeRef::new("http://example.com/o")?.into(),
/// graph_name: NamedNodeRef::new("http://example.com/g")?.into(),
/// }.to_string()
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Copy, Hash)]
pub struct QuadRef<'a> {
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple
/// The [subject](https://www.w3.org/TR/rdf11-concepts/#dfn-subject) of this triple.
pub subject: SubjectRef<'a>,
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple
/// The [predicate](https://www.w3.org/TR/rdf11-concepts/#dfn-predicate) of this triple.
pub predicate: NamedNodeRef<'a>,
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple
/// The [object](https://www.w3.org/TR/rdf11-concepts/#dfn-object) of this triple.
pub object: TermRef<'a>,
/// The name of the RDF [graph](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-graph) in which the triple is.
@ -1057,7 +1120,7 @@ pub struct QuadRef<'a> {
}
impl<'a> QuadRef<'a> {
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset)
/// Builds an RDF [triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) in a [RDF dataset](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-dataset).
#[inline]
pub fn new(
subject: impl Into<SubjectRef<'a>>,

@ -5,7 +5,7 @@ authors = ["Tpt <thomas@pellissier-tanon.fr>"]
license = "MIT OR Apache-2.0"
readme = "README.md"
keywords = ["SPARQL"]
repository = "https://github.com/oxigraph/oxigraph/tree/v0.3/spargebra"
repository = "https://github.com/oxigraph/oxigraph/tree/master/lib/spargebra"
homepage = "https://oxigraph.org/"
description = """
A SPARQL parser
@ -14,13 +14,14 @@ edition = "2021"
[features]
default = []
rdf-star = []
rdf-star = ["oxrdf/rdf-star"]
[dependencies]
peg = "0.7"
rand = "0.8"
oxiri = "0.1"
oxilangtag = "0.1"
oxrdf = { version = "0.1", path="../oxrdf" }
[package.metadata.docs.rs]
all-features = true

@ -1,5 +1,5 @@
Spargebra
========
=========
[![Latest Version](https://img.shields.io/crates/v/spargebra.svg)](https://crates.io/crates/spargebra)
[![Released API docs](https://docs.rs/spargebra/badge.svg)](https://docs.rs/spargebra)

@ -1,7 +1,7 @@
//! [SPARQL 1.1 Query Algebra](https://www.w3.org/TR/sparql11-query/#sparqlQuery) representation
use crate::term::print_quoted_str;
use crate::term::*;
use oxrdf::LiteralRef;
use std::fmt;
/// A [property path expression](https://www.w3.org/TR/sparql11-query/#defn_PropertyPathExpr)
@ -21,7 +21,7 @@ impl PropertyPathExpression {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self {
Self::NamedNode(p) => p.fmt_sse(f),
Self::NamedNode(p) => write!(f, "{}", p),
Self::Reverse(p) => {
write!(f, "(reverse ")?;
p.fmt_sse(f)?;
@ -59,8 +59,7 @@ impl PropertyPathExpression {
Self::NegatedPropertySet(p) => {
write!(f, "(notoneof")?;
for p in p {
write!(f, " ")?;
p.fmt_sse(f)?;
write!(f, " {}", p)?;
}
write!(f, ")")
}
@ -150,9 +149,9 @@ impl Expression {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::Literal(l) => l.fmt_sse(f),
Self::Variable(var) => var.fmt_sse(f),
Self::NamedNode(node) => write!(f, "{}", node),
Self::Literal(l) => write!(f, "{}", l),
Self::Variable(var) => write!(f, "{}", var),
Self::Or(a, b) => fmt_sse_binary_expression(f, "||", a, b),
Self::And(a, b) => fmt_sse_binary_expression(f, "&&", a, b),
Self::Equal(a, b) => fmt_sse_binary_expression(f, "=", a, b),
@ -192,9 +191,7 @@ impl Expression {
write!(f, ")")
}
Self::Bound(v) => {
write!(f, "(bound ")?;
v.fmt_sse(f)?;
write!(f, ")")
write!(f, "(bound {})", v)
}
Self::If(a, b, c) => {
write!(f, "(if ")?;
@ -442,7 +439,7 @@ impl Function {
Self::Object => write!(f, "object"),
#[cfg(feature = "rdf-star")]
Self::IsTriple => write!(f, "istriple"),
Self::Custom(iri) => iri.fmt_sse(f),
Self::Custom(iri) => write!(f, "{}", iri),
}
}
}
@ -658,9 +655,7 @@ impl GraphPattern {
variable,
expression,
} => {
write!(f, "(extend ((")?;
variable.fmt_sse(f)?;
write!(f, " ")?;
write!(f, "(extend (({} ", variable)?;
expression.fmt_sse(f)?;
write!(f, ")) ")?;
inner.fmt_sse(f)?;
@ -697,7 +692,7 @@ impl GraphPattern {
if i > 0 {
write!(f, " ")?;
}
v.fmt_sse(f)?;
write!(f, "{}", v)?;
}
write!(f, ") (")?;
for (i, (v, a)) in aggregates.iter().enumerate() {
@ -706,9 +701,7 @@ impl GraphPattern {
}
write!(f, "(")?;
a.fmt_sse(f)?;
write!(f, " ")?;
v.fmt_sse(f)?;
write!(f, ")")?;
write!(f, " {})", v)?;
}
write!(f, ") ")?;
inner.fmt_sse(f)?;
@ -720,19 +713,14 @@ impl GraphPattern {
} => {
write!(f, "(table (vars")?;
for var in variables {
write!(f, " ")?;
var.fmt_sse(f)?;
write!(f, " {}", var)?;
}
write!(f, ")")?;
for row in bindings {
write!(f, " (row")?;
for (value, var) in row.iter().zip(variables) {
if let Some(value) = value {
write!(f, " (")?;
var.fmt_sse(f)?;
write!(f, " ")?;
value.fmt_sse(f)?;
write!(f, ")")?;
write!(f, " ({} {})", var, value)?;
}
}
write!(f, ")")?;
@ -757,7 +745,7 @@ impl GraphPattern {
if i > 0 {
write!(f, " ")?;
}
v.fmt_sse(f)?;
write!(f, "{}", v)?;
}
write!(f, ") ")?;
inner.fmt_sse(f)?;
@ -1213,8 +1201,7 @@ impl AggregateExpression {
}
expr.fmt_sse(f)?;
if let Some(separator) = separator {
write!(f, " ")?;
print_quoted_str(separator, f)?;
write!(f, " {}", LiteralRef::new_simple_literal(separator))?;
}
write!(f, ")")
}
@ -1223,8 +1210,7 @@ impl AggregateExpression {
expr,
distinct,
} => {
write!(f, "(")?;
name.fmt_sse(f)?;
write!(f, "({}", name)?;
if *distinct {
write!(f, " distinct")?;
}
@ -1294,16 +1280,22 @@ impl fmt::Display for AggregateExpression {
} => {
if *distinct {
if let Some(separator) = separator {
write!(f, "GROUP_CONCAT(DISTINCT {}; SEPARATOR = ", expr)?;
print_quoted_str(separator, f)?;
write!(f, ")")
write!(
f,
"GROUP_CONCAT(DISTINCT {}; SEPARATOR = {})",
expr,
LiteralRef::new_simple_literal(separator)
)
} else {
write!(f, "GROUP_CONCAT(DISTINCT {})", expr)
}
} else if let Some(separator) = separator {
write!(f, "GROUP_CONCAT({}; SEPARATOR = ", expr)?;
print_quoted_str(separator, f)?;
write!(f, ")")
write!(
f,
"GROUP_CONCAT({}; SEPARATOR = {})",
expr,
LiteralRef::new_simple_literal(separator)
)
} else {
write!(f, "GROUP_CONCAT({})", expr)
}
@ -1374,16 +1366,14 @@ impl QueryDataset {
if i > 0 {
write!(f, " ")?;
}
graph_name.fmt_sse(f)?;
write!(f, "{}", graph_name)?;
}
if let Some(named) = &self.named {
for (i, graph_name) in named.iter().enumerate() {
if !self.default.is_empty() || i > 0 {
write!(f, " ")?;
}
write!(f, "(named ")?;
graph_name.fmt_sse(f)?;
write!(f, ")")?;
write!(f, "(named {})", graph_name)?;
}
}
write!(f, ")")
@ -1419,7 +1409,7 @@ impl GraphTarget {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::NamedNode(node) => write!(f, "{}", node),
Self::DefaultGraph => write!(f, "default"),
Self::NamedGraphs => write!(f, "named"),
Self::AllGraphs => write!(f, "all"),

@ -4,6 +4,7 @@ use crate::term::*;
use crate::update::*;
use oxilangtag::LanguageTag;
use oxiri::{Iri, IriParseError};
use oxrdf::vocab::{rdf, xsd};
use peg::parser;
use peg::str::LineCol;
use rand::random;
@ -200,7 +201,7 @@ fn add_to_triple_or_path_patterns(
if !object.annotations.is_empty() {
return Err("Annotations are not allowed on property paths");
}
let middle = bnode();
let middle = BlankNode::default();
add_to_triple_or_path_patterns(
subject,
*a,
@ -618,17 +619,17 @@ fn are_variables_bound(expression: &Expression, variables: &HashSet<Variable>) -
fn copy_graph(from: impl Into<GraphName>, to: impl Into<GraphNamePattern>) -> GraphUpdateOperation {
let bgp = GraphPattern::Bgp {
patterns: vec![TriplePattern::new(
Variable { name: "s".into() },
Variable { name: "p".into() },
Variable { name: "o".into() },
Variable::new_unchecked("s"),
Variable::new_unchecked("p"),
Variable::new_unchecked("o"),
)],
};
GraphUpdateOperation::DeleteInsert {
delete: Vec::new(),
insert: vec![QuadPattern::new(
Variable { name: "s".into() },
Variable { name: "p".into() },
Variable { name: "o".into() },
Variable::new_unchecked("s"),
Variable::new_unchecked("p"),
Variable::new_unchecked("o"),
to,
)],
using: None,
@ -882,20 +883,8 @@ pub fn unescape_pn_local(input: &str) -> Cow<'_, str> {
unescape_characters(input, &UNESCAPE_PN_CHARACTERS, &UNESCAPE_PN_REPLACEMENT)
}
fn iri(value: impl Into<String>) -> NamedNode {
NamedNode { iri: value.into() }
}
fn bnode() -> BlankNode {
BlankNode {
id: format!("{:x}", random::<u128>()),
}
}
fn variable() -> Variable {
Variable {
name: format!("{:x}", random::<u128>()),
}
Variable::new_unchecked(format!("{:x}", random::<u128>()))
}
parser! {
@ -1155,7 +1144,7 @@ parser! {
if from == to {
Vec::new() // identity case
} else {
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable { name: "s".into() }, Variable { name: "p".into() }, Variable { name: "o".into() })] };
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
vec![copy_graph(from, to)]
}
}
@ -1166,7 +1155,7 @@ parser! {
if from == to {
Vec::new() // identity case
} else {
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable { name: "s".into() }, Variable { name: "p".into() }, Variable { name: "o".into() })] };
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from.clone(), to), GraphUpdateOperation::Drop { silent, graph: from.into() }]
}
}
@ -1177,7 +1166,7 @@ parser! {
if from == to {
Vec::new() // identity case
} else {
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable { name: "s".into() }, Variable { name: "p".into() }, Variable{ name: "o".into() })] };
let bgp = GraphPattern::Bgp { patterns: vec![TriplePattern::new(Variable::new_unchecked("s"), Variable::new_unchecked("p"), Variable::new_unchecked("o"))] };
vec![GraphUpdateOperation::Drop { silent: true, graph: to.clone().into() }, copy_graph(from, to)]
}
}
@ -1557,7 +1546,7 @@ parser! {
}
//[78]
rule Verb() -> NamedNodePattern = VarOrIri() / "a" { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").into() }
rule Verb() -> NamedNodePattern = VarOrIri() / "a" { rdf::TYPE.into_owned().into() }
//[79]
rule ObjectList() -> FocusedTriplePattern<Vec<AnnotatedTerm>> = o:ObjectList_item() **<1,> ("," _) {
@ -1717,7 +1706,7 @@ parser! {
//[94]
rule PathPrimary() -> PropertyPathExpression =
v:iri() { v.into() } /
"a" { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type").into() } /
"a" { rdf::TYPE.into_owned().into() } /
"!" _ p:PathNegatedPropertySet() { p } /
"(" _ p:Path() _ ")" { p }
@ -1754,9 +1743,9 @@ parser! {
//[96]
rule PathOneInPropertySet() -> Either<NamedNode,NamedNode> =
"^" _ v:iri() { Either::Right(v) } /
"^" _ "a" { Either::Right(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) } /
"^" _ "a" { Either::Right(rdf::TYPE.into()) } /
v:iri() { Either::Left(v) } /
"a" { Either::Left(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) }
"a" { Either::Left(rdf::TYPE.into()) }
//[98]
rule TriplesNode() -> FocusedTriplePattern<TermPattern> = Collection() / BlankNodePropertyList()
@ -1764,7 +1753,7 @@ parser! {
//[99]
rule BlankNodePropertyList() -> FocusedTriplePattern<TermPattern> = "[" _ po:PropertyListNotEmpty() _ "]" {?
let mut patterns = po.patterns;
let mut bnode = TermPattern::from(bnode());
let mut bnode = TermPattern::from(BlankNode::default());
for (p, os) in po.focus {
for o in os {
add_to_triple_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
@ -1782,7 +1771,7 @@ parser! {
//[101]
rule BlankNodePropertyListPath() -> FocusedTripleOrPathPattern<TermPattern> = "[" _ po:PropertyListPathNotEmpty() _ "]" {?
let mut patterns: Vec<TripleOrPathPattern> = Vec::new();
let mut bnode = TermPattern::from(bnode());
let mut bnode = TermPattern::from(BlankNode::default());
for (p, os) in po.focus {
for o in os {
add_to_triple_or_path_patterns(bnode.clone(), p.clone(), o, &mut patterns)?;
@ -1797,11 +1786,11 @@ parser! {
//[102]
rule Collection() -> FocusedTriplePattern<TermPattern> = "(" _ o:Collection_item()+ ")" {
let mut patterns: Vec<TriplePattern> = Vec::new();
let mut current_list_node = TermPattern::from(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"));
let mut current_list_node = TermPattern::from(rdf::NIL.into_owned());
for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermPattern::from(bnode());
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first"), objWithPatterns.focus.clone()));
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"), current_list_node));
let new_blank_node = TermPattern::from(BlankNode::default());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.into_owned(), objWithPatterns.focus.clone()));
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.into_owned(), current_list_node));
current_list_node = new_blank_node;
patterns.extend_from_slice(&objWithPatterns.patterns);
}
@ -1815,11 +1804,11 @@ parser! {
//[103]
rule CollectionPath() -> FocusedTripleOrPathPattern<TermPattern> = "(" _ o:CollectionPath_item()+ _ ")" {
let mut patterns: Vec<TripleOrPathPattern> = Vec::new();
let mut current_list_node = TermPattern::from(iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"));
let mut current_list_node = TermPattern::from(rdf::NIL.into_owned());
for objWithPatterns in o.into_iter().rev() {
let new_blank_node = TermPattern::from(bnode());
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#first"), objWithPatterns.focus.clone()).into());
patterns.push(TriplePattern::new(new_blank_node.clone(), iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest"), current_list_node).into());
let new_blank_node = TermPattern::from(BlankNode::default());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::FIRST.into_owned(), objWithPatterns.focus.clone()).into());
patterns.push(TriplePattern::new(new_blank_node.clone(), rdf::REST.into_owned(), current_list_node).into());
current_list_node = new_blank_node;
patterns.extend(objWithPatterns.patterns);
}
@ -1851,7 +1840,7 @@ parser! {
i:iri() { i.into() }
//[108]
rule Var() -> Variable = name:(VAR1() / VAR2()) { Variable { name: name.into() } }
rule Var() -> Variable = name:(VAR1() / VAR2()) { Variable::new_unchecked(name) }
//[109]
rule GraphTerm() -> Term =
@ -1860,7 +1849,7 @@ parser! {
l:NumericLiteral() { l.into() } /
l:BooleanLiteral() { l.into() } /
b:BlankNode() { b.into() } /
NIL() { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil").into() }
NIL() { rdf::NIL.into_owned().into() }
//[110]
rule Expression() -> Expression = e:ConditionalOrExpression() {e}
@ -2078,43 +2067,43 @@ parser! {
//[129]
rule RDFLiteral() -> Literal =
value:String() _ "^^" _ datatype:iri() { Literal::Typed { value, datatype } } /
value:String() _ language:LANGTAG() { Literal::LanguageTaggedString { value, language: language.into_inner() } } /
value:String() { Literal::Simple { value } }
value:String() _ "^^" _ datatype:iri() { Literal::new_typed_literal(value, datatype) } /
value:String() _ language:LANGTAG() { Literal::new_language_tagged_literal_unchecked(value, language.into_inner()) } /
value:String() { Literal::new_simple_literal(value) }
//[130]
rule NumericLiteral() -> Literal = NumericLiteralUnsigned() / NumericLiteralPositive() / NumericLiteralNegative()
//[131]
rule NumericLiteralUnsigned() -> Literal =
d:$(DOUBLE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#double") } } /
d:$(DECIMAL()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#decimal") } } /
i:$(INTEGER()) { Literal::Typed { value: i.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#integer") } }
d:$(DOUBLE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
d:$(DECIMAL()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[132]
rule NumericLiteralPositive() -> Literal =
d:$(DOUBLE_POSITIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#double") } } /
d:$(DECIMAL_POSITIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#decimal") } } /
i:$(INTEGER_POSITIVE()) { Literal::Typed { value: i.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#integer") } }
d:$(DOUBLE_POSITIVE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
d:$(DECIMAL_POSITIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER_POSITIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[133]
rule NumericLiteralNegative() -> Literal =
d:$(DOUBLE_NEGATIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#double") } } /
d:$(DECIMAL_NEGATIVE()) { Literal::Typed { value: d.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#decimal") } } /
i:$(INTEGER_NEGATIVE()) { Literal::Typed { value: i.into(), datatype: iri("http://www.w3.org/2001/XMLSchema#integer") } }
d:$(DOUBLE_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DOUBLE) } /
d:$(DECIMAL_NEGATIVE()) { Literal::new_typed_literal(d, xsd::DECIMAL) } /
i:$(INTEGER_NEGATIVE()) { Literal::new_typed_literal(i, xsd::INTEGER) }
//[134]
rule BooleanLiteral() -> Literal =
"true" { Literal::Typed { value: "true".into(), datatype: iri("http://www.w3.org/2001/XMLSchema#boolean") } } /
"false" { Literal::Typed { value: "false".into(), datatype: iri("http://www.w3.org/2001/XMLSchema#boolean") } }
"true" { Literal::new_typed_literal("true", xsd::BOOLEAN) } /
"false" { Literal::new_typed_literal("false", xsd::BOOLEAN) }
//[135]
rule String() -> String = STRING_LITERAL_LONG1() / STRING_LITERAL_LONG2() / STRING_LITERAL1() / STRING_LITERAL2()
//[136]
rule iri() -> NamedNode = i:(IRIREF() / PrefixedName()) {
iri(i.into_inner())
NamedNode::new_unchecked(i.into_inner())
}
//[137]
@ -2127,14 +2116,14 @@ parser! {
//[138]
rule BlankNode() -> BlankNode = id:BLANK_NODE_LABEL() {?
let node = BlankNode { id: id.to_owned() };
let node = BlankNode::new_unchecked(id);
if state.used_bnodes.contains(&node) {
Err("Already used blank node id")
} else {
state.currently_used_bnodes.insert(node.clone());
Ok(node)
}
} / ANON() { bnode() }
} / ANON() { BlankNode::default() }
//[139]
rule IRIREF() -> Iri<String> = "<" i:$((!['>'] [_])*) ">" {?
@ -2285,7 +2274,7 @@ parser! {
object: o
})
}
rule EmbTriple_p() -> NamedNode = i: iri() { i } / "a" { iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type") }
rule EmbTriple_p() -> NamedNode = i: iri() { i } / "a" { rdf::TYPE.into() }
//[176]
rule EmbSubjectOrObject() -> TermPattern =

@ -1,243 +1,9 @@
//! Data structures for [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/) like IRI, literal or triples.
pub use oxrdf::{BlankNode, Literal, NamedNode, Subject, Term, Triple, Variable};
use std::fmt;
use std::fmt::Write;
/// An RDF [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
///
/// ```
/// use spargebra::term::NamedNode;
///
/// assert_eq!(
/// "<http://example.com/foo>",
/// NamedNode { iri: "http://example.com/foo".into() }.to_string()
/// )
/// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct NamedNode {
/// The [IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) itself.
pub iri: String,
}
impl NamedNode {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "<{}>", self.iri)
}
}
impl fmt::Display for NamedNode {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<{}>", self.iri)
}
}
impl TryFrom<NamedNodePattern> for NamedNode {
type Error = ();
#[inline]
fn try_from(pattern: NamedNodePattern) -> Result<Self, ()> {
match pattern {
NamedNodePattern::NamedNode(t) => Ok(t),
NamedNodePattern::Variable(_) => Err(()),
}
}
}
/// An RDF [blank node](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
///
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
///
/// ```
/// use spargebra::term::BlankNode;
///
/// assert_eq!(
/// "_:a1",
/// BlankNode { id: "a1".into() }.to_string()
/// )
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct BlankNode {
/// The [blank node identifier](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node-identifier).
pub id: String,
}
impl BlankNode {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "_:{}", self.id)
}
}
impl fmt::Display for BlankNode {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "_:{}", self.id)
}
}
/// An RDF [literal](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
///
/// The language tags should be lowercased [as suggested by the RDF specification](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string).
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::Literal;
///
/// assert_eq!(
/// "\"foo\\nbar\"",
/// Literal::Simple { value: "foo\nbar".into() }.to_string()
/// );
///
/// assert_eq!(
/// "\"1999-01-01\"^^<http://www.w3.org/2001/XMLSchema#date>",
/// Literal::Typed { value: "1999-01-01".into(), datatype: NamedNode { iri: "http://www.w3.org/2001/XMLSchema#date".into() }}.to_string()
/// );
///
/// assert_eq!(
/// "\"foo\"@en",
/// Literal::LanguageTaggedString { value: "foo".into(), language: "en".into() }.to_string()
/// );
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Literal {
/// A [simple literal](https://www.w3.org/TR/rdf11-concepts/#dfn-simple-literal) without datatype or language form.
Simple {
/// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
value: String,
},
/// A [language-tagged string](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tagged-string)
LanguageTaggedString {
/// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
value: String,
/// The [language tag](https://www.w3.org/TR/rdf11-concepts/#dfn-language-tag).
language: String,
},
/// A literal with an explicit datatype
Typed {
/// The [lexical form](https://www.w3.org/TR/rdf11-concepts/#dfn-lexical-form).
value: String,
/// The [datatype IRI](https://www.w3.org/TR/rdf11-concepts/#dfn-datatype-iri).
datatype: NamedNode,
},
}
impl Literal {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Literal::Simple { value } => print_quoted_str(value, f),
Literal::LanguageTaggedString { value, language } => {
print_quoted_str(value, f)?;
write!(f, "@{}", language)
}
Literal::Typed { value, datatype } => {
print_quoted_str(value, f)?;
write!(f, "^^{}", datatype)
}
}
}
}
impl fmt::Display for Literal {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Literal::Simple { value } => print_quoted_str(value, f),
Literal::LanguageTaggedString { value, language } => {
print_quoted_str(value, f)?;
write!(f, "@{}", language)
}
Literal::Typed { value, datatype } => {
print_quoted_str(value, f)?;
write!(f, "^^{}", datatype)
}
}
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Subject {
NamedNode(NamedNode),
BlankNode(BlankNode),
#[cfg(feature = "rdf-star")]
Triple(Box<Triple>),
}
impl Subject {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::BlankNode(node) => node.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for Subject {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!(
f,
"<<{} {} {}>>",
triple.subject, triple.predicate, triple.object
),
}
}
}
impl From<NamedNode> for Subject {
#[inline]
fn from(node: NamedNode) -> Self {
Self::NamedNode(node)
}
}
impl From<BlankNode> for Subject {
#[inline]
fn from(node: BlankNode) -> Self {
Self::BlankNode(node)
}
}
#[cfg(feature = "rdf-star")]
impl From<Triple> for Subject {
#[inline]
fn from(triple: Triple) -> Self {
Self::Triple(Box::new(triple))
}
}
impl TryFrom<TermPattern> for Subject {
type Error = ();
#[inline]
fn try_from(term: TermPattern) -> Result<Self, ()> {
match term {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Literal(_) | TermPattern::Variable(_) => Err(()),
}
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
@ -248,17 +14,6 @@ pub enum GroundSubject {
Triple(Box<GroundTriple>),
}
impl GroundSubject {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for GroundSubject {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -317,107 +72,6 @@ impl TryFrom<GroundTerm> for GroundSubject {
}
}
/// An RDF [term](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term).
///
/// It is the union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [blank nodes](https://www.w3.org/TR/rdf11-concepts/#dfn-blank-node) and [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum Term {
NamedNode(NamedNode),
BlankNode(BlankNode),
Literal(Literal),
#[cfg(feature = "rdf-star")]
Triple(Box<Triple>),
}
impl Term {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::BlankNode(node) => node.fmt_sse(f),
Self::Literal(literal) => literal.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for Term {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt(f),
Self::BlankNode(node) => node.fmt(f),
Self::Literal(literal) => literal.fmt(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => write!(
f,
"<<{} {} {}>>",
triple.subject, triple.predicate, triple.object
),
}
}
}
impl From<NamedNode> for Term {
#[inline]
fn from(node: NamedNode) -> Self {
Self::NamedNode(node)
}
}
impl From<BlankNode> for Term {
#[inline]
fn from(node: BlankNode) -> Self {
Self::BlankNode(node)
}
}
impl From<Literal> for Term {
#[inline]
fn from(literal: Literal) -> Self {
Self::Literal(literal)
}
}
#[cfg(feature = "rdf-star")]
impl From<Triple> for Term {
#[inline]
fn from(triple: Triple) -> Self {
Self::Triple(Box::new(triple))
}
}
impl From<Subject> for Term {
#[inline]
fn from(resource: Subject) -> Self {
match resource {
Subject::NamedNode(node) => node.into(),
Subject::BlankNode(node) => node.into(),
#[cfg(feature = "rdf-star")]
Subject::Triple(t) => (*t).into(),
}
}
}
impl TryFrom<TermPattern> for Term {
type Error = ();
#[inline]
fn try_from(pattern: TermPattern) -> Result<Self, ()> {
match pattern {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
TermPattern::Literal(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Variable(_) => Err(()),
}
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri), [literals](https://www.w3.org/TR/rdf11-concepts/#dfn-literal) and [triples](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning an N-Triples, Turtle and SPARQL compatible representation.
@ -429,18 +83,6 @@ pub enum GroundTerm {
Triple(Box<GroundTriple>),
}
impl GroundTerm {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::Literal(literal) => literal.fmt_sse(f),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
}
}
}
impl fmt::Display for GroundTerm {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -494,79 +136,22 @@ impl TryFrom<Term> for GroundTerm {
}
}
/// A [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple).
///
/// The default string formatter is returning a N-Quads representation.
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::Triple;
///
/// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo>",
/// Triple {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() },
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// }.to_string()
/// )
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Triple {
pub subject: Subject,
pub predicate: NamedNode,
pub object: Term,
}
impl Triple {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
}
}
impl fmt::Display for Triple {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {} {}", self.subject, self.predicate, self.object)
}
}
impl TryFrom<TriplePattern> for Triple {
type Error = ();
#[inline]
fn try_from(triple: TriplePattern) -> Result<Self, ()> {
Ok(Self {
subject: triple.subject.try_into()?,
predicate: triple.predicate.try_into()?,
object: triple.object.try_into()?,
})
}
}
/// A [RDF triple](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-triple) without blank nodes.
///
/// The default string formatter is returning a N-Quads representation.
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::GroundTriple;
/// use spargebra::term::{NamedNode, GroundTriple};
///
/// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo>",
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o>",
/// GroundTriple {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() },
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// }.to_string()
/// )
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundTriple {
@ -575,19 +160,6 @@ pub struct GroundTriple {
pub object: GroundTerm,
}
impl GroundTriple {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")
}
}
impl fmt::Display for GroundTriple {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@ -621,7 +193,7 @@ impl GraphName {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::NamedNode(node) => write!(f, "{}", node),
Self::DefaultGraph => write!(f, "default"),
}
}
@ -662,18 +234,18 @@ impl TryFrom<GraphNamePattern> for GraphName {
/// The default string formatter is returning a N-Quads representation.
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::Quad;
/// use spargebra::term::{NamedNode, Quad};
///
/// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo> <http://example.com/>",
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// Quad {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() },
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// graph_name: NamedNode { iri: "http://example.com/".into() }.into(),
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// graph_name: NamedNode::new("http://example.com/g")?.into(),
/// }.to_string()
/// )
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct Quad {
@ -691,13 +263,11 @@ impl Quad {
self.graph_name.fmt_sse(f)?;
write!(f, " (")?;
}
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")?;
write!(
f,
"(triple {} {} {})",
self.subject, self.predicate, self.object
)?;
if self.graph_name != GraphName::DefaultGraph {
write!(f, "))")?;
}
@ -739,18 +309,18 @@ impl TryFrom<QuadPattern> for Quad {
/// The default string formatter is returning a N-Quads representation.
///
/// ```
/// use spargebra::term::NamedNode;
/// use spargebra::term::GroundQuad;
/// use spargebra::term::{NamedNode, GroundQuad};
///
/// assert_eq!(
/// "<http://example.com/foo> <http://schema.org/sameAs> <http://example.com/foo> <http://example.com/>",
/// "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g>",
/// GroundQuad {
/// subject: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// predicate: NamedNode { iri: "http://schema.org/sameAs".into() },
/// object: NamedNode { iri: "http://example.com/foo".into() }.into(),
/// graph_name: NamedNode { iri: "http://example.com/".into() }.into(),
/// subject: NamedNode::new("http://example.com/s")?.into(),
/// predicate: NamedNode::new("http://example.com/p")?,
/// object: NamedNode::new("http://example.com/o")?.into(),
/// graph_name: NamedNode::new("http://example.com/g")?.into(),
/// }.to_string()
/// )
/// );
/// # Result::<_,oxrdf::IriParseError>::Ok(())
/// ```
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundQuad {
@ -768,13 +338,11 @@ impl GroundQuad {
self.graph_name.fmt_sse(f)?;
write!(f, " (")?;
}
write!(f, "(triple ")?;
self.subject.fmt_sse(f)?;
write!(f, " ")?;
self.predicate.fmt_sse(f)?;
write!(f, " ")?;
self.object.fmt_sse(f)?;
write!(f, ")")?;
write!(
f,
"(triple {} {} {})",
self.subject, self.predicate, self.object
)?;
if self.graph_name != GraphName::DefaultGraph {
write!(f, "))")?;
}
@ -811,35 +379,6 @@ impl TryFrom<Quad> for GroundQuad {
}
}
/// A [SPARQL query variable](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
///
/// ```
/// use spargebra::term::Variable;
///
/// assert_eq!(
/// "?foo",
/// Variable { name: "foo".into() }.to_string()
/// );
/// ```
#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Hash)]
pub struct Variable {
pub name: String,
}
impl Variable {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
write!(f, "?{}", self.name)
}
}
impl fmt::Display for Variable {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "?{}", self.name)
}
}
/// The union of [IRIs](https://www.w3.org/TR/rdf11-concepts/#dfn-iri) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum NamedNodePattern {
@ -851,8 +390,8 @@ impl NamedNodePattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::Variable(var) => var.fmt_sse(f),
Self::NamedNode(node) => write!(f, "{}", node),
Self::Variable(var) => write!(f, "{}", var),
}
}
}
@ -881,6 +420,18 @@ impl From<Variable> for NamedNodePattern {
}
}
impl TryFrom<NamedNodePattern> for NamedNode {
type Error = ();
#[inline]
fn try_from(pattern: NamedNodePattern) -> Result<Self, ()> {
match pattern {
NamedNodePattern::NamedNode(t) => Ok(t),
NamedNodePattern::Variable(_) => Err(()),
}
}
}
/// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables).
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum TermPattern {
@ -896,12 +447,12 @@ impl TermPattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(term) => term.fmt_sse(f),
Self::BlankNode(term) => term.fmt_sse(f),
Self::Literal(term) => term.fmt_sse(f),
Self::NamedNode(term) => write!(f, "{}", term),
Self::BlankNode(term) => write!(f, "{}", term),
Self::Literal(term) => write!(f, "{}", term),
#[cfg(feature = "rdf-star")]
Self::Triple(triple) => triple.fmt_sse(f),
Self::Variable(var) => var.fmt_sse(f),
Self::Variable(var) => write!(f, "{}", var),
}
}
}
@ -990,6 +541,36 @@ impl From<NamedNodePattern> for TermPattern {
}
}
impl TryFrom<TermPattern> for Subject {
type Error = ();
#[inline]
fn try_from(term: TermPattern) -> Result<Self, ()> {
match term {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Literal(_) | TermPattern::Variable(_) => Err(()),
}
}
}
impl TryFrom<TermPattern> for Term {
type Error = ();
#[inline]
fn try_from(pattern: TermPattern) -> Result<Self, ()> {
match pattern {
TermPattern::NamedNode(t) => Ok(t.into()),
TermPattern::BlankNode(t) => Ok(t.into()),
TermPattern::Literal(t) => Ok(t.into()),
#[cfg(feature = "rdf-star")]
TermPattern::Triple(t) => Ok(Triple::try_from(*t)?.into()),
TermPattern::Variable(_) => Err(()),
}
}
}
/// The union of [terms](https://www.w3.org/TR/rdf11-concepts/#dfn-rdf-term) and [variables](https://www.w3.org/TR/sparql11-query/#sparqlQueryVariables) without blank nodes.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub enum GroundTermPattern {
@ -1003,9 +584,9 @@ impl GroundTermPattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(term) => term.fmt_sse(f),
Self::Literal(term) => term.fmt_sse(f),
Self::Variable(var) => var.fmt_sse(f),
Self::NamedNode(term) => write!(f, "{}", term),
Self::Literal(term) => write!(f, "{}", term),
Self::Variable(var) => write!(f, "{}", var),
Self::Triple(triple) => triple.fmt_sse(f),
}
}
@ -1111,9 +692,9 @@ impl GraphNamePattern {
/// Formats using the [SPARQL S-Expression syntax](https://jena.apache.org/documentation/notes/sse.html).
pub(crate) fn fmt_sse(&self, f: &mut impl Write) -> fmt::Result {
match self {
Self::NamedNode(node) => node.fmt_sse(f),
Self::NamedNode(node) => write!(f, "{}", node),
Self::DefaultGraph => write!(f, "default"),
Self::Variable(var) => var.fmt_sse(f),
Self::Variable(var) => write!(f, "{}", var),
}
}
}
@ -1216,7 +797,20 @@ impl From<Triple> for TriplePattern {
}
}
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) without blank nodes
impl TryFrom<TriplePattern> for Triple {
type Error = ();
#[inline]
fn try_from(triple: TriplePattern) -> Result<Self, ()> {
Ok(Self {
subject: triple.subject.try_into()?,
predicate: triple.predicate.try_into()?,
object: triple.object.try_into()?,
})
}
}
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) without blank nodes.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundTriplePattern {
pub subject: GroundTermPattern,
@ -1330,7 +924,7 @@ impl fmt::Display for QuadPattern {
}
}
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph without blank nodes
/// A [triple pattern](https://www.w3.org/TR/sparql11-query/#defn_TriplePattern) in a specific graph without blank nodes.
#[derive(Eq, PartialEq, Debug, Clone, Hash)]
pub struct GroundQuadPattern {
pub subject: GroundTermPattern,
@ -1389,18 +983,3 @@ impl TryFrom<QuadPattern> for GroundQuadPattern {
})
}
}
#[inline]
pub(crate) fn print_quoted_str(string: &str, f: &mut impl Write) -> fmt::Result {
f.write_char('"')?;
for c in string.chars() {
match c {
'\n' => f.write_str("\\n"),
'\r' => f.write_str("\\r"),
'"' => f.write_str("\\\""),
'\\' => f.write_str("\\\\"),
c => f.write_char(c),
}?;
}
f.write_char('"')
}

@ -191,8 +191,7 @@ impl GraphUpdateOperation {
if *silent {
write!(f, "silent ")?;
}
source.fmt_sse(f)?;
write!(f, " ")?;
write!(f, "{} ", source)?;
destination.fmt_sse(f)?;
write!(f, ")")
}
@ -209,8 +208,7 @@ impl GraphUpdateOperation {
if *silent {
write!(f, "silent ")?;
}
graph.fmt_sse(f)?;
write!(f, ")")
write!(f, "{})", graph)
}
GraphUpdateOperation::Drop { silent, graph } => {
write!(f, "(drop ")?;

@ -188,19 +188,11 @@ impl QueryDataset {
fn from_algebra(inner: &Option<spargebra::algebra::QueryDataset>) -> Self {
if let Some(inner) = inner {
Self {
default: Some(
inner
.default
.iter()
.map(|g| NamedNode::new_unchecked(&g.iri).into())
.collect(),
),
named: inner.named.as_ref().map(|named| {
named
.iter()
.map(|g| NamedNode::new_unchecked(&g.iri).into())
.collect()
}),
default: Some(inner.default.iter().map(|g| g.clone().into()).collect()),
named: inner
.named
.as_ref()
.map(|named| named.iter().map(|g| g.clone().into()).collect()),
}
} else {
Self {

@ -52,15 +52,7 @@ pub(crate) fn evaluate_query(
options.service_handler(),
Rc::new(options.custom_functions),
)
.evaluate_select_plan(
&plan,
Rc::new(
variables
.into_iter()
.map(|v| Variable::new_unchecked(v.name))
.collect(),
),
))
.evaluate_select_plan(&plan, Rc::new(variables)))
}
spargebra::Query::Ask {
pattern, base_iri, ..

@ -1,9 +1,10 @@
use crate::model::{LiteralRef, NamedNode as OxNamedNode, NamedNodeRef, Term as OxTerm};
use crate::model::Term as OxTerm;
use crate::sparql::dataset::DatasetView;
use crate::sparql::error::EvaluationError;
use crate::sparql::plan::*;
use crate::storage::numeric_encoder::{EncodedTerm, EncodedTriple};
use oxrdf::Variable as OxVariable;
use oxrdf::vocab::xsd;
use oxrdf::TermRef;
use rand::random;
use spargebra::algebra::*;
use spargebra::term::*;
@ -13,7 +14,7 @@ use std::rc::Rc;
pub struct PlanBuilder<'a> {
dataset: &'a DatasetView,
custom_functions: &'a HashMap<OxNamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
custom_functions: &'a HashMap<NamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
}
impl<'a> PlanBuilder<'a> {
@ -21,7 +22,7 @@ impl<'a> PlanBuilder<'a> {
dataset: &'a DatasetView,
pattern: &GraphPattern,
is_cardinality_meaningful: bool,
custom_functions: &'a HashMap<OxNamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
custom_functions: &'a HashMap<NamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
) -> Result<(PlanNode, Vec<Variable>), EvaluationError> {
let mut variables = Vec::default();
let plan = PlanBuilder {
@ -49,7 +50,7 @@ impl<'a> PlanBuilder<'a> {
dataset: &'a DatasetView,
template: &[TriplePattern],
mut variables: Vec<Variable>,
custom_functions: &'a HashMap<OxNamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
custom_functions: &'a HashMap<NamedNode, Rc<dyn Fn(&[OxTerm]) -> Option<OxTerm>>>,
) -> Vec<TripleTemplate> {
PlanBuilder {
dataset,
@ -168,12 +169,7 @@ impl<'a> PlanBuilder<'a> {
let service_name = self.pattern_value_from_named_node_or_variable(name, variables);
PlanNode::Service {
service_name,
variables: Rc::new(
variables
.iter()
.map(|v| OxVariable::new_unchecked(v.name.clone()))
.collect(),
),
variables: Rc::new(variables.clone()),
child: Box::new(child),
graph_pattern: Rc::new(inner.as_ref().clone()),
silent: *silent,
@ -295,9 +291,7 @@ impl<'a> PlanBuilder<'a> {
fn build_for_path(&mut self, path: &PropertyPathExpression) -> PlanPropertyPath {
match path {
PropertyPathExpression::NamedNode(p) => {
PlanPropertyPath::Path(self.build_named_node(p))
}
PropertyPathExpression::NamedNode(p) => PlanPropertyPath::Path(self.build_term(p)),
PropertyPathExpression::Reverse(p) => {
PlanPropertyPath::Reverse(Rc::new(self.build_for_path(p)))
}
@ -319,7 +313,7 @@ impl<'a> PlanBuilder<'a> {
PlanPropertyPath::ZeroOrOne(Rc::new(self.build_for_path(p)))
}
PropertyPathExpression::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet(
Rc::new(p.iter().map(|p| self.build_named_node(p)).collect()),
Rc::new(p.iter().map(|p| self.build_term(p)).collect()),
),
}
}
@ -331,8 +325,8 @@ impl<'a> PlanBuilder<'a> {
graph_name: &PatternValue,
) -> Result<PlanExpression, EvaluationError> {
Ok(match expression {
Expression::NamedNode(node) => PlanExpression::Constant(self.build_named_node(node)),
Expression::Literal(l) => PlanExpression::Constant(self.build_literal(l)),
Expression::NamedNode(node) => PlanExpression::Constant(self.build_term(node)),
Expression::Literal(l) => PlanExpression::Constant(self.build_term(l)),
Expression::Variable(v) => PlanExpression::Variable(variable_key(variables, v)),
Expression::Or(a, b) => PlanExpression::Or(
Box::new(self.build_for_expression(a, variables, graph_name)?),
@ -639,16 +633,15 @@ impl<'a> PlanBuilder<'a> {
self.build_for_expression(&parameters[0], variables, graph_name)?,
)),
Function::Custom(name) => {
let ox_name = OxNamedNode::new(&name.iri).map_err(EvaluationError::wrap)?;
if self.custom_functions.contains_key(&ox_name) {
if self.custom_functions.contains_key(name) {
PlanExpression::CustomFunction(
ox_name,
name.clone(),
parameters
.iter()
.map(|p| self.build_for_expression(p, variables, graph_name))
.collect::<Result<Vec<_>, EvaluationError>>()?,
)
} else if name.iri == "http://www.w3.org/2001/XMLSchema#boolean" {
} else if name.as_ref() == xsd::BOOLEAN {
self.build_cast(
parameters,
PlanExpression::BooleanCast,
@ -656,7 +649,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"boolean",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#double" {
} else if name.as_ref() == xsd::DOUBLE {
self.build_cast(
parameters,
PlanExpression::DoubleCast,
@ -664,7 +657,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"double",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#float" {
} else if name.as_ref() == xsd::FLOAT {
self.build_cast(
parameters,
PlanExpression::FloatCast,
@ -672,7 +665,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"float",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#decimal" {
} else if name.as_ref() == xsd::DECIMAL {
self.build_cast(
parameters,
PlanExpression::DecimalCast,
@ -680,7 +673,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"decimal",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#integer" {
} else if name.as_ref() == xsd::INTEGER {
self.build_cast(
parameters,
PlanExpression::IntegerCast,
@ -688,7 +681,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"integer",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#date" {
} else if name.as_ref() == xsd::DATE {
self.build_cast(
parameters,
PlanExpression::DateCast,
@ -696,7 +689,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"date",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#time" {
} else if name.as_ref() == xsd::TIME {
self.build_cast(
parameters,
PlanExpression::TimeCast,
@ -704,7 +697,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"time",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#dateTime" {
} else if name.as_ref() == xsd::DATE_TIME {
self.build_cast(
parameters,
PlanExpression::DateTimeCast,
@ -712,7 +705,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"dateTime",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#duration" {
} else if name.as_ref() == xsd::DURATION {
self.build_cast(
parameters,
PlanExpression::DurationCast,
@ -720,7 +713,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"duration",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#yearMonthDuration" {
} else if name.as_ref() == xsd::YEAR_MONTH_DURATION {
self.build_cast(
parameters,
PlanExpression::YearMonthDurationCast,
@ -728,7 +721,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"yearMonthDuration",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#dayTimeDuration" {
} else if name.as_ref() == xsd::DAY_TIME_DURATION {
self.build_cast(
parameters,
PlanExpression::DayTimeDurationCast,
@ -736,7 +729,7 @@ impl<'a> PlanBuilder<'a> {
graph_name,
"dayTimeDuration",
)?
} else if name.iri == "http://www.w3.org/2001/XMLSchema#string" {
} else if name.as_ref() == xsd::STRING {
self.build_cast(
parameters,
PlanExpression::StringCast,
@ -814,17 +807,15 @@ impl<'a> PlanBuilder<'a> {
TermPattern::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable))
}
TermPattern::NamedNode(node) => PatternValue::Constant(self.build_named_node(node)),
TermPattern::NamedNode(node) => PatternValue::Constant(self.build_term(node)),
TermPattern::BlankNode(bnode) => {
PatternValue::Variable(variable_key(
variables,
&Variable {
name: bnode.id.clone(),
},
&Variable::new_unchecked(bnode.as_str()),
))
//TODO: very bad hack to convert bnode to variable
}
TermPattern::Literal(literal) => PatternValue::Constant(self.build_literal(literal)),
TermPattern::Literal(literal) => PatternValue::Constant(self.build_term(literal)),
TermPattern::Triple(triple) => {
match (
self.pattern_value_from_term_or_variable(&triple.subject, variables),
@ -862,7 +853,7 @@ impl<'a> PlanBuilder<'a> {
) -> PatternValue {
match named_node_or_variable {
NamedNodePattern::NamedNode(named_node) => {
PatternValue::Constant(self.build_named_node(named_node))
PatternValue::Constant(self.build_term(named_node))
}
NamedNodePattern::Variable(variable) => {
PatternValue::Variable(variable_key(variables, variable))
@ -888,8 +879,8 @@ impl<'a> PlanBuilder<'a> {
result.set(
bindings_variables_keys[key],
match term {
GroundTerm::NamedNode(node) => self.build_named_node(node),
GroundTerm::Literal(literal) => self.build_literal(literal),
GroundTerm::NamedNode(node) => self.build_term(node),
GroundTerm::Literal(literal) => self.build_term(literal),
GroundTerm::Triple(triple) => self.build_triple(triple),
},
);
@ -992,14 +983,12 @@ impl<'a> PlanBuilder<'a> {
TermPattern::Variable(variable) => {
TripleTemplateValue::Variable(variable_key(variables, variable))
}
TermPattern::NamedNode(node) => {
TripleTemplateValue::Constant(self.build_named_node(node))
}
TermPattern::NamedNode(node) => TripleTemplateValue::Constant(self.build_term(node)),
TermPattern::BlankNode(bnode) => {
TripleTemplateValue::BlankNode(bnode_key(bnodes, bnode))
}
TermPattern::Literal(literal) => {
TripleTemplateValue::Constant(self.build_literal(literal))
TripleTemplateValue::Constant(self.build_term(literal))
}
TermPattern::Triple(triple) => match (
self.template_value_from_term_or_variable(&triple.subject, variables, bnodes),
@ -1039,7 +1028,7 @@ impl<'a> PlanBuilder<'a> {
TripleTemplateValue::Variable(variable_key(variables, variable))
}
NamedNodePattern::NamedNode(term) => {
TripleTemplateValue::Constant(self.build_named_node(term))
TripleTemplateValue::Constant(self.build_term(term))
}
}
}
@ -1073,9 +1062,7 @@ impl<'a> PlanBuilder<'a> {
}) {
to_id
} else {
to.push(Variable {
name: format!("{:x}", random::<u128>()),
});
to.push(Variable::new_unchecked(format!("{:x}", random::<u128>())));
to.len() - 1
}
}
@ -1326,34 +1313,20 @@ impl<'a> PlanBuilder<'a> {
}
}
fn build_named_node(&mut self, node: &NamedNode) -> EncodedTerm {
self.dataset
.encode_term(NamedNodeRef::new_unchecked(node.iri.as_str()))
}
fn build_literal(&mut self, literal: &Literal) -> EncodedTerm {
self.dataset.encode_term(match literal {
Literal::Simple { value } => LiteralRef::new_simple_literal(value),
Literal::LanguageTaggedString { value, language } => {
LiteralRef::new_language_tagged_literal_unchecked(value, language.as_str())
}
Literal::Typed { value, datatype } => LiteralRef::new_typed_literal(
value,
NamedNodeRef::new_unchecked(datatype.iri.as_str()),
),
})
fn build_term<'b>(&mut self, term: impl Into<TermRef<'b>>) -> EncodedTerm {
self.dataset.encode_term(term)
}
fn build_triple(&mut self, triple: &GroundTriple) -> EncodedTerm {
EncodedTriple::new(
match &triple.subject {
GroundSubject::NamedNode(node) => self.build_named_node(node),
GroundSubject::NamedNode(node) => self.build_term(node),
GroundSubject::Triple(triple) => self.build_triple(triple),
},
self.build_named_node(&triple.predicate),
self.build_term(&triple.predicate),
match &triple.object {
GroundTerm::NamedNode(node) => self.build_named_node(node),
GroundTerm::Literal(literal) => self.build_literal(literal),
GroundTerm::NamedNode(node) => self.build_term(node),
GroundTerm::Literal(literal) => self.build_term(literal),
GroundTerm::Triple(triple) => self.build_triple(triple),
},
)

@ -1,9 +1,6 @@
use crate::io::read::ParserError;
use crate::io::{GraphFormat, GraphParser};
use crate::model::{
BlankNode as OxBlankNode, GraphName as OxGraphName, GraphNameRef, Literal as OxLiteral,
NamedNode as OxNamedNode, NamedNodeRef, Quad as OxQuad, Term as OxTerm, Triple as OxTriple,
};
use crate::model::{GraphName as OxGraphName, GraphNameRef, Quad as OxQuad};
use crate::sparql::algebra::QueryDataset;
use crate::sparql::dataset::DatasetView;
use crate::sparql::eval::SimpleEvaluator;
@ -17,9 +14,8 @@ use oxiri::Iri;
use spargebra::algebra::{GraphPattern, GraphTarget};
use spargebra::term::{
BlankNode, GraphName, GraphNamePattern, GroundQuad, GroundQuadPattern, GroundSubject,
GroundTerm, GroundTermPattern, GroundTriple, GroundTriplePattern, Literal, NamedNode,
NamedNodePattern, Quad, QuadPattern, Subject, Term, TermPattern, Triple, TriplePattern,
Variable,
GroundTerm, GroundTermPattern, GroundTriple, GroundTriplePattern, NamedNode, NamedNodePattern,
Quad, QuadPattern, Subject, Term, TermPattern, Triple, TriplePattern, Variable,
};
use spargebra::GraphUpdateOperation;
use std::collections::HashMap;
@ -159,7 +155,7 @@ impl SimpleUpdateEvaluator<'_> {
fn eval_load(&mut self, from: &NamedNode, to: &GraphName) -> Result<(), EvaluationError> {
let (content_type, body) = self.client.get(
&from.iri,
from.as_str(),
"application/n-triples, text/turtle, application/rdf+xml",
)?;
let format = GraphFormat::from_media_type(&content_type).ok_or_else(|| {
@ -169,7 +165,7 @@ impl SimpleUpdateEvaluator<'_> {
))
})?;
let to_graph_name = match to {
GraphName::NamedNode(graph_name) => NamedNodeRef::new_unchecked(&graph_name.iri).into(),
GraphName::NamedNode(graph_name) => graph_name.into(),
GraphName::DefaultGraph => GraphNameRef::DefaultGraph,
};
let mut parser = GraphParser::from_format(format);
@ -186,7 +182,6 @@ impl SimpleUpdateEvaluator<'_> {
}
fn eval_create(&mut self, graph_name: &NamedNode, silent: bool) -> Result<(), EvaluationError> {
let graph_name = NamedNodeRef::new_unchecked(&graph_name.iri);
if self.transaction.insert_named_graph(graph_name.into())? || silent {
Ok(())
} else {
@ -200,11 +195,10 @@ impl SimpleUpdateEvaluator<'_> {
fn eval_clear(&mut self, graph: &GraphTarget, silent: bool) -> Result<(), EvaluationError> {
match graph {
GraphTarget::NamedNode(graph_name) => {
let graph_name = NamedNodeRef::new_unchecked(&graph_name.iri);
if self
.transaction
.reader()
.contains_named_graph(&graph_name.into())?
.contains_named_graph(&graph_name.as_ref().into())?
{
Ok(self.transaction.clear_graph(graph_name.into())?)
} else if silent {
@ -228,7 +222,6 @@ impl SimpleUpdateEvaluator<'_> {
fn eval_drop(&mut self, graph: &GraphTarget, silent: bool) -> Result<(), EvaluationError> {
match graph {
GraphTarget::NamedNode(graph_name) => {
let graph_name = NamedNodeRef::new_unchecked(&graph_name.iri);
if self.transaction.remove_named_graph(graph_name.into())? || silent {
Ok(())
} else {
@ -246,96 +239,80 @@ impl SimpleUpdateEvaluator<'_> {
}
}
fn convert_quad(quad: &Quad, bnodes: &mut HashMap<BlankNode, OxBlankNode>) -> OxQuad {
fn convert_quad(quad: &Quad, bnodes: &mut HashMap<BlankNode, BlankNode>) -> OxQuad {
OxQuad {
subject: match &quad.subject {
Subject::NamedNode(subject) => Self::convert_named_node(subject).into(),
Subject::NamedNode(subject) => subject.clone().into(),
Subject::BlankNode(subject) => Self::convert_blank_node(subject, bnodes).into(),
Subject::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
},
predicate: Self::convert_named_node(&quad.predicate),
predicate: quad.predicate.clone(),
object: match &quad.object {
Term::NamedNode(object) => Self::convert_named_node(object).into(),
Term::NamedNode(object) => object.clone().into(),
Term::BlankNode(object) => Self::convert_blank_node(object, bnodes).into(),
Term::Literal(object) => Self::convert_literal(object).into(),
Term::Literal(object) => object.clone().into(),
Term::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
},
graph_name: match &quad.graph_name {
GraphName::NamedNode(graph_name) => Self::convert_named_node(graph_name).into(),
GraphName::NamedNode(graph_name) => graph_name.clone().into(),
GraphName::DefaultGraph => OxGraphName::DefaultGraph,
},
}
}
fn convert_triple(triple: &Triple, bnodes: &mut HashMap<BlankNode, OxBlankNode>) -> OxTriple {
OxTriple {
fn convert_triple(triple: &Triple, bnodes: &mut HashMap<BlankNode, BlankNode>) -> Triple {
Triple {
subject: match &triple.subject {
Subject::NamedNode(subject) => Self::convert_named_node(subject).into(),
Subject::NamedNode(subject) => subject.clone().into(),
Subject::BlankNode(subject) => Self::convert_blank_node(subject, bnodes).into(),
Subject::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
},
predicate: Self::convert_named_node(&triple.predicate),
predicate: triple.predicate.clone(),
object: match &triple.object {
Term::NamedNode(object) => Self::convert_named_node(object).into(),
Term::NamedNode(object) => object.clone().into(),
Term::BlankNode(object) => Self::convert_blank_node(object, bnodes).into(),
Term::Literal(object) => Self::convert_literal(object).into(),
Term::Literal(object) => object.clone().into(),
Term::Triple(subject) => Self::convert_triple(subject, bnodes).into(),
},
}
}
fn convert_named_node(node: &NamedNode) -> OxNamedNode {
OxNamedNode::new_unchecked(&node.iri)
}
fn convert_blank_node(
node: &BlankNode,
bnodes: &mut HashMap<BlankNode, OxBlankNode>,
) -> OxBlankNode {
bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> BlankNode {
bnodes.entry(node.clone()).or_default().clone()
}
fn convert_literal(literal: &Literal) -> OxLiteral {
match literal {
Literal::Simple { value } => OxLiteral::new_simple_literal(value),
Literal::LanguageTaggedString { value, language } => {
OxLiteral::new_language_tagged_literal_unchecked(value, language)
}
Literal::Typed { value, datatype } => {
OxLiteral::new_typed_literal(value, NamedNodeRef::new_unchecked(&datatype.iri))
}
}
}
fn convert_ground_quad(quad: &GroundQuad) -> OxQuad {
OxQuad {
subject: match &quad.subject {
GroundSubject::NamedNode(subject) => Self::convert_named_node(subject).into(),
GroundSubject::NamedNode(subject) => subject.clone().into(),
GroundSubject::Triple(subject) => Self::convert_ground_triple(subject).into(),
},
predicate: Self::convert_named_node(&quad.predicate),
predicate: quad.predicate.clone(),
object: match &quad.object {
GroundTerm::NamedNode(object) => Self::convert_named_node(object).into(),
GroundTerm::Literal(object) => Self::convert_literal(object).into(),
GroundTerm::NamedNode(object) => object.clone().into(),
GroundTerm::Literal(object) => object.clone().into(),
GroundTerm::Triple(subject) => Self::convert_ground_triple(subject).into(),
},
graph_name: match &quad.graph_name {
GraphName::NamedNode(graph_name) => Self::convert_named_node(graph_name).into(),
GraphName::NamedNode(graph_name) => graph_name.clone().into(),
GraphName::DefaultGraph => OxGraphName::DefaultGraph,
},
}
}
fn convert_ground_triple(triple: &GroundTriple) -> OxTriple {
OxTriple {
fn convert_ground_triple(triple: &GroundTriple) -> Triple {
Triple {
subject: match &triple.subject {
GroundSubject::NamedNode(subject) => Self::convert_named_node(subject).into(),
GroundSubject::NamedNode(subject) => subject.clone().into(),
GroundSubject::Triple(subject) => Self::convert_ground_triple(subject).into(),
},
predicate: Self::convert_named_node(&triple.predicate),
predicate: triple.predicate.clone(),
object: match &triple.object {
GroundTerm::NamedNode(object) => Self::convert_named_node(object).into(),
GroundTerm::Literal(object) => Self::convert_literal(object).into(),
GroundTerm::NamedNode(object) => object.clone().into(),
GroundTerm::Literal(object) => object.clone().into(),
GroundTerm::Triple(subject) => Self::convert_ground_triple(subject).into(),
},
}
@ -346,7 +323,7 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable],
values: &EncodedTuple,
dataset: &DatasetView,
bnodes: &mut HashMap<BlankNode, OxBlankNode>,
bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<OxQuad>, EvaluationError> {
Ok(Some(OxQuad {
subject: match Self::convert_term_or_var(
@ -356,10 +333,10 @@ impl SimpleUpdateEvaluator<'_> {
dataset,
bnodes,
)? {
Some(OxTerm::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None),
Some(Term::NamedNode(node)) => node.into(),
Some(Term::BlankNode(node)) => node.into(),
Some(Term::Triple(triple)) => triple.into(),
Some(Term::Literal(_)) | None => return Ok(None),
},
predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&quad.predicate, variables, values, dataset)?
@ -390,12 +367,12 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable],
values: &EncodedTuple,
dataset: &DatasetView,
bnodes: &mut HashMap<BlankNode, OxBlankNode>,
) -> Result<Option<OxTerm>, EvaluationError> {
bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<Term>, EvaluationError> {
Ok(match term {
TermPattern::NamedNode(term) => Some(Self::convert_named_node(term).into()),
TermPattern::NamedNode(term) => Some(term.clone().into()),
TermPattern::BlankNode(bnode) => Some(Self::convert_blank_node(bnode, bnodes).into()),
TermPattern::Literal(term) => Some(Self::convert_literal(term).into()),
TermPattern::Literal(term) => Some(term.clone().into()),
TermPattern::Triple(triple) => {
Self::convert_triple_pattern(triple, variables, values, dataset, bnodes)?
.map(|t| t.into())
@ -411,9 +388,9 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable],
values: &EncodedTuple,
dataset: &DatasetView,
) -> Result<Option<OxNamedNode>, EvaluationError> {
) -> Result<Option<NamedNode>, EvaluationError> {
Ok(match term {
NamedNodePattern::NamedNode(term) => Some(Self::convert_named_node(term)),
NamedNodePattern::NamedNode(term) => Some(term.clone()),
NamedNodePattern::Variable(v) => Self::lookup_variable(v, variables, values)
.map(|node| dataset.decode_named_node(&node))
.transpose()?,
@ -427,7 +404,7 @@ impl SimpleUpdateEvaluator<'_> {
dataset: &DatasetView,
) -> Result<Option<OxGraphName>, EvaluationError> {
match term {
GraphNamePattern::NamedNode(term) => Ok(Some(Self::convert_named_node(term).into())),
GraphNamePattern::NamedNode(term) => Ok(Some(term.clone().into())),
GraphNamePattern::DefaultGraph => Ok(Some(OxGraphName::DefaultGraph)),
GraphNamePattern::Variable(v) => Self::lookup_variable(v, variables, values)
.map(|node| {
@ -446,9 +423,9 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable],
values: &EncodedTuple,
dataset: &DatasetView,
bnodes: &mut HashMap<BlankNode, OxBlankNode>,
) -> Result<Option<OxTriple>, EvaluationError> {
Ok(Some(OxTriple {
bnodes: &mut HashMap<BlankNode, BlankNode>,
) -> Result<Option<Triple>, EvaluationError> {
Ok(Some(Triple {
subject: match Self::convert_term_or_var(
&triple.subject,
variables,
@ -456,10 +433,10 @@ impl SimpleUpdateEvaluator<'_> {
dataset,
bnodes,
)? {
Some(OxTerm::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None),
Some(Term::NamedNode(node)) => node.into(),
Some(Term::BlankNode(node)) => node.into(),
Some(Term::Triple(triple)) => triple.into(),
Some(Term::Literal(_)) | None => return Ok(None),
},
predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&triple.predicate, variables, values, dataset)?
@ -491,10 +468,10 @@ impl SimpleUpdateEvaluator<'_> {
values,
dataset,
)? {
Some(OxTerm::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None),
Some(Term::NamedNode(node)) => node.into(),
Some(Term::BlankNode(node)) => node.into(),
Some(Term::Triple(triple)) => triple.into(),
Some(Term::Literal(_)) | None => return Ok(None),
},
predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&quad.predicate, variables, values, dataset)?
@ -525,10 +502,10 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable],
values: &EncodedTuple,
dataset: &DatasetView,
) -> Result<Option<OxTerm>, EvaluationError> {
) -> Result<Option<Term>, EvaluationError> {
Ok(match term {
GroundTermPattern::NamedNode(term) => Some(Self::convert_named_node(term).into()),
GroundTermPattern::Literal(term) => Some(Self::convert_literal(term).into()),
GroundTermPattern::NamedNode(term) => Some(term.clone().into()),
GroundTermPattern::Literal(term) => Some(term.clone().into()),
GroundTermPattern::Triple(triple) => {
Self::convert_ground_triple_pattern(triple, variables, values, dataset)?
.map(|t| t.into())
@ -544,18 +521,18 @@ impl SimpleUpdateEvaluator<'_> {
variables: &[Variable],
values: &EncodedTuple,
dataset: &DatasetView,
) -> Result<Option<OxTriple>, EvaluationError> {
Ok(Some(OxTriple {
) -> Result<Option<Triple>, EvaluationError> {
Ok(Some(Triple {
subject: match Self::convert_ground_term_or_var(
&triple.subject,
variables,
values,
dataset,
)? {
Some(OxTerm::NamedNode(node)) => node.into(),
Some(OxTerm::BlankNode(node)) => node.into(),
Some(OxTerm::Triple(triple)) => triple.into(),
Some(OxTerm::Literal(_)) | None => return Ok(None),
Some(Term::NamedNode(node)) => node.into(),
Some(Term::BlankNode(node)) => node.into(),
Some(Term::Triple(triple)) => triple.into(),
Some(Term::Literal(_)) | None => return Ok(None),
},
predicate: if let Some(predicate) =
Self::convert_named_node_or_var(&triple.predicate, variables, values, dataset)?

Loading…
Cancel
Save